xref: /llvm-project/llvm/unittests/SandboxIR/SandboxIRTest.cpp (revision 7e5df5bcc3be3299a0aa3a2c65f81b794c5ba935)
1 //===- SandboxIRTest.cpp --------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/SandboxIR/SandboxIR.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/IR/BasicBlock.h"
12 #include "llvm/IR/Constants.h"
13 #include "llvm/IR/DataLayout.h"
14 #include "llvm/IR/Function.h"
15 #include "llvm/IR/Instruction.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/SandboxIR/Utils.h"
18 #include "llvm/Support/SourceMgr.h"
19 #include "gmock/gmock-matchers.h"
20 #include "gtest/gtest.h"
21 
22 using namespace llvm;
23 
24 struct SandboxIRTest : public testing::Test {
25   LLVMContext C;
26   std::unique_ptr<Module> M;
27 
28   void parseIR(LLVMContext &C, const char *IR) {
29     SMDiagnostic Err;
30     M = parseAssemblyString(IR, Err, C);
31     if (!M)
32       Err.print("SandboxIRTest", errs());
33   }
34   BasicBlock *getBasicBlockByName(Function &F, StringRef Name) {
35     for (BasicBlock &BB : F)
36       if (BB.getName() == Name)
37         return &BB;
38     llvm_unreachable("Expected to find basic block!");
39   }
40 };
41 
42 TEST_F(SandboxIRTest, ClassID) {
43   parseIR(C, R"IR(
44 define void @foo(i32 %v1) {
45   %add = add i32 %v1, 42
46   ret void
47 }
48 )IR");
49   llvm::Function *LLVMF = &*M->getFunction("foo");
50   llvm::BasicBlock *LLVMBB = &*LLVMF->begin();
51   llvm::Instruction *LLVMAdd = &*LLVMBB->begin();
52   auto *LLVMC = cast<llvm::Constant>(LLVMAdd->getOperand(1));
53 
54   sandboxir::Context Ctx(C);
55   sandboxir::Function *F = Ctx.createFunction(LLVMF);
56   sandboxir::Argument *Arg0 = F->getArg(0);
57   sandboxir::BasicBlock *BB = &*F->begin();
58   sandboxir::Instruction *AddI = &*BB->begin();
59   sandboxir::Constant *Const0 = cast<sandboxir::Constant>(Ctx.getValue(LLVMC));
60 
61   EXPECT_TRUE(isa<sandboxir::Function>(F));
62   EXPECT_FALSE(isa<sandboxir::Function>(Arg0));
63   EXPECT_FALSE(isa<sandboxir::Function>(BB));
64   EXPECT_FALSE(isa<sandboxir::Function>(AddI));
65   EXPECT_FALSE(isa<sandboxir::Function>(Const0));
66 
67   EXPECT_FALSE(isa<sandboxir::Argument>(F));
68   EXPECT_TRUE(isa<sandboxir::Argument>(Arg0));
69   EXPECT_FALSE(isa<sandboxir::Argument>(BB));
70   EXPECT_FALSE(isa<sandboxir::Argument>(AddI));
71   EXPECT_FALSE(isa<sandboxir::Argument>(Const0));
72 
73   EXPECT_TRUE(isa<sandboxir::Constant>(F));
74   EXPECT_FALSE(isa<sandboxir::Constant>(Arg0));
75   EXPECT_FALSE(isa<sandboxir::Constant>(BB));
76   EXPECT_FALSE(isa<sandboxir::Constant>(AddI));
77   EXPECT_TRUE(isa<sandboxir::Constant>(Const0));
78 
79   EXPECT_FALSE(isa<sandboxir::OpaqueInst>(F));
80   EXPECT_FALSE(isa<sandboxir::OpaqueInst>(Arg0));
81   EXPECT_FALSE(isa<sandboxir::OpaqueInst>(BB));
82   EXPECT_FALSE(isa<sandboxir::OpaqueInst>(AddI));
83   EXPECT_FALSE(isa<sandboxir::OpaqueInst>(Const0));
84 
85   EXPECT_FALSE(isa<sandboxir::Instruction>(F));
86   EXPECT_FALSE(isa<sandboxir::Instruction>(Arg0));
87   EXPECT_FALSE(isa<sandboxir::Instruction>(BB));
88   EXPECT_TRUE(isa<sandboxir::Instruction>(AddI));
89   EXPECT_FALSE(isa<sandboxir::Instruction>(Const0));
90 
91   EXPECT_TRUE(isa<sandboxir::User>(F));
92   EXPECT_FALSE(isa<sandboxir::User>(Arg0));
93   EXPECT_FALSE(isa<sandboxir::User>(BB));
94   EXPECT_TRUE(isa<sandboxir::User>(AddI));
95   EXPECT_TRUE(isa<sandboxir::User>(Const0));
96 
97 #ifndef NDEBUG
98   std::string Buff;
99   raw_string_ostream BS(Buff);
100   F->dumpOS(BS);
101   Arg0->dumpOS(BS);
102   BB->dumpOS(BS);
103   AddI->dumpOS(BS);
104   Const0->dumpOS(BS);
105 #endif
106 }
107 
108 TEST_F(SandboxIRTest, ConstantInt) {
109   parseIR(C, R"IR(
110 define void @foo(i32 %v0) {
111   %add0 = add i32 %v0, 42
112   ret void
113 }
114 )IR");
115   Function &LLVMF = *M->getFunction("foo");
116   auto *LLVMBB = &*LLVMF.begin();
117   auto *LLVMAdd0 = &*LLVMBB->begin();
118   auto *LLVMFortyTwo = cast<llvm::ConstantInt>(LLVMAdd0->getOperand(1));
119   sandboxir::Context Ctx(C);
120 
121   auto &F = *Ctx.createFunction(&LLVMF);
122   auto &BB = *F.begin();
123   auto It = BB.begin();
124   auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
125   auto *FortyTwo = cast<sandboxir::ConstantInt>(Add0->getOperand(1));
126 
127   // Check that creating an identical constant gives us the same object.
128   auto *NewCI =
129       sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42);
130   EXPECT_EQ(NewCI, FortyTwo);
131   {
132     // Check getTrue(Ctx).
133     auto *True = sandboxir::ConstantInt::getTrue(Ctx);
134     EXPECT_EQ(True, Ctx.getValue(llvm::ConstantInt::getTrue(C)));
135     // Check getFalse(Ctx).
136     auto *False = sandboxir::ConstantInt::getFalse(Ctx);
137     EXPECT_EQ(False, Ctx.getValue(llvm::ConstantInt::getFalse(C)));
138     // Check getBool(Ctx).
139     auto *Bool = sandboxir::ConstantInt::getBool(Ctx, true);
140     EXPECT_EQ(Bool, Ctx.getValue(llvm::ConstantInt::getBool(C, true)));
141   }
142   {
143     auto *Int1Ty = sandboxir::Type::getInt1Ty(Ctx);
144     auto *LLVMInt1Ty = llvm::Type::getInt1Ty(C);
145     // Check getTrue(Ty).
146     auto *True = sandboxir::ConstantInt::getTrue(Int1Ty);
147     EXPECT_EQ(True, Ctx.getValue(llvm::ConstantInt::getTrue(LLVMInt1Ty)));
148     // Check getFalse(Ty).
149     auto *False = sandboxir::ConstantInt::getFalse(Int1Ty);
150     EXPECT_EQ(False, Ctx.getValue(llvm::ConstantInt::getFalse(LLVMInt1Ty)));
151     // Check getBool(Ty).
152     auto *Bool = sandboxir::ConstantInt::getBool(Int1Ty, true);
153     EXPECT_EQ(Bool, Ctx.getValue(llvm::ConstantInt::getBool(LLVMInt1Ty, true)));
154   }
155 
156   auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx);
157   auto *LLVMInt32Ty = llvm::Type::getInt32Ty(C);
158   {
159     // Check get(Type, V).
160     auto *FortyThree = sandboxir::ConstantInt::get(Int32Ty, 43);
161     auto *LLVMFortyThree = llvm::ConstantInt::get(LLVMInt32Ty, 43);
162     EXPECT_NE(FortyThree, FortyTwo);
163     EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
164   }
165   {
166     // Check get(Type, V, IsSigned).
167     auto *FortyThree =
168         sandboxir::ConstantInt::get(Int32Ty, 43, /*IsSigned=*/true);
169     auto *LLVMFortyThree =
170         llvm::ConstantInt::get(LLVMInt32Ty, 43, /*IsSigned=*/true);
171     EXPECT_NE(FortyThree, FortyTwo);
172     EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
173   }
174 
175   {
176     // Check get(IntegerType, V).
177     auto *FortyThree =
178         sandboxir::ConstantInt::get(sandboxir::IntegerType::get(Ctx, 32), 43);
179     auto *LLVMFortyThree =
180         llvm::ConstantInt::get(llvm::IntegerType::get(C, 32), 43);
181     EXPECT_NE(FortyThree, FortyTwo);
182     EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
183   }
184   {
185     // Check get(IntegerType, V, IsSigned).
186     auto *FortyThree = sandboxir::ConstantInt::get(
187         sandboxir::IntegerType::get(Ctx, 32), 43, /*IsSigned=*/true);
188     auto *LLVMFortyThree = llvm::ConstantInt::get(llvm::IntegerType::get(C, 32),
189                                                   43, /*IsSigned=*/true);
190     EXPECT_NE(FortyThree, FortyTwo);
191     EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
192   }
193 
194   {
195     // Check getSigned(IntegerType, V).
196     auto *FortyThree = sandboxir::ConstantInt::getSigned(
197         sandboxir::IntegerType::get(Ctx, 32), 43);
198     auto *LLVMFortyThree =
199         llvm::ConstantInt::getSigned(llvm::IntegerType::get(C, 32), 43);
200     EXPECT_NE(FortyThree, FortyTwo);
201     EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
202   }
203   {
204     // Check getSigned(Type, V).
205     auto *FortyThree = sandboxir::ConstantInt::getSigned(Int32Ty, 43);
206     auto *LLVMFortyThree = llvm::ConstantInt::getSigned(LLVMInt32Ty, 43);
207     EXPECT_NE(FortyThree, FortyTwo);
208     EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
209   }
210   {
211     // Check get(Ctx, APInt).
212     APInt APInt43(32, 43);
213     auto *FortyThree = sandboxir::ConstantInt::get(Ctx, APInt43);
214     auto *LLVMFortyThree = llvm::ConstantInt::get(C, APInt43);
215     EXPECT_NE(FortyThree, FortyTwo);
216     EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
217   }
218   {
219     // Check get(Ty, Str, Radix).
220     StringRef Str("43");
221     uint8_t Radix(10);
222     auto *FortyThree = sandboxir::ConstantInt::get(
223         sandboxir::IntegerType::get(Ctx, 32), Str, Radix);
224     auto *LLVMFortyThree =
225         llvm::ConstantInt::get(llvm::IntegerType::get(C, 32), Str, Radix);
226     EXPECT_NE(FortyThree, FortyTwo);
227     EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
228   }
229   {
230     // Check get(Ty, APInt).
231     APInt APInt43(32, 43);
232     auto *FortyThree = sandboxir::ConstantInt::get(Int32Ty, APInt43);
233     auto *LLVMFortyThree = llvm::ConstantInt::get(LLVMInt32Ty, APInt43);
234     EXPECT_NE(FortyThree, FortyTwo);
235     EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
236   }
237   // Check getValue().
238   EXPECT_EQ(FortyTwo->getValue(), LLVMFortyTwo->getValue());
239   // Check getBitWidth().
240   EXPECT_EQ(FortyTwo->getBitWidth(), LLVMFortyTwo->getBitWidth());
241   // Check getZExtValue().
242   EXPECT_EQ(FortyTwo->getZExtValue(), LLVMFortyTwo->getZExtValue());
243   // Check getSExtValue().
244   EXPECT_EQ(FortyTwo->getSExtValue(), LLVMFortyTwo->getSExtValue());
245   // Check getMaybeAlignValue().
246   auto *SixtyFour =
247       cast<sandboxir::ConstantInt>(sandboxir::ConstantInt::get(Int32Ty, 64));
248   auto *LLVMSixtyFour =
249       cast<llvm::ConstantInt>(llvm::ConstantInt::get(LLVMInt32Ty, 64));
250   EXPECT_EQ(SixtyFour->getMaybeAlignValue(),
251             LLVMSixtyFour->getMaybeAlignValue());
252   // Check getAlignValue().
253   EXPECT_EQ(SixtyFour->getAlignValue(), LLVMSixtyFour->getAlignValue());
254   // Check equalsInt().
255   EXPECT_TRUE(FortyTwo->equalsInt(42));
256   EXPECT_FALSE(FortyTwo->equalsInt(43));
257   // Check getIntegerType().
258   EXPECT_EQ(FortyTwo->getIntegerType(), sandboxir::IntegerType::get(Ctx, 32));
259   // Check isValueValidForType().
260   EXPECT_TRUE(
261       sandboxir::ConstantInt::isValueValidForType(Int32Ty, (uint64_t)42));
262   EXPECT_TRUE(
263       sandboxir::ConstantInt::isValueValidForType(Int32Ty, (int64_t)42));
264   // Check isNegative().
265   EXPECT_FALSE(FortyTwo->isNegative());
266   EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty, -42));
267   // Check isZero().
268   EXPECT_FALSE(FortyTwo->isZero());
269   EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty, 0)->isZero());
270   // Check isOne().
271   EXPECT_FALSE(FortyTwo->isOne());
272   EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty, 1)->isOne());
273   // Check isMinusOne().
274   EXPECT_FALSE(FortyTwo->isMinusOne());
275   EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty, -1)->isMinusOne());
276   // Check isMaxValue().
277   EXPECT_FALSE(FortyTwo->isMaxValue(/*Signed=*/true));
278   EXPECT_TRUE(
279       sandboxir::ConstantInt::get(Int32Ty, std::numeric_limits<int32_t>::max())
280           ->isMaxValue(/*Signed=*/true));
281   // Check isMinValue().
282   EXPECT_FALSE(FortyTwo->isMinValue(/*Signed=*/true));
283   EXPECT_TRUE(
284       sandboxir::ConstantInt::get(Int32Ty, std::numeric_limits<int32_t>::min())
285           ->isMinValue(/*Signed=*/true));
286   // Check uge().
287   EXPECT_TRUE(FortyTwo->uge(41));
288   EXPECT_FALSE(FortyTwo->uge(43));
289   // Check getLimitedValue().
290   EXPECT_EQ(FortyTwo->getLimitedValue(40u), 40u);
291   EXPECT_EQ(FortyTwo->getLimitedValue(50u), 42u);
292 }
293 
294 TEST_F(SandboxIRTest, ConstantFP) {
295   parseIR(C, R"IR(
296 define void @foo(float %v0, double %v1) {
297   %fadd0 = fadd float %v0, 42.0
298   %fadd1 = fadd double %v1, 43.0
299   ret void
300 }
301 )IR");
302   Function &LLVMF = *M->getFunction("foo");
303   sandboxir::Context Ctx(C);
304 
305   auto &F = *Ctx.createFunction(&LLVMF);
306   auto &BB = *F.begin();
307   auto It = BB.begin();
308   auto *FAdd0 = cast<sandboxir::BinaryOperator>(&*It++);
309   auto *FAdd1 = cast<sandboxir::BinaryOperator>(&*It++);
310   auto *FortyTwo = cast<sandboxir::ConstantFP>(FAdd0->getOperand(1));
311   [[maybe_unused]] auto *FortyThree =
312       cast<sandboxir::ConstantFP>(FAdd1->getOperand(1));
313 
314   auto *FloatTy = sandboxir::Type::getFloatTy(Ctx);
315   auto *DoubleTy = sandboxir::Type::getDoubleTy(Ctx);
316   auto *LLVMFloatTy = Type::getFloatTy(C);
317   auto *LLVMDoubleTy = Type::getDoubleTy(C);
318   // Check that creating an identical constant gives us the same object.
319   auto *NewFortyTwo = sandboxir::ConstantFP::get(FloatTy, 42.0);
320   EXPECT_EQ(NewFortyTwo, FortyTwo);
321   // Check get(Type, double).
322   auto *FortyFour =
323       cast<sandboxir::ConstantFP>(sandboxir::ConstantFP::get(FloatTy, 44.0));
324   auto *LLVMFortyFour =
325       cast<llvm::ConstantFP>(llvm::ConstantFP::get(LLVMFloatTy, 44.0));
326   EXPECT_NE(FortyFour, FortyTwo);
327   EXPECT_EQ(FortyFour, Ctx.getValue(LLVMFortyFour));
328   // Check get(Type, APFloat).
329   auto *FortyFive = cast<sandboxir::ConstantFP>(
330       sandboxir::ConstantFP::get(DoubleTy, APFloat(45.0)));
331   auto *LLVMFortyFive = cast<llvm::ConstantFP>(
332       llvm::ConstantFP::get(LLVMDoubleTy, APFloat(45.0)));
333   EXPECT_EQ(FortyFive, Ctx.getValue(LLVMFortyFive));
334   // Check get(Type, StringRef).
335   auto *FortySix = sandboxir::ConstantFP::get(FloatTy, "46.0");
336   EXPECT_EQ(FortySix, Ctx.getValue(llvm::ConstantFP::get(LLVMFloatTy, "46.0")));
337   // Check get(APFloat).
338   auto *FortySeven = sandboxir::ConstantFP::get(APFloat(47.0), Ctx);
339   EXPECT_EQ(FortySeven, Ctx.getValue(llvm::ConstantFP::get(C, APFloat(47.0))));
340   // Check getNaN().
341   {
342     auto *NaN = sandboxir::ConstantFP::getNaN(FloatTy);
343     EXPECT_EQ(NaN, Ctx.getValue(llvm::ConstantFP::getNaN(LLVMFloatTy)));
344   }
345   {
346     auto *NaN = sandboxir::ConstantFP::getNaN(FloatTy, /*Negative=*/true);
347     EXPECT_EQ(NaN, Ctx.getValue(llvm::ConstantFP::getNaN(LLVMFloatTy,
348                                                          /*Negative=*/true)));
349   }
350   {
351     auto *NaN = sandboxir::ConstantFP::getNaN(FloatTy, /*Negative=*/true,
352                                               /*Payload=*/1);
353     EXPECT_EQ(NaN, Ctx.getValue(llvm::ConstantFP::getNaN(
354                        LLVMFloatTy, /*Negative=*/true, /*Payload=*/1)));
355   }
356   // Check getQNaN().
357   {
358     auto *QNaN = sandboxir::ConstantFP::getQNaN(FloatTy);
359     EXPECT_EQ(QNaN, Ctx.getValue(llvm::ConstantFP::getQNaN(LLVMFloatTy)));
360   }
361   {
362     auto *QNaN = sandboxir::ConstantFP::getQNaN(FloatTy, /*Negative=*/true);
363     EXPECT_EQ(QNaN, Ctx.getValue(llvm::ConstantFP::getQNaN(LLVMFloatTy,
364                                                            /*Negative=*/true)));
365   }
366   {
367     APInt Payload(1, 1);
368     auto *QNaN =
369         sandboxir::ConstantFP::getQNaN(FloatTy, /*Negative=*/true, &Payload);
370     EXPECT_EQ(QNaN, Ctx.getValue(llvm::ConstantFP::getQNaN(
371                         LLVMFloatTy, /*Negative=*/true, &Payload)));
372   }
373   // Check getSNaN().
374   {
375     auto *SNaN = sandboxir::ConstantFP::getSNaN(FloatTy);
376     EXPECT_EQ(SNaN, Ctx.getValue(llvm::ConstantFP::getSNaN(LLVMFloatTy)));
377   }
378   {
379     auto *SNaN = sandboxir::ConstantFP::getSNaN(FloatTy, /*Negative=*/true);
380     EXPECT_EQ(SNaN, Ctx.getValue(llvm::ConstantFP::getSNaN(LLVMFloatTy,
381                                                            /*Negative=*/true)));
382   }
383   {
384     APInt Payload(1, 1);
385     auto *SNaN =
386         sandboxir::ConstantFP::getSNaN(FloatTy, /*Negative=*/true, &Payload);
387     EXPECT_EQ(SNaN, Ctx.getValue(llvm::ConstantFP::getSNaN(
388                         LLVMFloatTy, /*Negative=*/true, &Payload)));
389   }
390 
391   // Check getZero().
392   {
393     auto *Zero = sandboxir::ConstantFP::getZero(FloatTy);
394     EXPECT_EQ(Zero, Ctx.getValue(llvm::ConstantFP::getZero(LLVMFloatTy)));
395   }
396   {
397     auto *Zero = sandboxir::ConstantFP::getZero(FloatTy, /*Negative=*/true);
398     EXPECT_EQ(Zero, Ctx.getValue(llvm::ConstantFP::getZero(LLVMFloatTy,
399                                                            /*Negative=*/true)));
400   }
401 
402   // Check getNegativeZero().
403   auto *NegZero = cast<sandboxir::ConstantFP>(
404       sandboxir::ConstantFP::getNegativeZero(FloatTy));
405   EXPECT_EQ(NegZero,
406             Ctx.getValue(llvm::ConstantFP::getNegativeZero(LLVMFloatTy)));
407 
408   // Check getInfinity().
409   {
410     auto *Inf = sandboxir::ConstantFP::getInfinity(FloatTy);
411     EXPECT_EQ(Inf, Ctx.getValue(llvm::ConstantFP::getInfinity(LLVMFloatTy)));
412   }
413   {
414     auto *Inf = sandboxir::ConstantFP::getInfinity(FloatTy, /*Negative=*/true);
415     EXPECT_EQ(Inf, Ctx.getValue(llvm::ConstantFP::getInfinity(
416                        LLVMFloatTy, /*Negative=*/true)));
417   }
418 
419   // Check isValueValidForType().
420   APFloat V(1.1);
421   EXPECT_EQ(sandboxir::ConstantFP::isValueValidForType(FloatTy, V),
422             llvm::ConstantFP::isValueValidForType(LLVMFloatTy, V));
423   // Check getValueAPF().
424   EXPECT_EQ(FortyFour->getValueAPF(), LLVMFortyFour->getValueAPF());
425   // Check getValue().
426   EXPECT_EQ(FortyFour->getValue(), LLVMFortyFour->getValue());
427   // Check isZero().
428   EXPECT_EQ(FortyFour->isZero(), LLVMFortyFour->isZero());
429   EXPECT_TRUE(sandboxir::ConstantFP::getZero(FloatTy));
430   EXPECT_TRUE(sandboxir::ConstantFP::getZero(FloatTy, /*Negative=*/true));
431   // Check isNegative().
432   EXPECT_TRUE(cast<sandboxir::ConstantFP>(
433                   sandboxir::ConstantFP::getZero(FloatTy, /*Negative=*/true))
434                   ->isNegative());
435   // Check isInfinity().
436   EXPECT_TRUE(
437       cast<sandboxir::ConstantFP>(sandboxir::ConstantFP::getInfinity(FloatTy))
438           ->isInfinity());
439   // Check isNaN().
440   EXPECT_TRUE(
441       cast<sandboxir::ConstantFP>(sandboxir::ConstantFP::getNaN(FloatTy))
442           ->isNaN());
443   // Check isExactlyValue(APFloat).
444   EXPECT_TRUE(NegZero->isExactlyValue(NegZero->getValueAPF()));
445   // Check isExactlyValue(double).
446   EXPECT_TRUE(NegZero->isExactlyValue(-0.0));
447 }
448 
449 // Tests ConstantArray, ConstantStruct and ConstantVector.
450 TEST_F(SandboxIRTest, ConstantAggregate) {
451   // Note: we are using i42 to avoid the creation of ConstantDataVector or
452   // ConstantDataArray.
453   parseIR(C, R"IR(
454 define void @foo() {
455   %array = extractvalue [2 x i42] [i42 0, i42 1], 0
456   %struct = extractvalue {i42, i42} {i42 0, i42 1}, 0
457   %vector = extractelement <2 x i42> <i42 0, i42 1>, i32 0
458   ret void
459 }
460 )IR");
461   Function &LLVMF = *M->getFunction("foo");
462   sandboxir::Context Ctx(C);
463 
464   auto &F = *Ctx.createFunction(&LLVMF);
465   auto &BB = *F.begin();
466   auto It = BB.begin();
467   auto *I0 = &*It++;
468   auto *I1 = &*It++;
469   auto *I2 = &*It++;
470   // Check classof() and creation.
471   auto *Array = cast<sandboxir::ConstantArray>(I0->getOperand(0));
472   EXPECT_TRUE(isa<sandboxir::ConstantAggregate>(Array));
473   auto *Struct = cast<sandboxir::ConstantStruct>(I1->getOperand(0));
474   EXPECT_TRUE(isa<sandboxir::ConstantAggregate>(Struct));
475   auto *Vector = cast<sandboxir::ConstantVector>(I2->getOperand(0));
476   EXPECT_TRUE(isa<sandboxir::ConstantAggregate>(Vector));
477 
478   auto *ZeroI42 = cast<sandboxir::ConstantInt>(Array->getOperand(0));
479   auto *OneI42 = cast<sandboxir::ConstantInt>(Array->getOperand(1));
480   // Check ConstantArray::get(), getType().
481   auto *NewCA =
482       sandboxir::ConstantArray::get(Array->getType(), {ZeroI42, OneI42});
483   EXPECT_EQ(NewCA, Array);
484 
485   // Check ConstantStruct::get(), getType().
486   auto *NewCS =
487       sandboxir::ConstantStruct::get(Struct->getType(), {ZeroI42, OneI42});
488   EXPECT_EQ(NewCS, Struct);
489   // Check ConstantStruct::get(...).
490   auto *NewCS2 =
491       sandboxir::ConstantStruct::get(Struct->getType(), ZeroI42, OneI42);
492   EXPECT_EQ(NewCS2, Struct);
493   // Check ConstantStruct::getAnon(ArayRef).
494   auto *AnonCS = sandboxir::ConstantStruct::getAnon({ZeroI42, OneI42});
495   EXPECT_FALSE(cast<sandboxir::StructType>(AnonCS->getType())->isPacked());
496   auto *AnonCSPacked =
497       sandboxir::ConstantStruct::getAnon({ZeroI42, OneI42}, /*Packed=*/true);
498   EXPECT_TRUE(cast<sandboxir::StructType>(AnonCSPacked->getType())->isPacked());
499   // Check ConstantStruct::getAnon(Ctx, ArrayRef).
500   auto *AnonCS2 = sandboxir::ConstantStruct::getAnon(Ctx, {ZeroI42, OneI42});
501   EXPECT_EQ(AnonCS2, AnonCS);
502   auto *AnonCS2Packed = sandboxir::ConstantStruct::getAnon(
503       Ctx, {ZeroI42, OneI42}, /*Packed=*/true);
504   EXPECT_EQ(AnonCS2Packed, AnonCSPacked);
505   // Check ConstantStruct::getTypeForElements(Ctx, ArrayRef).
506   auto *StructTy =
507       sandboxir::ConstantStruct::getTypeForElements(Ctx, {ZeroI42, OneI42});
508   EXPECT_EQ(StructTy, Struct->getType());
509   EXPECT_FALSE(StructTy->isPacked());
510   // Check ConstantStruct::getTypeForElements(Ctx, ArrayRef, Packed).
511   auto *StructTyPacked = sandboxir::ConstantStruct::getTypeForElements(
512       Ctx, {ZeroI42, OneI42}, /*Packed=*/true);
513   EXPECT_TRUE(StructTyPacked->isPacked());
514   // Check ConstantStruct::getTypeForElements(ArrayRef).
515   auto *StructTy2 =
516       sandboxir::ConstantStruct::getTypeForElements(Ctx, {ZeroI42, OneI42});
517   EXPECT_EQ(StructTy2, Struct->getType());
518   // Check ConstantStruct::getTypeForElements(ArrayRef, Packed).
519   auto *StructTy2Packed = sandboxir::ConstantStruct::getTypeForElements(
520       Ctx, {ZeroI42, OneI42}, /*Packed=*/true);
521   EXPECT_EQ(StructTy2Packed, StructTyPacked);
522 }
523 
524 TEST_F(SandboxIRTest, ConstantAggregateZero) {
525   parseIR(C, R"IR(
526 define void @foo(ptr %ptr, {i32, i8} %v1, <2 x i8> %v2) {
527   %extr0 = extractvalue [2 x i8] zeroinitializer, 0
528   %extr1 = extractvalue {i32, i8} zeroinitializer, 0
529   %extr2 = extractelement <2 x i8> zeroinitializer, i32 0
530   ret void
531 }
532 )IR");
533   Function &LLVMF = *M->getFunction("foo");
534   sandboxir::Context Ctx(C);
535 
536   auto &F = *Ctx.createFunction(&LLVMF);
537   auto &BB = *F.begin();
538   auto It = BB.begin();
539   auto *Extr0 = &*It++;
540   auto *Extr1 = &*It++;
541   auto *Extr2 = &*It++;
542   [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
543   auto *Zero32 =
544       sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0);
545   auto *Zero8 = sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 0);
546   auto *Int8Ty = sandboxir::Type::getInt8Ty(Ctx);
547   auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx);
548   auto *ArrayTy = sandboxir::ArrayType::get(Int8Ty, 2u);
549   auto *StructTy = sandboxir::StructType::get(Ctx, {Int32Ty, Int8Ty});
550   auto *VectorTy =
551       sandboxir::VectorType::get(Int8Ty, ElementCount::getFixed(2u));
552 
553   // Check creation and classof().
554   auto *ArrayCAZ = cast<sandboxir::ConstantAggregateZero>(Extr0->getOperand(0));
555   EXPECT_EQ(ArrayCAZ->getType(), ArrayTy);
556   auto *StructCAZ =
557       cast<sandboxir::ConstantAggregateZero>(Extr1->getOperand(0));
558   EXPECT_EQ(StructCAZ->getType(), StructTy);
559   auto *VectorCAZ =
560       cast<sandboxir::ConstantAggregateZero>(Extr2->getOperand(0));
561   EXPECT_EQ(VectorCAZ->getType(), VectorTy);
562   // Check get().
563   auto *SameVectorCAZ =
564       sandboxir::ConstantAggregateZero::get(sandboxir::VectorType::get(
565           sandboxir::Type::getInt8Ty(Ctx), ElementCount::getFixed(2)));
566   EXPECT_EQ(SameVectorCAZ, VectorCAZ); // Should be uniqued.
567   auto *NewVectorCAZ =
568       sandboxir::ConstantAggregateZero::get(sandboxir::VectorType::get(
569           sandboxir::Type::getInt8Ty(Ctx), ElementCount::getFixed(4)));
570   EXPECT_NE(NewVectorCAZ, VectorCAZ);
571   // Check getSequentialElement().
572   auto *SeqElm = VectorCAZ->getSequentialElement();
573   EXPECT_EQ(SeqElm,
574             sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 0));
575   // Check getStructElement().
576   auto *StructElm0 = StructCAZ->getStructElement(0);
577   auto *StructElm1 = StructCAZ->getStructElement(1);
578   EXPECT_EQ(StructElm0, Zero32);
579   EXPECT_EQ(StructElm1, Zero8);
580   // Check getElementValue(Constant).
581   EXPECT_EQ(ArrayCAZ->getElementValue(Zero32), Zero8);
582   EXPECT_EQ(StructCAZ->getElementValue(Zero32), Zero32);
583   EXPECT_EQ(VectorCAZ->getElementValue(Zero32), Zero8);
584   // Check getElementValue(unsigned).
585   EXPECT_EQ(ArrayCAZ->getElementValue(0u), Zero8);
586   EXPECT_EQ(StructCAZ->getElementValue(0u), Zero32);
587   EXPECT_EQ(VectorCAZ->getElementValue(0u), Zero8);
588   // Check getElementCount().
589   EXPECT_EQ(ArrayCAZ->getElementCount(), ElementCount::getFixed(2));
590   EXPECT_EQ(NewVectorCAZ->getElementCount(), ElementCount::getFixed(4));
591 }
592 
593 TEST_F(SandboxIRTest, ConstantPointerNull) {
594   parseIR(C, R"IR(
595 define ptr @foo() {
596   ret ptr null
597 }
598 )IR");
599   Function &LLVMF = *M->getFunction("foo");
600   sandboxir::Context Ctx(C);
601 
602   auto &F = *Ctx.createFunction(&LLVMF);
603   auto &BB = *F.begin();
604   auto It = BB.begin();
605   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
606   // Check classof() and creation.
607   auto *CPNull = cast<sandboxir::ConstantPointerNull>(Ret->getReturnValue());
608   // Check get().
609   auto *NewCPNull =
610       sandboxir::ConstantPointerNull::get(sandboxir::PointerType::get(Ctx, 0u));
611   EXPECT_EQ(NewCPNull, CPNull);
612   auto *NewCPNull2 =
613       sandboxir::ConstantPointerNull::get(sandboxir::PointerType::get(Ctx, 1u));
614   EXPECT_NE(NewCPNull2, CPNull);
615   // Check getType().
616   EXPECT_EQ(CPNull->getType(), sandboxir::PointerType::get(Ctx, 0u));
617   EXPECT_EQ(NewCPNull2->getType(), sandboxir::PointerType::get(Ctx, 1u));
618 }
619 
620 TEST_F(SandboxIRTest, PoisonValue) {
621   parseIR(C, R"IR(
622 define void @foo() {
623   %i0 = add i32 poison, poison
624   %i1 = add <2 x i32> poison, poison
625   %i2 = extractvalue {i32, i8} poison, 0
626   ret void
627 }
628 )IR");
629   Function &LLVMF = *M->getFunction("foo");
630   sandboxir::Context Ctx(C);
631 
632   auto &F = *Ctx.createFunction(&LLVMF);
633   auto &BB = *F.begin();
634   auto It = BB.begin();
635   auto *I0 = &*It++;
636   auto *I1 = &*It++;
637   auto *I2 = &*It++;
638   auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx);
639   auto *Int8Ty = sandboxir::Type::getInt8Ty(Ctx);
640   auto *Zero32 = sandboxir::ConstantInt::get(Int32Ty, 0u);
641   auto *One32 = sandboxir::ConstantInt::get(Int32Ty, 1u);
642 
643   // Check classof() and creation.
644   auto *Poison = cast<sandboxir::PoisonValue>(I0->getOperand(0));
645   EXPECT_EQ(Poison->getType(), Int32Ty);
646   EXPECT_TRUE(isa<sandboxir::UndefValue>(Poison)); // Poison is Undef
647   // Check get().
648   auto *NewPoison = sandboxir::PoisonValue::get(Int32Ty);
649   EXPECT_EQ(NewPoison, Poison);
650   auto *NewPoison2 =
651       sandboxir::PoisonValue::get(sandboxir::PointerType::get(Ctx, 0u));
652   EXPECT_NE(NewPoison2, Poison);
653   // Check getSequentialElement().
654   auto *PoisonVector = cast<sandboxir::PoisonValue>(I1->getOperand(0));
655   auto *SeqElm = PoisonVector->getSequentialElement();
656   EXPECT_EQ(SeqElm->getType(), Int32Ty);
657   // Check getStructElement().
658   auto *PoisonStruct = cast<sandboxir::PoisonValue>(I2->getOperand(0));
659   auto *StrElm0 = PoisonStruct->getStructElement(0);
660   auto *StrElm1 = PoisonStruct->getStructElement(1);
661   EXPECT_EQ(StrElm0->getType(), Int32Ty);
662   EXPECT_EQ(StrElm1->getType(), Int8Ty);
663   // Check getElementValue(Constant)
664   EXPECT_EQ(PoisonStruct->getElementValue(Zero32),
665             sandboxir::PoisonValue::get(Int32Ty));
666   EXPECT_EQ(PoisonStruct->getElementValue(One32),
667             sandboxir::PoisonValue::get(Int8Ty));
668   // Check getElementValue(unsigned)
669   EXPECT_EQ(PoisonStruct->getElementValue(0u),
670             sandboxir::PoisonValue::get(Int32Ty));
671   EXPECT_EQ(PoisonStruct->getElementValue(1u),
672             sandboxir::PoisonValue::get(Int8Ty));
673 }
674 
675 TEST_F(SandboxIRTest, UndefValue) {
676   parseIR(C, R"IR(
677 define void @foo() {
678   %i0 = add i32 undef, undef
679   %i1 = add <2 x i32> undef, undef
680   %i2 = extractvalue {i32, i8} undef, 0
681   ret void
682 }
683 )IR");
684   Function &LLVMF = *M->getFunction("foo");
685   sandboxir::Context Ctx(C);
686 
687   auto &F = *Ctx.createFunction(&LLVMF);
688   auto &BB = *F.begin();
689   auto It = BB.begin();
690   auto *I0 = &*It++;
691   auto *I1 = &*It++;
692   auto *I2 = &*It++;
693   auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx);
694   auto *Int8Ty = sandboxir::Type::getInt8Ty(Ctx);
695   auto *Zero32 = sandboxir::ConstantInt::get(Int32Ty, 0u);
696   auto *One32 = sandboxir::ConstantInt::get(Int32Ty, 1u);
697 
698   // Check classof() and creation.
699   auto *Undef = cast<sandboxir::UndefValue>(I0->getOperand(0));
700   EXPECT_EQ(Undef->getType(), Int32Ty);
701   EXPECT_FALSE(isa<sandboxir::PoisonValue>(Undef)); // Undef is not Poison
702   // Check get().
703   auto *NewUndef = sandboxir::UndefValue::get(Int32Ty);
704   EXPECT_EQ(NewUndef, Undef);
705   auto *NewUndef2 =
706       sandboxir::UndefValue::get(sandboxir::PointerType::get(Ctx, 0u));
707   EXPECT_NE(NewUndef2, Undef);
708   // Check getSequentialElement().
709   auto *UndefVector = cast<sandboxir::UndefValue>(I1->getOperand(0));
710   auto *SeqElm = UndefVector->getSequentialElement();
711   EXPECT_EQ(SeqElm->getType(), Int32Ty);
712   // Check getStructElement().
713   auto *UndefStruct = cast<sandboxir::UndefValue>(I2->getOperand(0));
714   auto *StrElm0 = UndefStruct->getStructElement(0);
715   auto *StrElm1 = UndefStruct->getStructElement(1);
716   EXPECT_EQ(StrElm0->getType(), Int32Ty);
717   EXPECT_EQ(StrElm1->getType(), Int8Ty);
718   // Check getElementValue(Constant)
719   EXPECT_EQ(UndefStruct->getElementValue(Zero32),
720             sandboxir::UndefValue::get(Int32Ty));
721   EXPECT_EQ(UndefStruct->getElementValue(One32),
722             sandboxir::UndefValue::get(Int8Ty));
723   // Check getElementValue(unsigned)
724   EXPECT_EQ(UndefStruct->getElementValue(0u),
725             sandboxir::UndefValue::get(Int32Ty));
726   EXPECT_EQ(UndefStruct->getElementValue(1u),
727             sandboxir::UndefValue::get(Int8Ty));
728   // Check getNumElements().
729   EXPECT_EQ(UndefVector->getNumElements(), 2u);
730   EXPECT_EQ(UndefStruct->getNumElements(), 2u);
731 }
732 
733 TEST_F(SandboxIRTest, GlobalValue) {
734   parseIR(C, R"IR(
735 declare external void @bar()
736 define void @foo() {
737   call void @bar()
738   ret void
739 }
740 )IR");
741   Function &LLVMF = *M->getFunction("foo");
742   auto *LLVMBB = &*LLVMF.begin();
743   auto LLVMIt = LLVMBB->begin();
744   auto *LLVMCall = cast<llvm::CallInst>(&*LLVMIt++);
745   auto *LLVMGV = cast<llvm::GlobalValue>(LLVMCall->getCalledOperand());
746   sandboxir::Context Ctx(C);
747 
748   auto &F = *Ctx.createFunction(&LLVMF);
749   auto *BB = &*F.begin();
750   auto It = BB->begin();
751   auto *Call = cast<sandboxir::CallInst>(&*It++);
752   [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
753 
754   // Check classof(), creation, getFunction(), getBasicBlock().
755   auto *GV = cast<sandboxir::GlobalValue>(Call->getCalledOperand());
756   // Check getAddressSpace().
757   EXPECT_EQ(GV->getAddressSpace(), LLVMGV->getAddressSpace());
758   // Check hasGlobalUnnamedAddr().
759   EXPECT_EQ(GV->hasGlobalUnnamedAddr(), LLVMGV->hasGlobalUnnamedAddr());
760   // Check hasAtLeastLocalUnnamedAddr().
761   EXPECT_EQ(GV->hasAtLeastLocalUnnamedAddr(),
762             LLVMGV->hasAtLeastLocalUnnamedAddr());
763   // Check getUnnamedAddr().
764   EXPECT_EQ(GV->getUnnamedAddr(), LLVMGV->getUnnamedAddr());
765   // Check setUnnamedAddr().
766   auto OrigUnnamedAddr = GV->getUnnamedAddr();
767   auto NewUnnamedAddr = sandboxir::GlobalValue::UnnamedAddr::Global;
768   EXPECT_NE(NewUnnamedAddr, OrigUnnamedAddr);
769   GV->setUnnamedAddr(NewUnnamedAddr);
770   EXPECT_EQ(GV->getUnnamedAddr(), NewUnnamedAddr);
771   GV->setUnnamedAddr(OrigUnnamedAddr);
772   EXPECT_EQ(GV->getUnnamedAddr(), OrigUnnamedAddr);
773   // Check getMinUnnamedAddr().
774   EXPECT_EQ(
775       sandboxir::GlobalValue::getMinUnnamedAddr(OrigUnnamedAddr,
776                                                 NewUnnamedAddr),
777       llvm::GlobalValue::getMinUnnamedAddr(OrigUnnamedAddr, NewUnnamedAddr));
778   // Check hasComdat().
779   EXPECT_EQ(GV->hasComdat(), LLVMGV->hasComdat());
780   // Check getVisibility().
781   EXPECT_EQ(GV->getVisibility(), LLVMGV->getVisibility());
782   // Check hasDefaultVisibility().
783   EXPECT_EQ(GV->hasDefaultVisibility(), LLVMGV->hasDefaultVisibility());
784   // Check hasHiddenVisibility().
785   EXPECT_EQ(GV->hasHiddenVisibility(), LLVMGV->hasHiddenVisibility());
786   // Check hasProtectedVisibility().
787   EXPECT_EQ(GV->hasProtectedVisibility(), LLVMGV->hasProtectedVisibility());
788   // Check setVisibility().
789   auto OrigVisibility = GV->getVisibility();
790   auto NewVisibility =
791       sandboxir::GlobalValue::VisibilityTypes::ProtectedVisibility;
792   EXPECT_NE(NewVisibility, OrigVisibility);
793   GV->setVisibility(NewVisibility);
794   EXPECT_EQ(GV->getVisibility(), NewVisibility);
795   GV->setVisibility(OrigVisibility);
796   EXPECT_EQ(GV->getVisibility(), OrigVisibility);
797 }
798 
799 TEST_F(SandboxIRTest, GlobalObject) {
800   parseIR(C, R"IR(
801 declare external void @bar()
802 define void @foo() {
803   call void @bar()
804   ret void
805 }
806 )IR");
807   Function &LLVMF = *M->getFunction("foo");
808   auto *LLVMBB = &*LLVMF.begin();
809   auto LLVMIt = LLVMBB->begin();
810   auto *LLVMCall = cast<llvm::CallInst>(&*LLVMIt++);
811   auto *LLVMGO = cast<llvm::GlobalObject>(LLVMCall->getCalledOperand());
812   sandboxir::Context Ctx(C);
813 
814   auto &F = *Ctx.createFunction(&LLVMF);
815   auto *BB = &*F.begin();
816   auto It = BB->begin();
817   auto *Call = cast<sandboxir::CallInst>(&*It++);
818   // Check classof(), creation.
819   auto *GO = cast<sandboxir::GlobalObject>(Call->getCalledOperand());
820   // Check getAlignment().
821   EXPECT_EQ(GO->getAlignment(), LLVMGO->getAlignment());
822   // Check getAlign().
823   EXPECT_EQ(GO->getAlign(), LLVMGO->getAlign());
824   // Check setAlignment().
825   auto OrigMaybeAlign = GO->getAlign();
826   auto NewMaybeAlign = MaybeAlign(128);
827   EXPECT_NE(NewMaybeAlign, OrigMaybeAlign);
828   GO->setAlignment(NewMaybeAlign);
829   EXPECT_EQ(GO->getAlign(), NewMaybeAlign);
830   GO->setAlignment(OrigMaybeAlign);
831   EXPECT_EQ(GO->getAlign(), OrigMaybeAlign);
832   // Check getGlobalObjectSubClassData().
833   EXPECT_EQ(GO->getGlobalObjectSubClassData(),
834             LLVMGO->getGlobalObjectSubClassData());
835   // Check setGlobalObjectSubClassData().
836   auto OrigGOSCD = GO->getGlobalObjectSubClassData();
837   auto NewGOSCD = 1u;
838   EXPECT_NE(NewGOSCD, OrigGOSCD);
839   GO->setGlobalObjectSubClassData(NewGOSCD);
840   EXPECT_EQ(GO->getGlobalObjectSubClassData(), NewGOSCD);
841   GO->setGlobalObjectSubClassData(OrigGOSCD);
842   EXPECT_EQ(GO->getGlobalObjectSubClassData(), OrigGOSCD);
843   // Check hasSection().
844   EXPECT_EQ(GO->hasSection(), LLVMGO->hasSection());
845   // Check getSection().
846   EXPECT_EQ(GO->getSection(), LLVMGO->getSection());
847   // Check setSection().
848   auto OrigSection = GO->getSection();
849   auto NewSection = ".some_section";
850   EXPECT_NE(NewSection, OrigSection);
851   GO->setSection(NewSection);
852   EXPECT_EQ(GO->getSection(), NewSection);
853   GO->setSection(OrigSection);
854   EXPECT_EQ(GO->getSection(), OrigSection);
855   // Check hasComdat().
856   EXPECT_EQ(GO->hasComdat(), LLVMGO->hasComdat());
857   // Check getVCallVisibility().
858   EXPECT_EQ(GO->getVCallVisibility(), LLVMGO->getVCallVisibility());
859   // Check canIncreaseAlignment().
860   EXPECT_EQ(GO->canIncreaseAlignment(), LLVMGO->canIncreaseAlignment());
861 }
862 
863 TEST_F(SandboxIRTest, GlobalIFunc) {
864   parseIR(C, R"IR(
865 declare external void @bar()
866 @ifunc0 = ifunc void(), ptr @foo
867 @ifunc1 = ifunc void(), ptr @foo
868 define void @foo() {
869   call void @ifunc0()
870   call void @ifunc1()
871   call void @bar()
872   ret void
873 }
874 )IR");
875   Function &LLVMF = *M->getFunction("foo");
876   auto *LLVMBB = &*LLVMF.begin();
877   auto LLVMIt = LLVMBB->begin();
878   auto *LLVMCall0 = cast<llvm::CallInst>(&*LLVMIt++);
879   auto *LLVMIFunc0 = cast<llvm::GlobalIFunc>(LLVMCall0->getCalledOperand());
880 
881   sandboxir::Context Ctx(C);
882 
883   auto &F = *Ctx.createFunction(&LLVMF);
884   auto *BB = &*F.begin();
885   auto It = BB->begin();
886   auto *Call0 = cast<sandboxir::CallInst>(&*It++);
887   auto *Call1 = cast<sandboxir::CallInst>(&*It++);
888   auto *CallBar = cast<sandboxir::CallInst>(&*It++);
889   // Check classof(), creation.
890   auto *IFunc0 = cast<sandboxir::GlobalIFunc>(Call0->getCalledOperand());
891   auto *IFunc1 = cast<sandboxir::GlobalIFunc>(Call1->getCalledOperand());
892   auto *Bar = cast<sandboxir::Function>(CallBar->getCalledOperand());
893 
894   // Check getIterator().
895   {
896     auto It0 = IFunc0->getIterator();
897     auto It1 = IFunc1->getIterator();
898     EXPECT_EQ(&*It0, IFunc0);
899     EXPECT_EQ(&*It1, IFunc1);
900     EXPECT_EQ(std::next(It0), It1);
901     EXPECT_EQ(std::prev(It1), It0);
902     EXPECT_EQ(&*std::next(It0), IFunc1);
903     EXPECT_EQ(&*std::prev(It1), IFunc0);
904   }
905   // Check getReverseIterator().
906   {
907     auto RevIt0 = IFunc0->getReverseIterator();
908     auto RevIt1 = IFunc1->getReverseIterator();
909     EXPECT_EQ(&*RevIt0, IFunc0);
910     EXPECT_EQ(&*RevIt1, IFunc1);
911     EXPECT_EQ(std::prev(RevIt0), RevIt1);
912     EXPECT_EQ(std::next(RevIt1), RevIt0);
913     EXPECT_EQ(&*std::prev(RevIt0), IFunc1);
914     EXPECT_EQ(&*std::next(RevIt1), IFunc0);
915   }
916 
917   // Check setResolver(), getResolver().
918   EXPECT_EQ(IFunc0->getResolver(), Ctx.getValue(LLVMIFunc0->getResolver()));
919   auto *OrigResolver = IFunc0->getResolver();
920   auto *NewResolver = Bar;
921   EXPECT_NE(NewResolver, OrigResolver);
922   IFunc0->setResolver(NewResolver);
923   EXPECT_EQ(IFunc0->getResolver(), NewResolver);
924   IFunc0->setResolver(OrigResolver);
925   EXPECT_EQ(IFunc0->getResolver(), OrigResolver);
926   // Check getResolverFunction().
927   EXPECT_EQ(IFunc0->getResolverFunction(),
928             Ctx.getValue(LLVMIFunc0->getResolverFunction()));
929   // Check isValidLinkage().
930   for (auto L :
931        {GlobalValue::ExternalLinkage, GlobalValue::AvailableExternallyLinkage,
932         GlobalValue::LinkOnceAnyLinkage, GlobalValue::LinkOnceODRLinkage,
933         GlobalValue::WeakAnyLinkage, GlobalValue::WeakODRLinkage,
934         GlobalValue::AppendingLinkage, GlobalValue::InternalLinkage,
935         GlobalValue::PrivateLinkage, GlobalValue::ExternalWeakLinkage,
936         GlobalValue::CommonLinkage}) {
937     EXPECT_EQ(IFunc0->isValidLinkage(L), LLVMIFunc0->isValidLinkage(L));
938   }
939 }
940 
941 TEST_F(SandboxIRTest, GlobalVariable) {
942   parseIR(C, R"IR(
943 @glob0 = global i32 42
944 @glob1 = global i32 43
945 define void @foo() {
946   %ld0 = load i32, ptr @glob0
947   %ld1 = load i32, ptr @glob1
948   ret void
949 }
950 )IR");
951   Function &LLVMF = *M->getFunction("foo");
952   auto *LLVMBB = &*LLVMF.begin();
953   auto LLVMIt = LLVMBB->begin();
954   auto *LLVMLd0 = cast<llvm::LoadInst>(&*LLVMIt++);
955   auto *LLVMGV0 = cast<llvm::GlobalVariable>(LLVMLd0->getPointerOperand());
956   sandboxir::Context Ctx(C);
957 
958   auto &F = *Ctx.createFunction(&LLVMF);
959   auto *BB = &*F.begin();
960   auto It = BB->begin();
961   auto *Ld0 = cast<sandboxir::LoadInst>(&*It++);
962   auto *Ld1 = cast<sandboxir::LoadInst>(&*It++);
963   // Check classof(), creation.
964   auto *GV0 = cast<sandboxir::GlobalVariable>(Ld0->getPointerOperand());
965   auto *GV1 = cast<sandboxir::GlobalVariable>(Ld1->getPointerOperand());
966   // Check getIterator().
967   {
968     auto It0 = GV0->getIterator();
969     auto It1 = GV1->getIterator();
970     EXPECT_EQ(&*It0, GV0);
971     EXPECT_EQ(&*It1, GV1);
972     EXPECT_EQ(std::next(It0), It1);
973     EXPECT_EQ(std::prev(It1), It0);
974     EXPECT_EQ(&*std::next(It0), GV1);
975     EXPECT_EQ(&*std::prev(It1), GV0);
976   }
977   // Check getReverseIterator().
978   {
979     auto RevIt0 = GV0->getReverseIterator();
980     auto RevIt1 = GV1->getReverseIterator();
981     EXPECT_EQ(&*RevIt0, GV0);
982     EXPECT_EQ(&*RevIt1, GV1);
983     EXPECT_EQ(std::prev(RevIt0), RevIt1);
984     EXPECT_EQ(std::next(RevIt1), RevIt0);
985     EXPECT_EQ(&*std::prev(RevIt0), GV1);
986     EXPECT_EQ(&*std::next(RevIt1), GV0);
987   }
988   // Check hasInitializer().
989   EXPECT_EQ(GV0->hasInitializer(), LLVMGV0->hasInitializer());
990   // Check hasDefinitiveInitializer().
991   EXPECT_EQ(GV0->hasDefinitiveInitializer(),
992             LLVMGV0->hasDefinitiveInitializer());
993   // Check hasUniqueInitializer().
994   EXPECT_EQ(GV0->hasUniqueInitializer(), LLVMGV0->hasUniqueInitializer());
995   // Check getInitializer().
996   EXPECT_EQ(GV0->getInitializer(), Ctx.getValue(LLVMGV0->getInitializer()));
997   // Check setInitializer().
998   auto *OrigInitializer = GV0->getInitializer();
999   auto *NewInitializer = GV1->getInitializer();
1000   EXPECT_NE(NewInitializer, OrigInitializer);
1001   GV0->setInitializer(NewInitializer);
1002   EXPECT_EQ(GV0->getInitializer(), NewInitializer);
1003   GV0->setInitializer(OrigInitializer);
1004   EXPECT_EQ(GV0->getInitializer(), OrigInitializer);
1005   // Check isConstant().
1006   EXPECT_EQ(GV0->isConstant(), LLVMGV0->isConstant());
1007   // Check setConstant().
1008   bool OrigIsConstant = GV0->isConstant();
1009   bool NewIsConstant = !OrigIsConstant;
1010   GV0->setConstant(NewIsConstant);
1011   EXPECT_EQ(GV0->isConstant(), NewIsConstant);
1012   GV0->setConstant(OrigIsConstant);
1013   EXPECT_EQ(GV0->isConstant(), OrigIsConstant);
1014   // Check isExternallyInitialized().
1015   EXPECT_EQ(GV0->isExternallyInitialized(), LLVMGV0->isExternallyInitialized());
1016   // Check setExternallyInitialized().
1017   bool OrigIsExtInit = GV0->isExternallyInitialized();
1018   bool NewIsExtInit = !OrigIsExtInit;
1019   GV0->setExternallyInitialized(NewIsExtInit);
1020   EXPECT_EQ(GV0->isExternallyInitialized(), NewIsExtInit);
1021   GV0->setExternallyInitialized(OrigIsExtInit);
1022   EXPECT_EQ(GV0->isExternallyInitialized(), OrigIsExtInit);
1023   for (auto KindIdx : seq<int>(0, Attribute::AttrKind::EndAttrKinds)) {
1024     // Check hasAttribute(AttrKind).
1025     auto Kind = static_cast<Attribute::AttrKind>(KindIdx);
1026     EXPECT_EQ(GV0->hasAttribute(Kind), LLVMGV0->hasAttribute(Kind));
1027     // Check hasAttribute(StringRef).
1028     StringRef KindStr = Attribute::getNameFromAttrKind(Kind);
1029     EXPECT_EQ(GV0->hasAttribute(KindStr), LLVMGV0->hasAttribute(KindStr));
1030   }
1031   // Check hasAttributes().
1032   EXPECT_EQ(GV0->hasAttributes(), LLVMGV0->hasAttributes());
1033 
1034   for (auto KindIdx : seq<int>(0, Attribute::AttrKind::EndAttrKinds)) {
1035     // Check getAttribute(AttrKind).
1036     auto Kind = static_cast<Attribute::AttrKind>(KindIdx);
1037     EXPECT_EQ(GV0->getAttribute(Kind), LLVMGV0->getAttribute(Kind));
1038     // Check getAttribute(StringRef).
1039     StringRef KindStr = Attribute::getNameFromAttrKind(Kind);
1040     EXPECT_EQ(GV0->getAttribute(KindStr), LLVMGV0->getAttribute(KindStr));
1041   }
1042   // Check getAttributes().
1043   EXPECT_EQ(GV0->getAttributes(), LLVMGV0->getAttributes());
1044   // Check getAttributesAsList().
1045   EXPECT_THAT(GV0->getAttributesAsList(0u),
1046               testing::ContainerEq(LLVMGV0->getAttributesAsList(0u)));
1047   // Check hasImplicitSection().
1048   EXPECT_EQ(GV0->hasImplicitSection(), LLVMGV0->hasImplicitSection());
1049   // Check getCodeModelRaw().
1050   EXPECT_EQ(GV0->getCodeModelRaw(), LLVMGV0->getCodeModelRaw());
1051   // Check getCodeModel().
1052   EXPECT_EQ(GV0->getCodeModel(), LLVMGV0->getCodeModel());
1053 }
1054 
1055 TEST_F(SandboxIRTest, GlobalAlias) {
1056   parseIR(C, R"IR(
1057 @alias0 = dso_local alias void(), ptr @foo
1058 @alias1 = dso_local alias void(), ptr @foo
1059 declare void @bar();
1060 define void @foo() {
1061   call void @alias0()
1062   call void @alias1()
1063   call void @bar()
1064   ret void
1065 }
1066 )IR");
1067   Function &LLVMF = *M->getFunction("foo");
1068   auto *LLVMBB = &*LLVMF.begin();
1069   auto LLVMIt = LLVMBB->begin();
1070   auto *LLVMCall0 = cast<llvm::CallInst>(&*LLVMIt++);
1071   auto *LLVMAlias0 = cast<llvm::GlobalAlias>(LLVMCall0->getCalledOperand());
1072   sandboxir::Context Ctx(C);
1073 
1074   auto &F = *Ctx.createFunction(&LLVMF);
1075   auto *BB = &*F.begin();
1076   auto It = BB->begin();
1077   auto *Call0 = cast<sandboxir::CallInst>(&*It++);
1078   auto *Call1 = cast<sandboxir::CallInst>(&*It++);
1079   auto *CallBar = cast<sandboxir::CallInst>(&*It++);
1080   auto *CalleeBar = cast<sandboxir::Constant>(CallBar->getCalledOperand());
1081   // Check classof(), creation.
1082   auto *Alias0 = cast<sandboxir::GlobalAlias>(Call0->getCalledOperand());
1083   auto *Alias1 = cast<sandboxir::GlobalAlias>(Call1->getCalledOperand());
1084   // Check getIterator().
1085   {
1086     auto It0 = Alias0->getIterator();
1087     auto It1 = Alias1->getIterator();
1088     EXPECT_EQ(&*It0, Alias0);
1089     EXPECT_EQ(&*It1, Alias1);
1090     EXPECT_EQ(std::next(It0), It1);
1091     EXPECT_EQ(std::prev(It1), It0);
1092     EXPECT_EQ(&*std::next(It0), Alias1);
1093     EXPECT_EQ(&*std::prev(It1), Alias0);
1094   }
1095   // Check getReverseIterator().
1096   {
1097     auto RevIt0 = Alias0->getReverseIterator();
1098     auto RevIt1 = Alias1->getReverseIterator();
1099     EXPECT_EQ(&*RevIt0, Alias0);
1100     EXPECT_EQ(&*RevIt1, Alias1);
1101     EXPECT_EQ(std::prev(RevIt0), RevIt1);
1102     EXPECT_EQ(std::next(RevIt1), RevIt0);
1103     EXPECT_EQ(&*std::prev(RevIt0), Alias1);
1104     EXPECT_EQ(&*std::next(RevIt1), Alias0);
1105   }
1106   // Check getAliasee().
1107   EXPECT_EQ(Alias0->getAliasee(), Ctx.getValue(LLVMAlias0->getAliasee()));
1108   // Check setAliasee().
1109   auto *OrigAliasee = Alias0->getAliasee();
1110   auto *NewAliasee = CalleeBar;
1111   EXPECT_NE(NewAliasee, OrigAliasee);
1112   Alias0->setAliasee(NewAliasee);
1113   EXPECT_EQ(Alias0->getAliasee(), NewAliasee);
1114   Alias0->setAliasee(OrigAliasee);
1115   EXPECT_EQ(Alias0->getAliasee(), OrigAliasee);
1116   // Check getAliaseeObject().
1117   EXPECT_EQ(Alias0->getAliaseeObject(),
1118             Ctx.getValue(LLVMAlias0->getAliaseeObject()));
1119 }
1120 
1121 TEST_F(SandboxIRTest, NoCFIValue) {
1122   parseIR(C, R"IR(
1123 define void @foo() {
1124   call void no_cfi @foo()
1125   ret void
1126 }
1127 )IR");
1128   Function &LLVMF = *M->getFunction("foo");
1129   sandboxir::Context Ctx(C);
1130 
1131   auto &F = *Ctx.createFunction(&LLVMF);
1132   auto *BB = &*F.begin();
1133   auto It = BB->begin();
1134   auto *Call = cast<sandboxir::CallInst>(&*It++);
1135   // Check classof(), creation.
1136   auto *NoCFI = cast<sandboxir::NoCFIValue>(Call->getCalledOperand());
1137   // Check get().
1138   auto *NewNoCFI = sandboxir::NoCFIValue::get(&F);
1139   EXPECT_EQ(NewNoCFI, NoCFI);
1140   // Check getGlobalValue().
1141   EXPECT_EQ(NoCFI->getGlobalValue(), &F);
1142   // Check getType().
1143   EXPECT_EQ(NoCFI->getType(), F.getType());
1144 }
1145 
1146 TEST_F(SandboxIRTest, ConstantPtrAuth) {
1147   parseIR(C, R"IR(
1148 define ptr @foo() {
1149   ret ptr ptrauth (ptr @foo, i32 2, i64 1234)
1150 }
1151 )IR");
1152   Function &LLVMF = *M->getFunction("foo");
1153   auto *LLVMBB = &*LLVMF.begin();
1154   auto *LLVMRet = cast<llvm::ReturnInst>(&*LLVMBB->begin());
1155   auto *LLVMPtrAuth = cast<llvm::ConstantPtrAuth>(LLVMRet->getReturnValue());
1156   sandboxir::Context Ctx(C);
1157 
1158   auto &F = *Ctx.createFunction(&LLVMF);
1159   auto *BB = &*F.begin();
1160   auto It = BB->begin();
1161   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
1162   // Check classof(), creation.
1163   auto *PtrAuth = cast<sandboxir::ConstantPtrAuth>(Ret->getReturnValue());
1164   // Check get(), getKey(), getDiscriminator(), getAddrDiscriminator().
1165   auto *NewPtrAuth = sandboxir::ConstantPtrAuth::get(
1166       &F, PtrAuth->getKey(), PtrAuth->getDiscriminator(),
1167       PtrAuth->getAddrDiscriminator());
1168   EXPECT_EQ(NewPtrAuth, PtrAuth);
1169   // Check hasAddressDiscriminator().
1170   EXPECT_EQ(PtrAuth->hasAddressDiscriminator(),
1171             LLVMPtrAuth->hasAddressDiscriminator());
1172   // Check hasSpecialAddressDiscriminator().
1173   EXPECT_EQ(PtrAuth->hasSpecialAddressDiscriminator(0u),
1174             LLVMPtrAuth->hasSpecialAddressDiscriminator(0u));
1175   // Check isKnownCompatibleWith().
1176   const DataLayout &DL = M->getDataLayout();
1177   EXPECT_TRUE(PtrAuth->isKnownCompatibleWith(PtrAuth->getKey(),
1178                                              PtrAuth->getDiscriminator(), DL));
1179   // Check getWithSameSchema().
1180   EXPECT_EQ(PtrAuth->getWithSameSchema(&F), PtrAuth);
1181 }
1182 
1183 TEST_F(SandboxIRTest, ConstantExpr) {
1184   parseIR(C, R"IR(
1185 define i32 @foo() {
1186   ret i32 ptrtoint (ptr @foo to i32)
1187 }
1188 )IR");
1189   Function &LLVMF = *M->getFunction("foo");
1190   sandboxir::Context Ctx(C);
1191 
1192   auto &F = *Ctx.createFunction(&LLVMF);
1193   auto *BB = &*F.begin();
1194   auto It = BB->begin();
1195   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
1196   // Check classof(), creation.
1197   [[maybe_unused]] auto *ConstExpr =
1198       cast<sandboxir::ConstantExpr>(Ret->getReturnValue());
1199 }
1200 
1201 TEST_F(SandboxIRTest, BlockAddress) {
1202   parseIR(C, R"IR(
1203 define void @foo(ptr %ptr) {
1204 bb0:
1205   store ptr blockaddress(@foo, %bb0), ptr %ptr
1206   ret void
1207 bb1:
1208   ret void
1209 bb2:
1210   ret void
1211 }
1212 )IR");
1213   Function &LLVMF = *M->getFunction("foo");
1214   sandboxir::Context Ctx(C);
1215 
1216   auto &F = *Ctx.createFunction(&LLVMF);
1217   auto *BB0 = cast<sandboxir::BasicBlock>(
1218       Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
1219   auto *BB1 = cast<sandboxir::BasicBlock>(
1220       Ctx.getValue(getBasicBlockByName(LLVMF, "bb1")));
1221   auto *BB2 = cast<sandboxir::BasicBlock>(
1222       Ctx.getValue(getBasicBlockByName(LLVMF, "bb2")));
1223   auto It = BB0->begin();
1224   auto *SI = cast<sandboxir::StoreInst>(&*It++);
1225   [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
1226 
1227   // Check classof(), creation, getFunction(), getBasicBlock().
1228   auto *BB0Addr = cast<sandboxir::BlockAddress>(SI->getValueOperand());
1229   EXPECT_EQ(BB0Addr->getBasicBlock(), BB0);
1230   EXPECT_EQ(BB0Addr->getFunction(), &F);
1231   // Check get(F, BB).
1232   auto *NewBB0Addr = sandboxir::BlockAddress::get(&F, BB0);
1233   EXPECT_EQ(NewBB0Addr, BB0Addr);
1234   // Check get(BB).
1235   auto *NewBB0Addr2 = sandboxir::BlockAddress::get(BB0);
1236   EXPECT_EQ(NewBB0Addr2, BB0Addr);
1237   auto *BB1Addr = sandboxir::BlockAddress::get(BB1);
1238   EXPECT_EQ(BB1Addr->getBasicBlock(), BB1);
1239   EXPECT_NE(BB1Addr, BB0Addr);
1240   // Check lookup().
1241   auto *LookupBB0Addr = sandboxir::BlockAddress::lookup(BB0);
1242   EXPECT_EQ(LookupBB0Addr, BB0Addr);
1243   auto *LookupBB1Addr = sandboxir::BlockAddress::lookup(BB1);
1244   EXPECT_EQ(LookupBB1Addr, BB1Addr);
1245   auto *LookupBB2Addr = sandboxir::BlockAddress::lookup(BB2);
1246   EXPECT_EQ(LookupBB2Addr, nullptr);
1247 }
1248 
1249 TEST_F(SandboxIRTest, DSOLocalEquivalent) {
1250   parseIR(C, R"IR(
1251 declare void @bar()
1252 define void @foo() {
1253   call void dso_local_equivalent @bar()
1254   ret void
1255 }
1256 )IR");
1257   Function &LLVMF = *M->getFunction("foo");
1258   sandboxir::Context Ctx(C);
1259 
1260   auto &F = *Ctx.createFunction(&LLVMF);
1261   auto *BB = &*F.begin();
1262   auto It = BB->begin();
1263   auto *CI = cast<sandboxir::CallInst>(&*It++);
1264   // Check classof().
1265   auto *DSOLE = cast<sandboxir::DSOLocalEquivalent>(CI->getCalledOperand());
1266   // Check getGlobalValue().
1267   auto *GV = DSOLE->getGlobalValue();
1268   // Check get().
1269   auto *NewDSOLE = sandboxir::DSOLocalEquivalent::get(GV);
1270   EXPECT_EQ(NewDSOLE, DSOLE);
1271 }
1272 
1273 TEST_F(SandboxIRTest, ConstantTokenNone) {
1274   parseIR(C, R"IR(
1275 define void @foo(ptr %ptr) {
1276  bb0:
1277    %cs = catchswitch within none [label %handler] unwind to caller
1278  handler:
1279    ret void
1280 }
1281 )IR");
1282   Function &LLVMF = *M->getFunction("foo");
1283   sandboxir::Context Ctx(C);
1284 
1285   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
1286   auto *BB0 = cast<sandboxir::BasicBlock>(
1287       Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
1288   auto *CS = cast<sandboxir::CatchSwitchInst>(&*BB0->begin());
1289 
1290   // Check classof(), creation, getFunction(), getBasicBlock().
1291   auto *CTN = cast<sandboxir::ConstantTokenNone>(CS->getParentPad());
1292   // Check get().
1293   auto *NewCTN = sandboxir::ConstantTokenNone::get(Ctx);
1294   EXPECT_EQ(NewCTN, CTN);
1295 }
1296 
1297 TEST_F(SandboxIRTest, Use) {
1298   parseIR(C, R"IR(
1299 define i32 @foo(i32 %v0, i32 %v1) {
1300   %add0 = add i32 %v0, %v1
1301   ret i32 %add0
1302 }
1303 )IR");
1304   Function &LLVMF = *M->getFunction("foo");
1305   sandboxir::Context Ctx(C);
1306 
1307   BasicBlock *LLVMBB = &*LLVMF.begin();
1308   auto LLVMBBIt = LLVMBB->begin();
1309   Instruction *LLVMI0 = &*LLVMBBIt++;
1310   Instruction *LLVMRet = &*LLVMBBIt++;
1311   Argument *LLVMArg0 = LLVMF.getArg(0);
1312   Argument *LLVMArg1 = LLVMF.getArg(1);
1313 
1314   auto &F = *Ctx.createFunction(&LLVMF);
1315   auto &BB = *F.begin();
1316   auto *Arg0 = F.getArg(0);
1317   auto *Arg1 = F.getArg(1);
1318   auto It = BB.begin();
1319   auto *I0 = &*It++;
1320   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
1321 
1322   SmallVector<sandboxir::Argument *> Args{Arg0, Arg1};
1323   unsigned OpIdx = 0;
1324   for (sandboxir::Use Use : I0->operands()) {
1325     // Check Use.getOperandNo().
1326     EXPECT_EQ(Use.getOperandNo(), OpIdx);
1327     // Check Use.getUser().
1328     EXPECT_EQ(Use.getUser(), I0);
1329     // Check Use.getContext().
1330     EXPECT_EQ(Use.getContext(), &Ctx);
1331     // Check Use.get().
1332     sandboxir::Value *Op = Use.get();
1333     EXPECT_EQ(Op, Ctx.getValue(LLVMI0->getOperand(OpIdx)));
1334     // Check Use.getUser().
1335     EXPECT_EQ(Use.getUser(), I0);
1336     // Check implicit cast to Value.
1337     sandboxir::Value *Cast = Use;
1338     EXPECT_EQ(Cast, Op);
1339     // Check that Use points to the correct operand.
1340     EXPECT_EQ(Op, Args[OpIdx]);
1341     // Check getOperand().
1342     EXPECT_EQ(Op, I0->getOperand(OpIdx));
1343     // Check getOperandUse().
1344     EXPECT_EQ(Use, I0->getOperandUse(OpIdx));
1345     ++OpIdx;
1346   }
1347   EXPECT_EQ(OpIdx, 2u);
1348 
1349   // Check Use.operator==() and Use.operator!=().
1350   sandboxir::Use UseA = I0->getOperandUse(0);
1351   sandboxir::Use UseB = I0->getOperandUse(0);
1352   EXPECT_TRUE(UseA == UseB);
1353   EXPECT_FALSE(UseA != UseB);
1354 
1355   // Check getNumOperands().
1356   EXPECT_EQ(I0->getNumOperands(), 2u);
1357   EXPECT_EQ(Ret->getNumOperands(), 1u);
1358 
1359   EXPECT_EQ(Ret->getOperand(0), I0);
1360 
1361 #ifndef NDEBUG
1362   // Check Use.dump(()
1363   std::string Buff;
1364   raw_string_ostream BS(Buff);
1365   BS << "\n";
1366   I0->getOperandUse(0).dumpOS(BS);
1367   EXPECT_EQ(Buff, R"IR(
1368 Def:  i32 %v0 ; SB2. (Argument)
1369 User:   %add0 = add i32 %v0, %v1 ; SB5. (BinaryOperator)
1370 OperandNo: 0
1371 )IR");
1372 #endif // NDEBUG
1373 
1374   // Check Value.user_begin().
1375   sandboxir::Value::user_iterator UIt = I0->user_begin();
1376   sandboxir::User *U = *UIt;
1377   EXPECT_EQ(U, Ret);
1378   // Check Value.uses().
1379   EXPECT_EQ(range_size(I0->uses()), 1u);
1380   EXPECT_EQ((*I0->uses().begin()).getUser(), Ret);
1381   // Check Value.users().
1382   EXPECT_EQ(range_size(I0->users()), 1u);
1383   EXPECT_EQ(*I0->users().begin(), Ret);
1384   // Check Value.getNumUses().
1385   EXPECT_EQ(I0->getNumUses(), 1u);
1386   // Check Value.hasNUsesOrMore().
1387   EXPECT_TRUE(I0->hasNUsesOrMore(0u));
1388   EXPECT_TRUE(I0->hasNUsesOrMore(1u));
1389   EXPECT_FALSE(I0->hasNUsesOrMore(2u));
1390   // Check Value.hasNUses().
1391   EXPECT_FALSE(I0->hasNUses(0u));
1392   EXPECT_TRUE(I0->hasNUses(1u));
1393   EXPECT_FALSE(I0->hasNUses(2u));
1394 
1395   // Check Value.getExpectedType
1396 
1397   // Check User.setOperand().
1398   Ret->setOperand(0, Arg0);
1399   EXPECT_EQ(Ret->getOperand(0), Arg0);
1400   EXPECT_EQ(Ret->getOperandUse(0).get(), Arg0);
1401   EXPECT_EQ(LLVMRet->getOperand(0), LLVMArg0);
1402 
1403   Ret->setOperand(0, Arg1);
1404   EXPECT_EQ(Ret->getOperand(0), Arg1);
1405   EXPECT_EQ(Ret->getOperandUse(0).get(), Arg1);
1406   EXPECT_EQ(LLVMRet->getOperand(0), LLVMArg1);
1407 }
1408 
1409 TEST_F(SandboxIRTest, RUOW) {
1410   parseIR(C, R"IR(
1411 declare void @bar0()
1412 declare void @bar1()
1413 
1414 @glob0 = global ptr @bar0
1415 @glob1 = global ptr @bar1
1416 
1417 define i32 @foo(i32 %arg0, i32 %arg1) {
1418   %add0 = add i32 %arg0, %arg1
1419   %gep1 = getelementptr i8, ptr @glob0, i32 1
1420   %gep2 = getelementptr i8, ptr @glob1, i32 1
1421   ret i32 %add0
1422 }
1423 )IR");
1424   llvm::Function &LLVMF = *M->getFunction("foo");
1425   sandboxir::Context Ctx(C);
1426 
1427   auto &F = *Ctx.createFunction(&LLVMF);
1428   auto &BB = *F.begin();
1429   auto *Arg0 = F.getArg(0);
1430   auto *Arg1 = F.getArg(1);
1431   auto It = BB.begin();
1432   auto *I0 = &*It++;
1433   auto *I1 = &*It++;
1434   auto *I2 = &*It++;
1435   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
1436 
1437   bool Replaced;
1438   // Try to replace an operand that doesn't match.
1439   Replaced = I0->replaceUsesOfWith(Ret, Arg1);
1440   EXPECT_FALSE(Replaced);
1441   EXPECT_EQ(I0->getOperand(0), Arg0);
1442   EXPECT_EQ(I0->getOperand(1), Arg1);
1443 
1444   // Replace I0 operands when operands differ.
1445   Replaced = I0->replaceUsesOfWith(Arg0, Arg1);
1446   EXPECT_TRUE(Replaced);
1447   EXPECT_EQ(I0->getOperand(0), Arg1);
1448   EXPECT_EQ(I0->getOperand(1), Arg1);
1449 
1450   // Replace I0 operands when operands are the same.
1451   Replaced = I0->replaceUsesOfWith(Arg1, Arg0);
1452   EXPECT_TRUE(Replaced);
1453   EXPECT_EQ(I0->getOperand(0), Arg0);
1454   EXPECT_EQ(I0->getOperand(1), Arg0);
1455 
1456   // Replace Ret operand.
1457   Replaced = Ret->replaceUsesOfWith(I0, Arg0);
1458   EXPECT_TRUE(Replaced);
1459   EXPECT_EQ(Ret->getOperand(0), Arg0);
1460   // Check RAUW on constant.
1461   auto *Glob0 = cast<sandboxir::Constant>(I1->getOperand(0));
1462   auto *Glob1 = cast<sandboxir::Constant>(I2->getOperand(0));
1463   auto *Glob0Op = Glob0->getOperand(0);
1464   Glob0->replaceUsesOfWith(Glob0Op, Glob1);
1465   EXPECT_EQ(Glob0->getOperand(0), Glob1);
1466 }
1467 
1468 TEST_F(SandboxIRTest, GetExpected) {
1469   parseIR(C, R"IR(
1470 define float @foo(float %v, ptr %ptr) {
1471   %add = fadd float %v, %v
1472   store float %v, ptr %ptr
1473   ret float %v
1474 }
1475 define void @bar(float %v, ptr %ptr) {
1476   ret void
1477 }
1478 )IR");
1479   llvm::Function &Foo = *M->getFunction("foo");
1480   sandboxir::Context Ctx(C);
1481 
1482   Ctx.createFunction(&Foo);
1483   auto *FooBB = cast<sandboxir::BasicBlock>(Ctx.getValue(&*Foo.begin()));
1484   auto FooIt = FooBB->begin();
1485   auto Add = cast<sandboxir::Instruction>(&*FooIt++);
1486   auto *S0 = cast<sandboxir::Instruction>(&*FooIt++);
1487   auto *RetF = cast<sandboxir::Instruction>(&*FooIt++);
1488   // getExpectedValue
1489   EXPECT_EQ(sandboxir::Utils::getExpectedValue(Add), Add);
1490   EXPECT_EQ(sandboxir::Utils::getExpectedValue(S0),
1491             cast<sandboxir::StoreInst>(S0)->getValueOperand());
1492   EXPECT_EQ(sandboxir::Utils::getExpectedValue(RetF),
1493             cast<sandboxir::ReturnInst>(RetF)->getReturnValue());
1494   // getExpectedType
1495   EXPECT_EQ(sandboxir::Utils::getExpectedType(Add), Add->getType());
1496   EXPECT_EQ(sandboxir::Utils::getExpectedType(S0),
1497             cast<sandboxir::StoreInst>(S0)->getValueOperand()->getType());
1498   EXPECT_EQ(sandboxir::Utils::getExpectedType(RetF),
1499             cast<sandboxir::ReturnInst>(RetF)->getReturnValue()->getType());
1500 
1501   // getExpectedValue for void returns
1502   llvm::Function &Bar = *M->getFunction("bar");
1503   Ctx.createFunction(&Bar);
1504   auto *BarBB = cast<sandboxir::BasicBlock>(Ctx.getValue(&*Bar.begin()));
1505   auto BarIt = BarBB->begin();
1506   auto *RetV = cast<sandboxir::Instruction>(&*BarIt++);
1507   EXPECT_EQ(sandboxir::Utils::getExpectedValue(RetV), nullptr);
1508 }
1509 
1510 TEST_F(SandboxIRTest, GetNumBits) {
1511   parseIR(C, R"IR(
1512 define void @foo(float %arg0, double %arg1, i8 %arg2, i64 %arg3) {
1513 bb0:
1514   ret void
1515 }
1516 )IR");
1517   llvm::Function &Foo = *M->getFunction("foo");
1518   sandboxir::Context Ctx(C);
1519   sandboxir::Function *F = Ctx.createFunction(&Foo);
1520   const DataLayout &DL = M->getDataLayout();
1521   // getNumBits for scalars
1522   EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(0), DL),
1523             DL.getTypeSizeInBits(Type::getFloatTy(C)));
1524   EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(1), DL),
1525             DL.getTypeSizeInBits(Type::getDoubleTy(C)));
1526   EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(2), DL), 8u);
1527   EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(3), DL), 64u);
1528 }
1529 
1530 TEST_F(SandboxIRTest, RAUW_RUWIf) {
1531   parseIR(C, R"IR(
1532 define void @foo(ptr %ptr) {
1533   %ld0 = load float, ptr %ptr
1534   %ld1 = load float, ptr %ptr
1535   store float %ld0, ptr %ptr
1536   store float %ld0, ptr %ptr
1537   ret void
1538 }
1539 )IR");
1540   llvm::Function &LLVMF = *M->getFunction("foo");
1541   sandboxir::Context Ctx(C);
1542   llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
1543 
1544   Ctx.createFunction(&LLVMF);
1545   auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB));
1546   auto It = BB->begin();
1547   sandboxir::Instruction *Ld0 = &*It++;
1548   sandboxir::Instruction *Ld1 = &*It++;
1549   sandboxir::Instruction *St0 = &*It++;
1550   sandboxir::Instruction *St1 = &*It++;
1551   // Check RUWIf when the lambda returns false.
1552   Ld0->replaceUsesWithIf(Ld1, [](const sandboxir::Use &Use) { return false; });
1553   EXPECT_EQ(St0->getOperand(0), Ld0);
1554   EXPECT_EQ(St1->getOperand(0), Ld0);
1555   // Check RUWIf when the lambda returns true.
1556   Ld0->replaceUsesWithIf(Ld1, [](const sandboxir::Use &Use) { return true; });
1557   EXPECT_EQ(St0->getOperand(0), Ld1);
1558   EXPECT_EQ(St1->getOperand(0), Ld1);
1559   St0->setOperand(0, Ld0);
1560   St1->setOperand(0, Ld0);
1561   // Check RUWIf user == St0.
1562   Ld0->replaceUsesWithIf(
1563       Ld1, [St0](const sandboxir::Use &Use) { return Use.getUser() == St0; });
1564   EXPECT_EQ(St0->getOperand(0), Ld1);
1565   EXPECT_EQ(St1->getOperand(0), Ld0);
1566   St0->setOperand(0, Ld0);
1567   // Check RUWIf user == St1.
1568   Ld0->replaceUsesWithIf(
1569       Ld1, [St1](const sandboxir::Use &Use) { return Use.getUser() == St1; });
1570   EXPECT_EQ(St0->getOperand(0), Ld0);
1571   EXPECT_EQ(St1->getOperand(0), Ld1);
1572   St1->setOperand(0, Ld0);
1573   // Check RAUW.
1574   Ld1->replaceAllUsesWith(Ld0);
1575   EXPECT_EQ(St0->getOperand(0), Ld0);
1576   EXPECT_EQ(St1->getOperand(0), Ld0);
1577 }
1578 
1579 // Check that the operands/users are counted correctly.
1580 //  I1
1581 // /  \
1582 // \  /
1583 //  I2
1584 TEST_F(SandboxIRTest, DuplicateUses) {
1585   parseIR(C, R"IR(
1586 define void @foo(i8 %v) {
1587   %I1 = add i8 %v, %v
1588   %I2 = add i8 %I1, %I1
1589   ret void
1590 }
1591 )IR");
1592   Function &LLVMF = *M->getFunction("foo");
1593   sandboxir::Context Ctx(C);
1594   auto *F = Ctx.createFunction(&LLVMF);
1595   auto *BB = &*F->begin();
1596   auto It = BB->begin();
1597   auto *I1 = &*It++;
1598   auto *I2 = &*It++;
1599   EXPECT_EQ(range_size(I1->users()), 2u);
1600   EXPECT_EQ(range_size(I2->operands()), 2u);
1601 }
1602 
1603 TEST_F(SandboxIRTest, Function) {
1604   parseIR(C, R"IR(
1605 define void @foo0(i32 %arg0, i32 %arg1) {
1606 bb0:
1607   br label %bb1
1608 bb1:
1609   ret void
1610 }
1611 define void @foo1() {
1612   ret void
1613 }
1614 
1615 )IR");
1616   llvm::Function *LLVMF0 = &*M->getFunction("foo0");
1617   llvm::Function *LLVMF1 = &*M->getFunction("foo1");
1618   llvm::Argument *LLVMArg0 = LLVMF0->getArg(0);
1619   llvm::Argument *LLVMArg1 = LLVMF0->getArg(1);
1620 
1621   sandboxir::Context Ctx(C);
1622   sandboxir::Function *F0 = Ctx.createFunction(LLVMF0);
1623   sandboxir::Function *F1 = Ctx.createFunction(LLVMF1);
1624 
1625   // Check getIterator().
1626   {
1627     auto It0 = F0->getIterator();
1628     auto It1 = F1->getIterator();
1629     EXPECT_EQ(&*It0, F0);
1630     EXPECT_EQ(&*It1, F1);
1631     EXPECT_EQ(std::next(It0), It1);
1632     EXPECT_EQ(std::prev(It1), It0);
1633     EXPECT_EQ(&*std::next(It0), F1);
1634     EXPECT_EQ(&*std::prev(It1), F0);
1635   }
1636   // Check getReverseIterator().
1637   {
1638     auto RevIt0 = F0->getReverseIterator();
1639     auto RevIt1 = F1->getReverseIterator();
1640     EXPECT_EQ(&*RevIt0, F0);
1641     EXPECT_EQ(&*RevIt1, F1);
1642     EXPECT_EQ(std::prev(RevIt0), RevIt1);
1643     EXPECT_EQ(std::next(RevIt1), RevIt0);
1644     EXPECT_EQ(&*std::prev(RevIt0), F1);
1645     EXPECT_EQ(&*std::next(RevIt1), F0);
1646   }
1647 
1648   // Check F arguments
1649   EXPECT_EQ(F0->arg_size(), 2u);
1650   EXPECT_FALSE(F0->arg_empty());
1651   EXPECT_EQ(F0->getArg(0), Ctx.getValue(LLVMArg0));
1652   EXPECT_EQ(F0->getArg(1), Ctx.getValue(LLVMArg1));
1653 
1654   // Check F.begin(), F.end(), Function::iterator
1655   llvm::BasicBlock *LLVMBB = &*LLVMF0->begin();
1656   for (sandboxir::BasicBlock &BB : *F0) {
1657     EXPECT_EQ(&BB, Ctx.getValue(LLVMBB));
1658     LLVMBB = LLVMBB->getNextNode();
1659   }
1660 
1661 #ifndef NDEBUG
1662   {
1663     // Check F.dumpNameAndArgs()
1664     std::string Buff;
1665     raw_string_ostream BS(Buff);
1666     F0->dumpNameAndArgs(BS);
1667     EXPECT_EQ(Buff, "void @foo0(i32 %arg0, i32 %arg1)");
1668   }
1669   {
1670     // Check F.dump()
1671     std::string Buff;
1672     raw_string_ostream BS(Buff);
1673     BS << "\n";
1674     F0->dumpOS(BS);
1675     EXPECT_EQ(Buff, R"IR(
1676 void @foo0(i32 %arg0, i32 %arg1) {
1677 bb0:
1678   br label %bb1 ; SB4. (Br)
1679 
1680 bb1:
1681   ret void ; SB6. (Ret)
1682 }
1683 )IR");
1684   }
1685 #endif // NDEBUG
1686 }
1687 
1688 TEST_F(SandboxIRTest, Module) {
1689   parseIR(C, R"IR(
1690 @glob0 = global i32 42
1691 @glob1 = global i32 43
1692 @internal0 = internal global i32 42
1693 @const0 = constant i32 42
1694 @alias0 = dso_local alias void(), ptr @foo
1695 @ifunc = ifunc void(), ptr @foo
1696 define void @foo() {
1697   ret void
1698 }
1699 define void @bar() {
1700   ret void
1701 }
1702 )IR");
1703   llvm::Module *LLVMM = &*M;
1704   llvm::Function *LLVMFFoo = &*M->getFunction("foo");
1705   llvm::Function *LLVMFBar = &*M->getFunction("bar");
1706 
1707   sandboxir::Context Ctx(C);
1708   auto *M = Ctx.createModule(LLVMM);
1709   // Check getContext().
1710   EXPECT_EQ(&M->getContext(), &Ctx);
1711   // Check getFunction().
1712   auto *FFoo = M->getFunction("foo");
1713   auto *FBar = M->getFunction("bar");
1714   EXPECT_EQ(FFoo, Ctx.getValue(LLVMFFoo));
1715   EXPECT_EQ(FBar, Ctx.getValue(LLVMFBar));
1716   // Check getDataLayout().
1717   EXPECT_EQ(&M->getDataLayout(), &LLVMM->getDataLayout());
1718   // Check getSourceFileName().
1719   EXPECT_EQ(M->getSourceFileName(), LLVMM->getSourceFileName());
1720   // Check getGlobalVariable().
1721   for (const char *Name : {"global0", "global1", "internal0"})
1722     EXPECT_EQ(M->getGlobalVariable(Name),
1723               Ctx.getValue(LLVMM->getGlobalVariable(Name)));
1724   // Check getGlobalVariable(AllowInternal).
1725   {
1726     auto *Internal0 = M->getGlobalVariable("internal0", /*AllowInternal=*/true);
1727     EXPECT_TRUE(Internal0 != nullptr);
1728     EXPECT_EQ(Internal0, Ctx.getValue(LLVMM->getNamedGlobal("internal0")));
1729   }
1730   // Check getNamedGlobal().
1731   {
1732     auto *Internal = M->getNamedGlobal("internal0");
1733     EXPECT_TRUE(Internal != nullptr);
1734     EXPECT_EQ(Internal, Ctx.getValue(LLVMM->getNamedGlobal("internal0")));
1735   }
1736   // Check getNamedAlias().
1737   auto *Alias0 = M->getNamedAlias("alias0");
1738   EXPECT_EQ(Alias0, Ctx.getValue(LLVMM->getNamedAlias("alias0")));
1739   EXPECT_EQ(M->getNamedAlias("aliasFOO"), nullptr);
1740   // Check getNamedIFunc().
1741   auto *IFunc0 = M->getNamedIFunc("ifunc0");
1742   EXPECT_EQ(IFunc0, Ctx.getValue(LLVMM->getNamedAlias("ifunc0")));
1743   EXPECT_EQ(M->getNamedIFunc("ifuncFOO"), nullptr);
1744 }
1745 
1746 TEST_F(SandboxIRTest, BasicBlock) {
1747   parseIR(C, R"IR(
1748 define void @foo(i32 %v1) {
1749 bb0:
1750   br label %bb1
1751 bb1:
1752   ret void
1753 }
1754 )IR");
1755   llvm::Function *LLVMF = &*M->getFunction("foo");
1756   llvm::BasicBlock *LLVMBB0 = getBasicBlockByName(*LLVMF, "bb0");
1757   llvm::BasicBlock *LLVMBB1 = getBasicBlockByName(*LLVMF, "bb1");
1758 
1759   sandboxir::Context Ctx(C);
1760   sandboxir::Function *F = Ctx.createFunction(LLVMF);
1761   auto &BB0 = cast<sandboxir::BasicBlock>(*Ctx.getValue(LLVMBB0));
1762   auto &BB1 = cast<sandboxir::BasicBlock>(*Ctx.getValue(LLVMBB1));
1763 
1764   // Check BB::classof()
1765   EXPECT_TRUE(isa<sandboxir::Value>(BB0));
1766   EXPECT_FALSE(isa<sandboxir::User>(BB0));
1767   EXPECT_FALSE(isa<sandboxir::Instruction>(BB0));
1768   EXPECT_FALSE(isa<sandboxir::Constant>(BB0));
1769   EXPECT_FALSE(isa<sandboxir::Argument>(BB0));
1770 
1771   // Check BB.getParent()
1772   EXPECT_EQ(BB0.getParent(), F);
1773   EXPECT_EQ(BB1.getParent(), F);
1774 
1775   // Check BBIterator, BB.begin(), BB.end().
1776   llvm::Instruction *LLVMI = &*LLVMBB0->begin();
1777   for (sandboxir::Instruction &I : BB0) {
1778     EXPECT_EQ(&I, Ctx.getValue(LLVMI));
1779     LLVMI = LLVMI->getNextNode();
1780     // Check getNodeParent().
1781     EXPECT_EQ(I.getIterator().getNodeParent(), &BB0);
1782   }
1783   LLVMI = &*LLVMBB1->begin();
1784   for (sandboxir::Instruction &I : BB1) {
1785     EXPECT_EQ(&I, Ctx.getValue(LLVMI));
1786     LLVMI = LLVMI->getNextNode();
1787   }
1788   // Check NodeParent() for BB::end().
1789   EXPECT_EQ(BB0.end().getNodeParent(), &BB0);
1790 
1791   // Check BB.getTerminator()
1792   EXPECT_EQ(BB0.getTerminator(), Ctx.getValue(LLVMBB0->getTerminator()));
1793   EXPECT_EQ(BB1.getTerminator(), Ctx.getValue(LLVMBB1->getTerminator()));
1794 
1795   // Check BB.rbegin(), BB.rend()
1796   EXPECT_EQ(&*BB0.rbegin(), BB0.getTerminator());
1797   EXPECT_EQ(&*std::prev(BB0.rend()), &*BB0.begin());
1798 
1799 #ifndef NDEBUG
1800   {
1801     // Check BB.dump()
1802     std::string Buff;
1803     raw_string_ostream BS(Buff);
1804     BS << "\n";
1805     BB0.dumpOS(BS);
1806     EXPECT_EQ(Buff, R"IR(
1807 bb0:
1808   br label %bb1 ; SB3. (Br)
1809 )IR");
1810   }
1811 #endif // NDEBUG
1812 }
1813 
1814 TEST_F(SandboxIRTest, Instruction) {
1815   parseIR(C, R"IR(
1816 define void @foo(i8 %v1, ptr %ptr) {
1817 bb0:
1818   %add0 = add i8 %v1, %v1
1819   %sub1 = sub i8 %add0, %v1
1820   ret void
1821 
1822 bb1:
1823   %add1 = add i8 %v1, %v1
1824   %sub2 = sub i8 %add1, %v1
1825   %ld0 = load i8, ptr %ptr
1826   store i8 %ld0, ptr %ptr
1827   store volatile i8 %ld0, ptr %ptr
1828   %atomicrmw = atomicrmw add ptr %ptr, i8 %v1 acquire
1829   %udiv = udiv i8 %ld0, %v1
1830   %urem = urem i8 %ld0, %v1
1831   call void @foo()
1832   ret void
1833 }
1834 )IR");
1835   llvm::Function *LLVMF = &*M->getFunction("foo");
1836   llvm::BasicBlock *LLVMBB1 = getBasicBlockByName(*LLVMF, "bb1");
1837   sandboxir::Context Ctx(C);
1838   sandboxir::Function *F = Ctx.createFunction(LLVMF);
1839   auto *Arg = F->getArg(0);
1840   auto *BB = cast<sandboxir::BasicBlock>(
1841       Ctx.getValue(getBasicBlockByName(*LLVMF, "bb0")));
1842   auto It = BB->begin();
1843   auto *I0 = &*It++;
1844   auto *I1 = &*It++;
1845   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
1846 
1847   // Check getPrevNode().
1848   EXPECT_EQ(Ret->getPrevNode(), I1);
1849   EXPECT_EQ(I1->getPrevNode(), I0);
1850   EXPECT_EQ(I0->getPrevNode(), nullptr);
1851 
1852   // Check getNextNode().
1853   EXPECT_EQ(I0->getNextNode(), I1);
1854   EXPECT_EQ(I1->getNextNode(), Ret);
1855   EXPECT_EQ(Ret->getNextNode(), nullptr);
1856 
1857   // Check getIterator().
1858   EXPECT_EQ(I0->getIterator(), std::next(BB->begin(), 0));
1859   EXPECT_EQ(I1->getIterator(), std::next(BB->begin(), 1));
1860   EXPECT_EQ(Ret->getIterator(), std::next(BB->begin(), 2));
1861 
1862   // Check getOpcode().
1863   EXPECT_EQ(I0->getOpcode(), sandboxir::Instruction::Opcode::Add);
1864   EXPECT_EQ(I1->getOpcode(), sandboxir::Instruction::Opcode::Sub);
1865   EXPECT_EQ(Ret->getOpcode(), sandboxir::Instruction::Opcode::Ret);
1866 
1867   // Check moveBefore(I).
1868   I1->moveBefore(I0);
1869   EXPECT_EQ(I0->getPrevNode(), I1);
1870   EXPECT_EQ(I1->getNextNode(), I0);
1871 
1872   // Check moveAfter(I).
1873   I1->moveAfter(I0);
1874   EXPECT_EQ(I0->getNextNode(), I1);
1875   EXPECT_EQ(I1->getPrevNode(), I0);
1876 
1877   // Check comesBefore(I).
1878   EXPECT_TRUE(I0->comesBefore(I1));
1879   EXPECT_FALSE(I1->comesBefore(I0));
1880 
1881   // Check moveBefore(BB, It).
1882   I1->moveBefore(*BB, BB->begin());
1883   EXPECT_EQ(I1->getPrevNode(), nullptr);
1884   EXPECT_EQ(I1->getNextNode(), I0);
1885   I1->moveBefore(*BB, BB->end());
1886   EXPECT_EQ(I1->getNextNode(), nullptr);
1887   EXPECT_EQ(Ret->getNextNode(), I1);
1888   I1->moveBefore(*BB, std::next(BB->begin()));
1889   EXPECT_EQ(I0->getNextNode(), I1);
1890   EXPECT_EQ(I1->getNextNode(), Ret);
1891 
1892   // Check removeFromParent().
1893   I0->removeFromParent();
1894 #ifndef NDEBUG
1895   EXPECT_DEATH(I0->getPrevNode(), ".*Detached.*");
1896   EXPECT_DEATH(I0->getNextNode(), ".*Detached.*");
1897 #endif // NDEBUG
1898   EXPECT_EQ(I0->getParent(), nullptr);
1899   EXPECT_EQ(I1->getPrevNode(), nullptr);
1900   EXPECT_EQ(I0->getOperand(0), Arg);
1901 
1902   // Check insertBefore().
1903   I0->insertBefore(I1);
1904   EXPECT_EQ(I1->getPrevNode(), I0);
1905 
1906   // Check insertInto().
1907   I0->removeFromParent();
1908   I0->insertInto(BB, BB->end());
1909   EXPECT_EQ(Ret->getNextNode(), I0);
1910   I0->moveBefore(I1);
1911   EXPECT_EQ(I0->getNextNode(), I1);
1912 
1913   // Check eraseFromParent().
1914 #ifndef NDEBUG
1915   EXPECT_DEATH(I0->eraseFromParent(), "Still connected to users.*");
1916 #endif
1917   I1->eraseFromParent();
1918   EXPECT_EQ(I0->getNumUses(), 0u);
1919   EXPECT_EQ(I0->getNextNode(), Ret);
1920 
1921   for (auto &LLVMI : *LLVMBB1) {
1922     auto &I = cast<sandboxir::Instruction>(*Ctx.getValue(&LLVMI));
1923     // Check isTerminator().
1924     EXPECT_EQ(LLVMI.isTerminator(), I.isTerminator());
1925     // Check isUnaryOp().
1926     EXPECT_EQ(LLVMI.isUnaryOp(), I.isUnaryOp());
1927     // Check isBinaryOp().
1928     EXPECT_EQ(LLVMI.isBinaryOp(), I.isBinaryOp());
1929     // Check isIntDivRem().
1930     EXPECT_EQ(LLVMI.isIntDivRem(), I.isIntDivRem());
1931     // Check isShift().
1932     EXPECT_EQ(LLVMI.isShift(), I.isShift());
1933     // Check isCast().
1934     EXPECT_EQ(LLVMI.isCast(), I.isCast());
1935     // Check isAssociative().
1936     EXPECT_EQ(LLVMI.isAssociative(), I.isAssociative());
1937     // Check isCommutative().
1938     EXPECT_EQ(LLVMI.isCommutative(), I.isCommutative());
1939     // Check isIdempotent().
1940     EXPECT_EQ(LLVMI.isIdempotent(), I.isIdempotent());
1941     // Check isNilpotent().
1942     EXPECT_EQ(LLVMI.isNilpotent(), I.isNilpotent());
1943     // Check mayWriteToMemory().
1944     EXPECT_EQ(LLVMI.mayWriteToMemory(), I.mayWriteToMemory());
1945     // Check mayReadFromMemory().
1946     EXPECT_EQ(LLVMI.mayReadFromMemory(), I.mayReadFromMemory());
1947     // Check mayReadOrWriteMemory().
1948     EXPECT_EQ(LLVMI.mayReadOrWriteMemory(), I.mayReadOrWriteMemory());
1949     // Check isAtomic().
1950     EXPECT_EQ(LLVMI.isAtomic(), I.isAtomic());
1951     if (I.isAtomic()) {
1952       // Check hasAtomicLoad().
1953       EXPECT_EQ(LLVMI.hasAtomicLoad(), I.hasAtomicLoad());
1954       // Check hasAtomicStore().
1955       EXPECT_EQ(LLVMI.hasAtomicStore(), I.hasAtomicStore());
1956     }
1957     // Check isVolatile().
1958     EXPECT_EQ(LLVMI.isVolatile(), I.isVolatile());
1959     // Check getAccessType().
1960     EXPECT_EQ(Ctx.getType(LLVMI.getAccessType()), I.getAccessType());
1961     // Check mayThrow().
1962     EXPECT_EQ(LLVMI.mayThrow(), I.mayThrow());
1963     // Check isFenceLike().
1964     EXPECT_EQ(LLVMI.isFenceLike(), I.isFenceLike());
1965     // Check mayHaveSideEffects().
1966     EXPECT_EQ(LLVMI.mayHaveSideEffects(), I.mayHaveSideEffects());
1967   }
1968 }
1969 
1970 TEST_F(SandboxIRTest, Instruction_isStackSaveOrRestoreIntrinsic) {
1971   parseIR(C, R"IR(
1972 declare void @llvm.sideeffect()
1973 define void @foo(i8 %v1, ptr %ptr) {
1974   %add = add i8 %v1, %v1
1975   %stacksave = call ptr @llvm.stacksave()
1976   call void @llvm.stackrestore(ptr %stacksave)
1977   call void @llvm.sideeffect()
1978   ret void
1979 }
1980 )IR");
1981   llvm::Function *LLVMF = &*M->getFunction("foo");
1982   sandboxir::Context Ctx(C);
1983   sandboxir::Function *F = Ctx.createFunction(LLVMF);
1984   auto *BB = &*F->begin();
1985   auto It = BB->begin();
1986   auto *Add = cast<sandboxir::BinaryOperator>(&*It++);
1987   auto *StackSave = cast<sandboxir::CallInst>(&*It++);
1988   auto *StackRestore = cast<sandboxir::CallInst>(&*It++);
1989   auto *Other = cast<sandboxir::CallInst>(&*It++);
1990   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
1991 
1992   EXPECT_FALSE(Add->isStackSaveOrRestoreIntrinsic());
1993   EXPECT_TRUE(StackSave->isStackSaveOrRestoreIntrinsic());
1994   EXPECT_TRUE(StackRestore->isStackSaveOrRestoreIntrinsic());
1995   EXPECT_FALSE(Other->isStackSaveOrRestoreIntrinsic());
1996   EXPECT_FALSE(Ret->isStackSaveOrRestoreIntrinsic());
1997 }
1998 
1999 TEST_F(SandboxIRTest, Instruction_isMemDepCandidate) {
2000   parseIR(C, R"IR(
2001 declare void @llvm.fake.use(...)
2002 declare void @llvm.sideeffect()
2003 declare void @llvm.pseudoprobe(i64, i64, i32, i64)
2004 declare void @bar()
2005 define void @foo(i8 %v1, ptr %ptr) {
2006   %add0 = add i8 %v1, %v1
2007   %ld0 = load i8, ptr %ptr
2008   store i8 %v1, ptr %ptr
2009   call void @llvm.sideeffect()
2010   call void @llvm.pseudoprobe(i64 42, i64 1, i32 0, i64 -1)
2011   call void @llvm.fake.use(ptr %ptr)
2012   call void @bar()
2013   ret void
2014 }
2015 )IR");
2016   llvm::Function *LLVMF = &*M->getFunction("foo");
2017   sandboxir::Context Ctx(C);
2018   sandboxir::Function *F = Ctx.createFunction(LLVMF);
2019   auto *BB = &*F->begin();
2020   auto It = BB->begin();
2021   auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
2022   auto *Ld0 = cast<sandboxir::LoadInst>(&*It++);
2023   auto *St0 = cast<sandboxir::StoreInst>(&*It++);
2024   auto *SideEffect0 = cast<sandboxir::CallInst>(&*It++);
2025   auto *PseudoProbe0 = cast<sandboxir::CallInst>(&*It++);
2026   auto *OtherIntrinsic0 = cast<sandboxir::CallInst>(&*It++);
2027   auto *CallBar = cast<sandboxir::CallInst>(&*It++);
2028   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
2029 
2030   EXPECT_FALSE(Add0->isMemDepCandidate());
2031   EXPECT_TRUE(Ld0->isMemDepCandidate());
2032   EXPECT_TRUE(St0->isMemDepCandidate());
2033   EXPECT_FALSE(SideEffect0->isMemDepCandidate());
2034   EXPECT_FALSE(PseudoProbe0->isMemDepCandidate());
2035   EXPECT_TRUE(OtherIntrinsic0->isMemDepCandidate());
2036   EXPECT_TRUE(CallBar->isMemDepCandidate());
2037   EXPECT_FALSE(Ret->isMemDepCandidate());
2038 }
2039 
2040 TEST_F(SandboxIRTest, VAArgInst) {
2041   parseIR(C, R"IR(
2042 define void @foo(ptr %va) {
2043   %va_arg = va_arg ptr %va, i32
2044   ret void
2045 }
2046 )IR");
2047   llvm::Function *LLVMF = &*M->getFunction("foo");
2048 
2049   sandboxir::Context Ctx(C);
2050   sandboxir::Function *F = Ctx.createFunction(LLVMF);
2051   auto *Arg = F->getArg(0);
2052   auto *BB = &*F->begin();
2053   auto It = BB->begin();
2054   auto *VA = cast<sandboxir::VAArgInst>(&*It++);
2055   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
2056 
2057   // Check getPointerOperand().
2058   EXPECT_EQ(VA->getPointerOperand(), Arg);
2059   // Check getPOinterOperandIndex().
2060   EXPECT_EQ(sandboxir::VAArgInst::getPointerOperandIndex(),
2061             llvm::VAArgInst::getPointerOperandIndex());
2062   // Check create().
2063   auto *NewVATy = sandboxir::Type::getInt8Ty(Ctx);
2064   auto *NewVA = sandboxir::VAArgInst::create(Arg, NewVATy, Ret->getIterator(),
2065                                              Ret->getParent(), Ctx, "NewVA");
2066   EXPECT_EQ(NewVA->getNextNode(), Ret);
2067   EXPECT_EQ(NewVA->getType(), NewVATy);
2068 #ifndef NDEBUG
2069   EXPECT_EQ(NewVA->getName(), "NewVA");
2070 #endif // NDEBUG
2071 }
2072 
2073 TEST_F(SandboxIRTest, FreezeInst) {
2074   parseIR(C, R"IR(
2075 define void @foo(i8 %arg) {
2076   freeze i8 %arg
2077   ret void
2078 }
2079 )IR");
2080   llvm::Function *LLVMF = &*M->getFunction("foo");
2081 
2082   sandboxir::Context Ctx(C);
2083   sandboxir::Function *F = Ctx.createFunction(LLVMF);
2084   auto *Arg = F->getArg(0);
2085   auto *BB = &*F->begin();
2086   auto It = BB->begin();
2087   auto *Freeze = cast<sandboxir::FreezeInst>(&*It++);
2088   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
2089 
2090   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Freeze));
2091   EXPECT_EQ(Freeze->getOperand(0), Arg);
2092 
2093   // Check create().
2094   auto *NewFreeze = sandboxir::FreezeInst::create(
2095       Arg, Ret->getIterator(), Ret->getParent(), Ctx, "NewFreeze");
2096   EXPECT_EQ(NewFreeze->getNextNode(), Ret);
2097 #ifndef NDEBUG
2098   EXPECT_EQ(NewFreeze->getName(), "NewFreeze");
2099 #endif // NDEBUG
2100 }
2101 
2102 TEST_F(SandboxIRTest, FenceInst) {
2103   parseIR(C, R"IR(
2104 define void @foo() {
2105   fence syncscope("singlethread") seq_cst
2106   ret void
2107 }
2108 )IR");
2109   llvm::Function *LLVMF = &*M->getFunction("foo");
2110   llvm::BasicBlock *LLVMBB = &*LLVMF->begin();
2111   auto *LLVMFence = cast<llvm::FenceInst>(&*LLVMBB->begin());
2112   sandboxir::Context Ctx(C);
2113   sandboxir::Function *F = Ctx.createFunction(LLVMF);
2114   auto *BB = &*F->begin();
2115   auto It = BB->begin();
2116   auto *Fence = cast<sandboxir::FenceInst>(&*It++);
2117   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
2118 
2119   // Check getOrdering().
2120   EXPECT_EQ(Fence->getOrdering(), LLVMFence->getOrdering());
2121   // Check setOrdering().
2122   auto OrigOrdering = Fence->getOrdering();
2123   auto NewOrdering = AtomicOrdering::Release;
2124   EXPECT_NE(NewOrdering, OrigOrdering);
2125   Fence->setOrdering(NewOrdering);
2126   EXPECT_EQ(Fence->getOrdering(), NewOrdering);
2127   Fence->setOrdering(OrigOrdering);
2128   EXPECT_EQ(Fence->getOrdering(), OrigOrdering);
2129   // Check getSyncScopeID().
2130   EXPECT_EQ(Fence->getSyncScopeID(), LLVMFence->getSyncScopeID());
2131   // Check setSyncScopeID().
2132   auto OrigSSID = Fence->getSyncScopeID();
2133   auto NewSSID = SyncScope::System;
2134   EXPECT_NE(NewSSID, OrigSSID);
2135   Fence->setSyncScopeID(NewSSID);
2136   EXPECT_EQ(Fence->getSyncScopeID(), NewSSID);
2137   Fence->setSyncScopeID(OrigSSID);
2138   EXPECT_EQ(Fence->getSyncScopeID(), OrigSSID);
2139   // Check create().
2140   auto *NewFence =
2141       sandboxir::FenceInst::create(AtomicOrdering::Release, Ret->getIterator(),
2142                                    BB, Ctx, SyncScope::SingleThread);
2143   EXPECT_EQ(NewFence->getNextNode(), Ret);
2144   EXPECT_EQ(NewFence->getOrdering(), AtomicOrdering::Release);
2145   EXPECT_EQ(NewFence->getSyncScopeID(), SyncScope::SingleThread);
2146 }
2147 
2148 TEST_F(SandboxIRTest, SelectInst) {
2149   parseIR(C, R"IR(
2150 define void @foo(i1 %c0, i8 %v0, i8 %v1, i1 %c1) {
2151   %sel = select i1 %c0, i8 %v0, i8 %v1
2152   ret void
2153 }
2154 )IR");
2155   llvm::Function *LLVMF = &*M->getFunction("foo");
2156   sandboxir::Context Ctx(C);
2157   sandboxir::Function *F = Ctx.createFunction(LLVMF);
2158   auto *Cond0 = F->getArg(0);
2159   auto *V0 = F->getArg(1);
2160   auto *V1 = F->getArg(2);
2161   auto *Cond1 = F->getArg(3);
2162   auto *BB = &*F->begin();
2163   auto It = BB->begin();
2164   auto *Select = cast<sandboxir::SelectInst>(&*It++);
2165   const auto *ConstSelect = Select; // To test the const getters.
2166   auto *Ret = &*It++;
2167 
2168   // Check getCondition().
2169   EXPECT_EQ(Select->getCondition(), Cond0);
2170   EXPECT_EQ(ConstSelect->getCondition(), Cond0);
2171   // Check getTrueValue().
2172   EXPECT_EQ(Select->getTrueValue(), V0);
2173   EXPECT_EQ(ConstSelect->getTrueValue(), V0);
2174   // Check getFalseValue().
2175   EXPECT_EQ(Select->getFalseValue(), V1);
2176   EXPECT_EQ(ConstSelect->getFalseValue(), V1);
2177   // Check setCondition().
2178   Select->setCondition(Cond1);
2179   EXPECT_EQ(Select->getCondition(), Cond1);
2180   // Check setTrueValue().
2181   Select->setTrueValue(V1);
2182   EXPECT_EQ(Select->getTrueValue(), V1);
2183   // Check setFalseValue().
2184   Select->setFalseValue(V0);
2185   EXPECT_EQ(Select->getFalseValue(), V0);
2186   // Check swapValues().
2187   Select->swapValues();
2188   EXPECT_EQ(Select->getTrueValue(), V0);
2189   EXPECT_EQ(Select->getFalseValue(), V1);
2190   // Check areInvalidOperands.
2191   EXPECT_EQ(sandboxir::SelectInst::areInvalidOperands(Cond0, V0, V1), nullptr);
2192   EXPECT_NE(sandboxir::SelectInst::areInvalidOperands(V0, V1, Cond0), nullptr);
2193 
2194   {
2195     // Check SelectInst::create() InsertBefore.
2196     auto *NewSel = cast<sandboxir::SelectInst>(sandboxir::SelectInst::create(
2197         Cond0, V0, V1, /*InsertBefore=*/Ret, Ctx));
2198     EXPECT_EQ(NewSel->getCondition(), Cond0);
2199     EXPECT_EQ(NewSel->getTrueValue(), V0);
2200     EXPECT_EQ(NewSel->getFalseValue(), V1);
2201     EXPECT_EQ(NewSel->getNextNode(), Ret);
2202   }
2203   {
2204     // Check SelectInst::create() InsertAtEnd.
2205     auto *NewSel = cast<sandboxir::SelectInst>(
2206         sandboxir::SelectInst::create(Cond0, V0, V1, /*InsertAtEnd=*/BB, Ctx));
2207     EXPECT_EQ(NewSel->getCondition(), Cond0);
2208     EXPECT_EQ(NewSel->getTrueValue(), V0);
2209     EXPECT_EQ(NewSel->getFalseValue(), V1);
2210     EXPECT_EQ(NewSel->getPrevNode(), Ret);
2211   }
2212   {
2213     // Check SelectInst::create() Folded.
2214     auto *False = sandboxir::ConstantInt::get(sandboxir::Type::getInt1Ty(Ctx),
2215                                               0, /*IsSigned=*/false);
2216     auto *FortyTwo =
2217         sandboxir::ConstantInt::get(sandboxir::Type::getInt1Ty(Ctx), 42,
2218                                     /*IsSigned=*/false);
2219     auto *NewSel =
2220         sandboxir::SelectInst::create(False, FortyTwo, FortyTwo, Ret, Ctx);
2221     EXPECT_TRUE(isa<sandboxir::Constant>(NewSel));
2222     EXPECT_EQ(NewSel, FortyTwo);
2223   }
2224 }
2225 
2226 TEST_F(SandboxIRTest, ExtractElementInst) {
2227   parseIR(C, R"IR(
2228 define void @foo(<2 x i8> %vec, i32 %idx) {
2229   %ins0 = extractelement <2 x i8> %vec, i32 %idx
2230   ret void
2231 }
2232 )IR");
2233   Function &LLVMF = *M->getFunction("foo");
2234   sandboxir::Context Ctx(C);
2235   auto &F = *Ctx.createFunction(&LLVMF);
2236   auto *ArgVec = F.getArg(0);
2237   auto *ArgIdx = F.getArg(1);
2238   auto *BB = &*F.begin();
2239   auto It = BB->begin();
2240   auto *EI = cast<sandboxir::ExtractElementInst>(&*It++);
2241   auto *Ret = &*It++;
2242 
2243   EXPECT_EQ(EI->getOpcode(), sandboxir::Instruction::Opcode::ExtractElement);
2244   EXPECT_EQ(EI->getOperand(0), ArgVec);
2245   EXPECT_EQ(EI->getOperand(1), ArgIdx);
2246   EXPECT_EQ(EI->getVectorOperand(), ArgVec);
2247   EXPECT_EQ(EI->getIndexOperand(), ArgIdx);
2248   EXPECT_EQ(EI->getVectorOperandType(), ArgVec->getType());
2249 
2250   auto *NewI1 =
2251       cast<sandboxir::ExtractElementInst>(sandboxir::ExtractElementInst::create(
2252           ArgVec, ArgIdx, Ret, Ctx, "NewExtrBeforeRet"));
2253   EXPECT_EQ(NewI1->getOperand(0), ArgVec);
2254   EXPECT_EQ(NewI1->getOperand(1), ArgIdx);
2255   EXPECT_EQ(NewI1->getNextNode(), Ret);
2256 
2257   auto *NewI2 =
2258       cast<sandboxir::ExtractElementInst>(sandboxir::ExtractElementInst::create(
2259           ArgVec, ArgIdx, BB, Ctx, "NewExtrAtEndOfBB"));
2260   EXPECT_EQ(NewI2->getPrevNode(), Ret);
2261 
2262   auto *LLVMArgVec = LLVMF.getArg(0);
2263   auto *LLVMArgIdx = LLVMF.getArg(1);
2264   EXPECT_EQ(sandboxir::ExtractElementInst::isValidOperands(ArgVec, ArgIdx),
2265             llvm::ExtractElementInst::isValidOperands(LLVMArgVec, LLVMArgIdx));
2266   EXPECT_EQ(sandboxir::ExtractElementInst::isValidOperands(ArgIdx, ArgVec),
2267             llvm::ExtractElementInst::isValidOperands(LLVMArgIdx, LLVMArgVec));
2268 }
2269 
2270 TEST_F(SandboxIRTest, InsertElementInst) {
2271   parseIR(C, R"IR(
2272 define void @foo(i8 %v0, i8 %v1, <2 x i8> %vec) {
2273   %ins0 = insertelement <2 x i8> poison, i8 %v0, i32 0
2274   %ins1 = insertelement <2 x i8> %ins0, i8 %v1, i32 1
2275   ret void
2276 }
2277 )IR");
2278   Function &LLVMF = *M->getFunction("foo");
2279   sandboxir::Context Ctx(C);
2280   auto &F = *Ctx.createFunction(&LLVMF);
2281   auto *Arg0 = F.getArg(0);
2282   auto *Arg1 = F.getArg(1);
2283   auto *ArgVec = F.getArg(2);
2284   auto *BB = &*F.begin();
2285   auto It = BB->begin();
2286   auto *Ins0 = cast<sandboxir::InsertElementInst>(&*It++);
2287   auto *Ins1 = cast<sandboxir::InsertElementInst>(&*It++);
2288   auto *Ret = &*It++;
2289 
2290   EXPECT_EQ(Ins0->getOpcode(), sandboxir::Instruction::Opcode::InsertElement);
2291   EXPECT_EQ(Ins0->getOperand(1), Arg0);
2292   EXPECT_EQ(Ins1->getOperand(1), Arg1);
2293   EXPECT_EQ(Ins1->getOperand(0), Ins0);
2294   auto *Poison = Ins0->getOperand(0);
2295   auto *Idx = Ins0->getOperand(2);
2296   auto *NewI1 =
2297       cast<sandboxir::InsertElementInst>(sandboxir::InsertElementInst::create(
2298           Poison, Arg0, Idx, Ret, Ctx, "NewIns1"));
2299   EXPECT_EQ(NewI1->getOperand(0), Poison);
2300   EXPECT_EQ(NewI1->getNextNode(), Ret);
2301 
2302   auto *NewI2 =
2303       cast<sandboxir::InsertElementInst>(sandboxir::InsertElementInst::create(
2304           Poison, Arg0, Idx, BB, Ctx, "NewIns2"));
2305   EXPECT_EQ(NewI2->getPrevNode(), Ret);
2306 
2307   auto *LLVMArg0 = LLVMF.getArg(0);
2308   auto *LLVMArgVec = LLVMF.getArg(2);
2309   auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 0);
2310   auto *LLVMZero = llvm::ConstantInt::get(Type::getInt8Ty(C), 0);
2311   EXPECT_EQ(
2312       sandboxir::InsertElementInst::isValidOperands(ArgVec, Arg0, Zero),
2313       llvm::InsertElementInst::isValidOperands(LLVMArgVec, LLVMArg0, LLVMZero));
2314   EXPECT_EQ(
2315       sandboxir::InsertElementInst::isValidOperands(Arg0, ArgVec, Zero),
2316       llvm::InsertElementInst::isValidOperands(LLVMArg0, LLVMArgVec, LLVMZero));
2317 }
2318 
2319 TEST_F(SandboxIRTest, ShuffleVectorInst) {
2320   parseIR(C, R"IR(
2321 define void @foo(<2 x i8> %v1, <2 x i8> %v2) {
2322   %shuf = shufflevector <2 x i8> %v1, <2 x i8> %v2, <2 x i32> <i32 0, i32 2>
2323   %extr = extractelement <2 x i8> <i8 0, i8 1>, i32 0
2324   ret void
2325 }
2326 )IR");
2327   Function &LLVMF = *M->getFunction("foo");
2328   sandboxir::Context Ctx(C);
2329   auto &F = *Ctx.createFunction(&LLVMF);
2330   auto *ArgV1 = F.getArg(0);
2331   auto *ArgV2 = F.getArg(1);
2332   auto *BB = &*F.begin();
2333   auto It = BB->begin();
2334   auto *SVI = cast<sandboxir::ShuffleVectorInst>(&*It++);
2335   auto *EEI = cast<sandboxir::ExtractElementInst>(&*It++);
2336   auto *Ret = &*It++;
2337 
2338   EXPECT_EQ(SVI->getOpcode(), sandboxir::Instruction::Opcode::ShuffleVector);
2339   EXPECT_EQ(SVI->getOperand(0), ArgV1);
2340   EXPECT_EQ(SVI->getOperand(1), ArgV2);
2341 
2342   // In order to test all the methods we need masks of different lengths, so we
2343   // can't simply reuse one of the instructions created above. This helper
2344   // creates a new `shufflevector %v1, %2, <mask>` with the given mask indices.
2345   auto CreateShuffleWithMask = [&](auto &&...Indices) {
2346     SmallVector<int, 4> Mask = {Indices...};
2347     return cast<sandboxir::ShuffleVectorInst>(
2348         sandboxir::ShuffleVectorInst::create(ArgV1, ArgV2, Mask, Ret, Ctx));
2349   };
2350 
2351   // create (InsertBefore)
2352   auto *NewI1 =
2353       cast<sandboxir::ShuffleVectorInst>(sandboxir::ShuffleVectorInst::create(
2354           ArgV1, ArgV2, ArrayRef<int>({0, 2, 1, 3}), Ret, Ctx,
2355           "NewShuffleBeforeRet"));
2356   EXPECT_EQ(NewI1->getOperand(0), ArgV1);
2357   EXPECT_EQ(NewI1->getOperand(1), ArgV2);
2358   EXPECT_EQ(NewI1->getNextNode(), Ret);
2359 #ifndef NDEBUG
2360   EXPECT_EQ(NewI1->getName(), "NewShuffleBeforeRet");
2361 #endif
2362 
2363   // create (InsertAtEnd)
2364   auto *NewI2 =
2365       cast<sandboxir::ShuffleVectorInst>(sandboxir::ShuffleVectorInst::create(
2366           ArgV1, ArgV2, ArrayRef<int>({0, 1}), BB, Ctx, "NewShuffleAtEndOfBB"));
2367   EXPECT_EQ(NewI2->getPrevNode(), Ret);
2368 
2369   // Test the path that creates a folded constant. We're currently using an
2370   // extractelement instruction with a constant operand in the textual IR above
2371   // to obtain a constant vector to work with.
2372   // TODO: Refactor this once sandboxir::ConstantVector lands.
2373   auto *ShouldBeConstant = sandboxir::ShuffleVectorInst::create(
2374       EEI->getOperand(0), EEI->getOperand(0), ArrayRef<int>({0, 3}), BB, Ctx);
2375   EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant));
2376 
2377   // isValidOperands
2378   auto *LLVMArgV1 = LLVMF.getArg(0);
2379   auto *LLVMArgV2 = LLVMF.getArg(1);
2380   SmallVector<int, 2> Mask({1, 2});
2381   EXPECT_EQ(
2382       sandboxir::ShuffleVectorInst::isValidOperands(ArgV1, ArgV2, Mask),
2383       llvm::ShuffleVectorInst::isValidOperands(LLVMArgV1, LLVMArgV2, Mask));
2384   EXPECT_EQ(sandboxir::ShuffleVectorInst::isValidOperands(ArgV1, ArgV1, ArgV1),
2385             llvm::ShuffleVectorInst::isValidOperands(LLVMArgV1, LLVMArgV1,
2386                                                      LLVMArgV1));
2387 
2388   // commute
2389   {
2390     auto *I = CreateShuffleWithMask(0, 2);
2391     I->commute();
2392     EXPECT_EQ(I->getOperand(0), ArgV2);
2393     EXPECT_EQ(I->getOperand(1), ArgV1);
2394     EXPECT_THAT(I->getShuffleMask(), testing::ElementsAre(2, 0));
2395   }
2396 
2397   // getType
2398   EXPECT_EQ(SVI->getType(), ArgV1->getType());
2399 
2400   // getMaskValue
2401   EXPECT_EQ(SVI->getMaskValue(0), 0);
2402   EXPECT_EQ(SVI->getMaskValue(1), 2);
2403 
2404   // getShuffleMask / getShuffleMaskForBitcode
2405   {
2406     EXPECT_THAT(SVI->getShuffleMask(), testing::ElementsAre(0, 2));
2407 
2408     SmallVector<int, 2> Result;
2409     SVI->getShuffleMask(Result);
2410     EXPECT_THAT(Result, testing::ElementsAre(0, 2));
2411 
2412     Result.clear();
2413     sandboxir::ShuffleVectorInst::getShuffleMask(
2414         SVI->getShuffleMaskForBitcode(), Result);
2415     EXPECT_THAT(Result, testing::ElementsAre(0, 2));
2416   }
2417 
2418   // convertShuffleMaskForBitcode
2419   {
2420     auto *C = sandboxir::ShuffleVectorInst::convertShuffleMaskForBitcode(
2421         ArrayRef<int>({2, 3}), ArgV1->getType());
2422     SmallVector<int, 2> Result;
2423     sandboxir::ShuffleVectorInst::getShuffleMask(C, Result);
2424     EXPECT_THAT(Result, testing::ElementsAre(2, 3));
2425   }
2426 
2427   // setShuffleMask
2428   {
2429     auto *I = CreateShuffleWithMask(0, 1);
2430     I->setShuffleMask(ArrayRef<int>({2, 3}));
2431     EXPECT_THAT(I->getShuffleMask(), testing::ElementsAre(2, 3));
2432   }
2433 
2434   // The following functions check different mask properties. Note that most
2435   // of these come in three different flavors: a method that checks the mask
2436   // in the current instructions and two static member functions that check
2437   // a mask given as an ArrayRef<int> or Constant*, so there's quite a bit of
2438   // repetition in order to check all of them.
2439 
2440   // changesLength / increasesLength
2441   {
2442     auto *I = CreateShuffleWithMask(1);
2443     EXPECT_TRUE(I->changesLength());
2444     EXPECT_FALSE(I->increasesLength());
2445   }
2446   {
2447     auto *I = CreateShuffleWithMask(1, 1);
2448     EXPECT_FALSE(I->changesLength());
2449     EXPECT_FALSE(I->increasesLength());
2450   }
2451   {
2452     auto *I = CreateShuffleWithMask(1, 1, 1);
2453     EXPECT_TRUE(I->changesLength());
2454     EXPECT_TRUE(I->increasesLength());
2455   }
2456 
2457   // isSingleSource / isSingleSourceMask
2458   {
2459     auto *I = CreateShuffleWithMask(0, 1);
2460     EXPECT_TRUE(I->isSingleSource());
2461     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSingleSourceMask(
2462         I->getShuffleMaskForBitcode(), 2));
2463     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSingleSourceMask(
2464         I->getShuffleMask(), 2));
2465   }
2466   {
2467     auto *I = CreateShuffleWithMask(0, 2);
2468     EXPECT_FALSE(I->isSingleSource());
2469     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSingleSourceMask(
2470         I->getShuffleMaskForBitcode(), 2));
2471     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSingleSourceMask(
2472         I->getShuffleMask(), 2));
2473   }
2474 
2475   // isIdentity / isIdentityMask
2476   {
2477     auto *I = CreateShuffleWithMask(0, 1);
2478     EXPECT_TRUE(I->isIdentity());
2479     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isIdentityMask(
2480         I->getShuffleMaskForBitcode(), 2));
2481     EXPECT_TRUE(
2482         sandboxir::ShuffleVectorInst::isIdentityMask(I->getShuffleMask(), 2));
2483   }
2484   {
2485     auto *I = CreateShuffleWithMask(1, 0);
2486     EXPECT_FALSE(I->isIdentity());
2487     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isIdentityMask(
2488         I->getShuffleMaskForBitcode(), 2));
2489     EXPECT_FALSE(
2490         sandboxir::ShuffleVectorInst::isIdentityMask(I->getShuffleMask(), 2));
2491   }
2492 
2493   // isIdentityWithPadding
2494   EXPECT_TRUE(CreateShuffleWithMask(0, 1, -1, -1)->isIdentityWithPadding());
2495   EXPECT_FALSE(CreateShuffleWithMask(0, 1)->isIdentityWithPadding());
2496 
2497   // isIdentityWithExtract
2498   EXPECT_TRUE(CreateShuffleWithMask(0)->isIdentityWithExtract());
2499   EXPECT_FALSE(CreateShuffleWithMask(0, 1)->isIdentityWithExtract());
2500   EXPECT_FALSE(CreateShuffleWithMask(0, 1, 2)->isIdentityWithExtract());
2501   EXPECT_FALSE(CreateShuffleWithMask(1)->isIdentityWithExtract());
2502 
2503   // isConcat
2504   EXPECT_TRUE(CreateShuffleWithMask(0, 1, 2, 3)->isConcat());
2505   EXPECT_FALSE(CreateShuffleWithMask(0, 3)->isConcat());
2506 
2507   // isSelect / isSelectMask
2508   {
2509     auto *I = CreateShuffleWithMask(0, 3);
2510     EXPECT_TRUE(I->isSelect());
2511     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSelectMask(
2512         I->getShuffleMaskForBitcode(), 2));
2513     EXPECT_TRUE(
2514         sandboxir::ShuffleVectorInst::isSelectMask(I->getShuffleMask(), 2));
2515   }
2516   {
2517     auto *I = CreateShuffleWithMask(0, 2);
2518     EXPECT_FALSE(I->isSelect());
2519     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSelectMask(
2520         I->getShuffleMaskForBitcode(), 2));
2521     EXPECT_FALSE(
2522         sandboxir::ShuffleVectorInst::isSelectMask(I->getShuffleMask(), 2));
2523   }
2524 
2525   // isReverse / isReverseMask
2526   {
2527     auto *I = CreateShuffleWithMask(1, 0);
2528     EXPECT_TRUE(I->isReverse());
2529     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isReverseMask(
2530         I->getShuffleMaskForBitcode(), 2));
2531     EXPECT_TRUE(
2532         sandboxir::ShuffleVectorInst::isReverseMask(I->getShuffleMask(), 2));
2533   }
2534   {
2535     auto *I = CreateShuffleWithMask(1, 2);
2536     EXPECT_FALSE(I->isReverse());
2537     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isReverseMask(
2538         I->getShuffleMaskForBitcode(), 2));
2539     EXPECT_FALSE(
2540         sandboxir::ShuffleVectorInst::isReverseMask(I->getShuffleMask(), 2));
2541   }
2542 
2543   // isZeroEltSplat / isZeroEltSplatMask
2544   {
2545     auto *I = CreateShuffleWithMask(0, 0);
2546     EXPECT_TRUE(I->isZeroEltSplat());
2547     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask(
2548         I->getShuffleMaskForBitcode(), 2));
2549     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask(
2550         I->getShuffleMask(), 2));
2551   }
2552   {
2553     auto *I = CreateShuffleWithMask(1, 1);
2554     EXPECT_FALSE(I->isZeroEltSplat());
2555     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask(
2556         I->getShuffleMaskForBitcode(), 2));
2557     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask(
2558         I->getShuffleMask(), 2));
2559   }
2560 
2561   // isTranspose / isTransposeMask
2562   {
2563     auto *I = CreateShuffleWithMask(0, 2);
2564     EXPECT_TRUE(I->isTranspose());
2565     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isTransposeMask(
2566         I->getShuffleMaskForBitcode(), 2));
2567     EXPECT_TRUE(
2568         sandboxir::ShuffleVectorInst::isTransposeMask(I->getShuffleMask(), 2));
2569   }
2570   {
2571     auto *I = CreateShuffleWithMask(1, 1);
2572     EXPECT_FALSE(I->isTranspose());
2573     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isTransposeMask(
2574         I->getShuffleMaskForBitcode(), 2));
2575     EXPECT_FALSE(
2576         sandboxir::ShuffleVectorInst::isTransposeMask(I->getShuffleMask(), 2));
2577   }
2578 
2579   // isSplice / isSpliceMask
2580   {
2581     auto *I = CreateShuffleWithMask(1, 2);
2582     int Index;
2583     EXPECT_TRUE(I->isSplice(Index));
2584     EXPECT_EQ(Index, 1);
2585     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSpliceMask(
2586         I->getShuffleMaskForBitcode(), 2, Index));
2587     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSpliceMask(I->getShuffleMask(),
2588                                                            2, Index));
2589   }
2590   {
2591     auto *I = CreateShuffleWithMask(2, 1);
2592     int Index;
2593     EXPECT_FALSE(I->isSplice(Index));
2594     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSpliceMask(
2595         I->getShuffleMaskForBitcode(), 2, Index));
2596     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSpliceMask(I->getShuffleMask(),
2597                                                             2, Index));
2598   }
2599 
2600   // isExtractSubvectorMask
2601   {
2602     auto *I = CreateShuffleWithMask(1);
2603     int Index;
2604     EXPECT_TRUE(I->isExtractSubvectorMask(Index));
2605     EXPECT_EQ(Index, 1);
2606     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask(
2607         I->getShuffleMaskForBitcode(), 2, Index));
2608     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask(
2609         I->getShuffleMask(), 2, Index));
2610   }
2611   {
2612     auto *I = CreateShuffleWithMask(1, 2);
2613     int Index;
2614     EXPECT_FALSE(I->isExtractSubvectorMask(Index));
2615     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask(
2616         I->getShuffleMaskForBitcode(), 2, Index));
2617     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask(
2618         I->getShuffleMask(), 2, Index));
2619   }
2620 
2621   // isInsertSubvectorMask
2622   {
2623     auto *I = CreateShuffleWithMask(0, 2);
2624     int NumSubElts, Index;
2625     EXPECT_TRUE(I->isInsertSubvectorMask(NumSubElts, Index));
2626     EXPECT_EQ(Index, 1);
2627     EXPECT_EQ(NumSubElts, 1);
2628     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask(
2629         I->getShuffleMaskForBitcode(), 2, NumSubElts, Index));
2630     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask(
2631         I->getShuffleMask(), 2, NumSubElts, Index));
2632   }
2633   {
2634     auto *I = CreateShuffleWithMask(0, 1);
2635     int NumSubElts, Index;
2636     EXPECT_FALSE(I->isInsertSubvectorMask(NumSubElts, Index));
2637     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask(
2638         I->getShuffleMaskForBitcode(), 2, NumSubElts, Index));
2639     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask(
2640         I->getShuffleMask(), 2, NumSubElts, Index));
2641   }
2642 
2643   // isReplicationMask
2644   {
2645     auto *I = CreateShuffleWithMask(0, 0, 0, 1, 1, 1);
2646     int ReplicationFactor, VF;
2647     EXPECT_TRUE(I->isReplicationMask(ReplicationFactor, VF));
2648     EXPECT_EQ(ReplicationFactor, 3);
2649     EXPECT_EQ(VF, 2);
2650     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isReplicationMask(
2651         I->getShuffleMaskForBitcode(), ReplicationFactor, VF));
2652     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isReplicationMask(
2653         I->getShuffleMask(), ReplicationFactor, VF));
2654   }
2655   {
2656     auto *I = CreateShuffleWithMask(1, 2);
2657     int ReplicationFactor, VF;
2658     EXPECT_FALSE(I->isReplicationMask(ReplicationFactor, VF));
2659     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isReplicationMask(
2660         I->getShuffleMaskForBitcode(), ReplicationFactor, VF));
2661     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isReplicationMask(
2662         I->getShuffleMask(), ReplicationFactor, VF));
2663   }
2664 
2665   // isOneUseSingleSourceMask
2666   {
2667     auto *I = CreateShuffleWithMask(0, 1, 1, 0);
2668     EXPECT_TRUE(I->isOneUseSingleSourceMask(2));
2669     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isOneUseSingleSourceMask(
2670         I->getShuffleMask(), 2));
2671   }
2672   {
2673     auto *I = CreateShuffleWithMask(0, 1, 0, 0);
2674     EXPECT_FALSE(I->isOneUseSingleSourceMask(2));
2675     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isOneUseSingleSourceMask(
2676         I->getShuffleMask(), 2));
2677   }
2678 
2679   // commuteShuffleMask
2680   {
2681     SmallVector<int, 4> M = {0, 2, 1, 3};
2682     ShuffleVectorInst::commuteShuffleMask(M, 2);
2683     EXPECT_THAT(M, testing::ElementsAre(2, 0, 3, 1));
2684   }
2685 
2686   // isInterleave / isInterleaveMask
2687   {
2688     auto *I = CreateShuffleWithMask(0, 2, 1, 3);
2689     EXPECT_TRUE(I->isInterleave(2));
2690     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInterleaveMask(
2691         I->getShuffleMask(), 2, 4));
2692     SmallVector<unsigned, 4> StartIndexes;
2693     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInterleaveMask(
2694         I->getShuffleMask(), 2, 4, StartIndexes));
2695     EXPECT_THAT(StartIndexes, testing::ElementsAre(0, 2));
2696   }
2697   {
2698     auto *I = CreateShuffleWithMask(0, 3, 1, 2);
2699     EXPECT_FALSE(I->isInterleave(2));
2700     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isInterleaveMask(
2701         I->getShuffleMask(), 2, 4));
2702   }
2703 
2704   // isDeInterleaveMaskOfFactor
2705   {
2706     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isDeInterleaveMaskOfFactor(
2707         ArrayRef<int>({0, 2}), 2));
2708     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isDeInterleaveMaskOfFactor(
2709         ArrayRef<int>({0, 1}), 2));
2710 
2711     unsigned Index;
2712     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isDeInterleaveMaskOfFactor(
2713         ArrayRef<int>({1, 3}), 2, Index));
2714     EXPECT_EQ(Index, 1u);
2715   }
2716 
2717   // isBitRotateMask
2718   {
2719     unsigned NumSubElts, RotateAmt;
2720     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isBitRotateMask(
2721         ArrayRef<int>({1, 0, 3, 2, 5, 4, 7, 6}), 8, 2, 2, NumSubElts,
2722         RotateAmt));
2723     EXPECT_EQ(NumSubElts, 2u);
2724     EXPECT_EQ(RotateAmt, 8u);
2725 
2726     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isBitRotateMask(
2727         ArrayRef<int>({0, 7, 1, 6, 2, 5, 3, 4}), 8, 2, 2, NumSubElts,
2728         RotateAmt));
2729   }
2730 }
2731 
2732 TEST_F(SandboxIRTest, ExtractValueInst) {
2733   parseIR(C, R"IR(
2734 define void @foo({i32, float} %agg) {
2735   %ext_simple = extractvalue {i32, float} %agg, 0
2736   %ext_nested = extractvalue {float, {i32}} undef, 1, 0
2737   %const1 = extractvalue {i32, float} {i32 0, float 99.0}, 0
2738   ret void
2739 }
2740 )IR");
2741   Function &LLVMF = *M->getFunction("foo");
2742   auto *LLVMBB = &*LLVMF.begin();
2743   auto LLVMIt = LLVMBB->begin();
2744   [[maybe_unused]] auto *LLVMExtSimple =
2745       cast<llvm::ExtractValueInst>(&*LLVMIt++);
2746   auto *LLVMExtNested = cast<llvm::ExtractValueInst>(&*LLVMIt++);
2747 
2748   sandboxir::Context Ctx(C);
2749   auto &F = *Ctx.createFunction(&LLVMF);
2750   auto *ArgAgg = F.getArg(0);
2751   auto *BB = &*F.begin();
2752   auto It = BB->begin();
2753   auto *ExtSimple = cast<sandboxir::ExtractValueInst>(&*It++);
2754   auto *ExtNested = cast<sandboxir::ExtractValueInst>(&*It++);
2755   auto *Const1 = cast<sandboxir::ExtractValueInst>(&*It++);
2756   auto *Ret = &*It++;
2757 
2758   EXPECT_EQ(ExtSimple->getOperand(0), ArgAgg);
2759 
2760   // create before instruction
2761   auto *NewExtBeforeRet =
2762       cast<sandboxir::ExtractValueInst>(sandboxir::ExtractValueInst::create(
2763           ArgAgg, ArrayRef<unsigned>({0}), Ret->getIterator(), Ret->getParent(),
2764           Ctx, "NewExtBeforeRet"));
2765   EXPECT_EQ(NewExtBeforeRet->getNextNode(), Ret);
2766 #ifndef NDEBUG
2767   EXPECT_EQ(NewExtBeforeRet->getName(), "NewExtBeforeRet");
2768 #endif // NDEBUG
2769 
2770   // create at end of BB
2771   auto *NewExtAtEnd =
2772       cast<sandboxir::ExtractValueInst>(sandboxir::ExtractValueInst::create(
2773           ArgAgg, ArrayRef<unsigned>({0}), BB->end(), BB, Ctx, "NewExtAtEnd"));
2774   EXPECT_EQ(NewExtAtEnd->getPrevNode(), Ret);
2775 #ifndef NDEBUG
2776   EXPECT_EQ(NewExtAtEnd->getName(), "NewExtAtEnd");
2777 #endif // NDEBUG
2778 
2779   // Test the path that creates a folded constant.
2780   auto *ShouldBeConstant = sandboxir::ExtractValueInst::create(
2781       Const1->getOperand(0), ArrayRef<unsigned>({0}), BB->end(), BB, Ctx);
2782   EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant));
2783 
2784   auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0);
2785   EXPECT_EQ(ShouldBeConstant, Zero);
2786 
2787   // getIndexedType
2788   sandboxir::Type *AggType = ExtNested->getAggregateOperand()->getType();
2789   llvm::Type *LLVMAggType = LLVMExtNested->getAggregateOperand()->getType();
2790   EXPECT_EQ(sandboxir::ExtractValueInst::getIndexedType(
2791                 AggType, ArrayRef<unsigned>({1, 0})),
2792             Ctx.getType(llvm::ExtractValueInst::getIndexedType(
2793                 LLVMAggType, ArrayRef<unsigned>({1, 0}))));
2794 
2795   EXPECT_EQ(sandboxir::ExtractValueInst::getIndexedType(
2796                 AggType, ArrayRef<unsigned>({2})),
2797             nullptr);
2798 
2799   // idx_begin / idx_end
2800   {
2801     SmallVector<int, 2> IndicesSimple(ExtSimple->idx_begin(),
2802                                       ExtSimple->idx_end());
2803     EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
2804 
2805     SmallVector<int, 2> IndicesNested(ExtNested->idx_begin(),
2806                                       ExtNested->idx_end());
2807     EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
2808   }
2809 
2810   // indices
2811   {
2812     SmallVector<int, 2> IndicesSimple(ExtSimple->indices());
2813     EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
2814 
2815     SmallVector<int, 2> IndicesNested(ExtNested->indices());
2816     EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
2817   }
2818 
2819   // getAggregateOperand
2820   EXPECT_EQ(ExtSimple->getAggregateOperand(), ArgAgg);
2821   const auto *ConstExtSimple = ExtSimple;
2822   EXPECT_EQ(ConstExtSimple->getAggregateOperand(), ArgAgg);
2823 
2824   // getAggregateOperandIndex
2825   EXPECT_EQ(sandboxir::ExtractValueInst::getAggregateOperandIndex(),
2826             llvm::ExtractValueInst::getAggregateOperandIndex());
2827 
2828   // getIndices
2829   EXPECT_EQ(ExtSimple->getIndices().size(), 1u);
2830   EXPECT_EQ(ExtSimple->getIndices()[0], 0u);
2831 
2832   // getNumIndices
2833   EXPECT_EQ(ExtSimple->getNumIndices(), 1u);
2834 
2835   // hasIndices
2836   EXPECT_EQ(ExtSimple->hasIndices(), true);
2837 }
2838 
2839 TEST_F(SandboxIRTest, InsertValueInst) {
2840   parseIR(C, R"IR(
2841 define void @foo({i32, float} %agg, i32 %i) {
2842   %ins_simple = insertvalue {i32, float} %agg, i32 %i, 0
2843   %ins_nested = insertvalue {float, {i32}} undef, i32 %i, 1, 0
2844   %const1 = insertvalue {i32, float} {i32 99, float 99.0}, i32 %i, 0
2845   %const2 = insertvalue {i32, float} {i32 0, float 99.0}, i32 %i, 0
2846   ret void
2847 }
2848 )IR");
2849   Function &LLVMF = *M->getFunction("foo");
2850   sandboxir::Context Ctx(C);
2851   auto &F = *Ctx.createFunction(&LLVMF);
2852   auto *ArgAgg = F.getArg(0);
2853   auto *ArgInt = F.getArg(1);
2854   auto *BB = &*F.begin();
2855   auto It = BB->begin();
2856   auto *InsSimple = cast<sandboxir::InsertValueInst>(&*It++);
2857   auto *InsNested = cast<sandboxir::InsertValueInst>(&*It++);
2858   // These "const" instructions are helpers to create constant struct operands.
2859   // TODO: Remove them once sandboxir::ConstantStruct gets added.
2860   auto *Const1 = cast<sandboxir::InsertValueInst>(&*It++);
2861   auto *Const2 = cast<sandboxir::InsertValueInst>(&*It++);
2862   auto *Ret = &*It++;
2863 
2864   EXPECT_EQ(InsSimple->getOperand(0), ArgAgg);
2865   EXPECT_EQ(InsSimple->getOperand(1), ArgInt);
2866 
2867   // create before instruction
2868   auto *NewInsBeforeRet =
2869       cast<sandboxir::InsertValueInst>(sandboxir::InsertValueInst::create(
2870           ArgAgg, ArgInt, ArrayRef<unsigned>({0}), Ret->getIterator(),
2871           Ret->getParent(), Ctx, "NewInsBeforeRet"));
2872   EXPECT_EQ(NewInsBeforeRet->getNextNode(), Ret);
2873 #ifndef NDEBUG
2874   EXPECT_EQ(NewInsBeforeRet->getName(), "NewInsBeforeRet");
2875 #endif // NDEBUG
2876 
2877   // create at end of BB
2878   auto *NewInsAtEnd =
2879       cast<sandboxir::InsertValueInst>(sandboxir::InsertValueInst::create(
2880           ArgAgg, ArgInt, ArrayRef<unsigned>({0}), BB->end(), BB, Ctx,
2881           "NewInsAtEnd"));
2882   EXPECT_EQ(NewInsAtEnd->getPrevNode(), Ret);
2883 #ifndef NDEBUG
2884   EXPECT_EQ(NewInsAtEnd->getName(), "NewInsAtEnd");
2885 #endif // NDEBUG
2886 
2887   // Test the path that creates a folded constant.
2888   auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0);
2889   auto *ShouldBeConstant = sandboxir::InsertValueInst::create(
2890       Const1->getOperand(0), Zero, ArrayRef<unsigned>({0}), BB->end(), BB, Ctx);
2891   auto *ExpectedConstant = Const2->getOperand(0);
2892   EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant));
2893   EXPECT_EQ(ShouldBeConstant, ExpectedConstant);
2894 
2895   // idx_begin / idx_end
2896   {
2897     SmallVector<int, 2> IndicesSimple(InsSimple->idx_begin(),
2898                                       InsSimple->idx_end());
2899     EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
2900 
2901     SmallVector<int, 2> IndicesNested(InsNested->idx_begin(),
2902                                       InsNested->idx_end());
2903     EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
2904   }
2905 
2906   // indices
2907   {
2908     SmallVector<int, 2> IndicesSimple(InsSimple->indices());
2909     EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
2910 
2911     SmallVector<int, 2> IndicesNested(InsNested->indices());
2912     EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
2913   }
2914 
2915   // getAggregateOperand
2916   EXPECT_EQ(InsSimple->getAggregateOperand(), ArgAgg);
2917   const auto *ConstInsSimple = InsSimple;
2918   EXPECT_EQ(ConstInsSimple->getAggregateOperand(), ArgAgg);
2919 
2920   // getAggregateOperandIndex
2921   EXPECT_EQ(sandboxir::InsertValueInst::getAggregateOperandIndex(),
2922             llvm::InsertValueInst::getAggregateOperandIndex());
2923 
2924   // getInsertedValueOperand
2925   EXPECT_EQ(InsSimple->getInsertedValueOperand(), ArgInt);
2926   EXPECT_EQ(ConstInsSimple->getInsertedValueOperand(), ArgInt);
2927 
2928   // getInsertedValueOperandIndex
2929   EXPECT_EQ(sandboxir::InsertValueInst::getInsertedValueOperandIndex(),
2930             llvm::InsertValueInst::getInsertedValueOperandIndex());
2931 
2932   // getIndices
2933   EXPECT_EQ(InsSimple->getIndices().size(), 1u);
2934   EXPECT_EQ(InsSimple->getIndices()[0], 0u);
2935 
2936   // getNumIndices
2937   EXPECT_EQ(InsSimple->getNumIndices(), 1u);
2938 
2939   // hasIndices
2940   EXPECT_EQ(InsSimple->hasIndices(), true);
2941 }
2942 
2943 TEST_F(SandboxIRTest, BranchInst) {
2944   parseIR(C, R"IR(
2945 define void @foo(i1 %cond0, i1 %cond2) {
2946  bb0:
2947    br i1 %cond0, label %bb1, label %bb2
2948  bb1:
2949    ret void
2950  bb2:
2951    ret void
2952 }
2953 )IR");
2954   llvm::Function *LLVMF = &*M->getFunction("foo");
2955   sandboxir::Context Ctx(C);
2956   sandboxir::Function *F = Ctx.createFunction(LLVMF);
2957   auto *Cond0 = F->getArg(0);
2958   auto *Cond1 = F->getArg(1);
2959   auto *BB0 = cast<sandboxir::BasicBlock>(
2960       Ctx.getValue(getBasicBlockByName(*LLVMF, "bb0")));
2961   auto *BB1 = cast<sandboxir::BasicBlock>(
2962       Ctx.getValue(getBasicBlockByName(*LLVMF, "bb1")));
2963   auto *Ret1 = BB1->getTerminator();
2964   auto *BB2 = cast<sandboxir::BasicBlock>(
2965       Ctx.getValue(getBasicBlockByName(*LLVMF, "bb2")));
2966   auto *Ret2 = BB2->getTerminator();
2967   auto It = BB0->begin();
2968   auto *Br0 = cast<sandboxir::BranchInst>(&*It++);
2969   // Check isUnconditional().
2970   EXPECT_FALSE(Br0->isUnconditional());
2971   // Check isConditional().
2972   EXPECT_TRUE(Br0->isConditional());
2973   // Check getCondition().
2974   EXPECT_EQ(Br0->getCondition(), Cond0);
2975   // Check setCondition().
2976   Br0->setCondition(Cond1);
2977   EXPECT_EQ(Br0->getCondition(), Cond1);
2978   // Check getNumSuccessors().
2979   EXPECT_EQ(Br0->getNumSuccessors(), 2u);
2980   // Check getSuccessor().
2981   EXPECT_EQ(Br0->getSuccessor(0), BB1);
2982   EXPECT_EQ(Br0->getSuccessor(1), BB2);
2983   // Check swapSuccessors().
2984   Br0->swapSuccessors();
2985   EXPECT_EQ(Br0->getSuccessor(0), BB2);
2986   EXPECT_EQ(Br0->getSuccessor(1), BB1);
2987   // Check successors().
2988   EXPECT_EQ(range_size(Br0->successors()), 2u);
2989   unsigned SuccIdx = 0;
2990   SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1, BB2});
2991   for (sandboxir::BasicBlock *Succ : Br0->successors())
2992     EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
2993 
2994   {
2995     // Check unconditional BranchInst::create() InsertBefore.
2996     auto *Br = sandboxir::BranchInst::create(BB1, /*InsertBefore=*/Ret1, Ctx);
2997     EXPECT_FALSE(Br->isConditional());
2998     EXPECT_TRUE(Br->isUnconditional());
2999 #ifndef NDEBUG
3000     EXPECT_DEATH(Br->getCondition(), ".*condition.*");
3001 #endif // NDEBUG
3002     unsigned SuccIdx = 0;
3003     SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1});
3004     for (sandboxir::BasicBlock *Succ : Br->successors())
3005       EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
3006     EXPECT_EQ(Br->getNextNode(), Ret1);
3007   }
3008   {
3009     // Check unconditional BranchInst::create() InsertAtEnd.
3010     auto *Br = sandboxir::BranchInst::create(BB1, /*InsertAtEnd=*/BB1, Ctx);
3011     EXPECT_FALSE(Br->isConditional());
3012     EXPECT_TRUE(Br->isUnconditional());
3013 #ifndef NDEBUG
3014     EXPECT_DEATH(Br->getCondition(), ".*condition.*");
3015 #endif // NDEBUG
3016     unsigned SuccIdx = 0;
3017     SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1});
3018     for (sandboxir::BasicBlock *Succ : Br->successors())
3019       EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
3020     EXPECT_EQ(Br->getPrevNode(), Ret1);
3021   }
3022   {
3023     // Check conditional BranchInst::create() InsertBefore.
3024     auto *Br = sandboxir::BranchInst::create(BB1, BB2, Cond0,
3025                                              /*InsertBefore=*/Ret1, Ctx);
3026     EXPECT_TRUE(Br->isConditional());
3027     EXPECT_EQ(Br->getCondition(), Cond0);
3028     unsigned SuccIdx = 0;
3029     SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB2, BB1});
3030     for (sandboxir::BasicBlock *Succ : Br->successors())
3031       EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
3032     EXPECT_EQ(Br->getNextNode(), Ret1);
3033   }
3034   {
3035     // Check conditional BranchInst::create() InsertAtEnd.
3036     auto *Br = sandboxir::BranchInst::create(BB1, BB2, Cond0,
3037                                              /*InsertAtEnd=*/BB2, Ctx);
3038     EXPECT_TRUE(Br->isConditional());
3039     EXPECT_EQ(Br->getCondition(), Cond0);
3040     unsigned SuccIdx = 0;
3041     SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB2, BB1});
3042     for (sandboxir::BasicBlock *Succ : Br->successors())
3043       EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
3044     EXPECT_EQ(Br->getPrevNode(), Ret2);
3045   }
3046 }
3047 
3048 TEST_F(SandboxIRTest, LoadInst) {
3049   parseIR(C, R"IR(
3050 define void @foo(ptr %arg0, ptr %arg1) {
3051   %ld = load i8, ptr %arg0, align 64
3052   %vld = load volatile i8, ptr %arg0, align 64
3053   ret void
3054 }
3055 )IR");
3056   llvm::Function *LLVMF = &*M->getFunction("foo");
3057   sandboxir::Context Ctx(C);
3058   sandboxir::Function *F = Ctx.createFunction(LLVMF);
3059   auto *Arg0 = F->getArg(0);
3060   auto *Arg1 = F->getArg(1);
3061   auto *BB = &*F->begin();
3062   auto It = BB->begin();
3063   auto *Ld = cast<sandboxir::LoadInst>(&*It++);
3064   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Ld));
3065   auto *VLd = cast<sandboxir::LoadInst>(&*It++);
3066   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
3067   bool OrigVolatileValue;
3068 
3069   // Check isVolatile()
3070   EXPECT_FALSE(Ld->isVolatile());
3071   // Check isVolatile()
3072   EXPECT_TRUE(VLd->isVolatile());
3073   // Check getPointerOperand()
3074   EXPECT_EQ(Ld->getPointerOperand(), Arg0);
3075   // Check getAlign()
3076   EXPECT_EQ(Ld->getAlign(), 64);
3077   // Check create(InsertBefore)
3078   sandboxir::LoadInst *NewLd =
3079       sandboxir::LoadInst::create(Ld->getType(), Arg1, Align(8),
3080                                   /*InsertBefore=*/Ret, Ctx, "NewLd");
3081   EXPECT_FALSE(NewLd->isVolatile());
3082   OrigVolatileValue = NewLd->isVolatile();
3083   NewLd->setVolatile(true);
3084   EXPECT_TRUE(NewLd->isVolatile());
3085   NewLd->setVolatile(OrigVolatileValue);
3086   EXPECT_FALSE(NewLd->isVolatile());
3087   EXPECT_EQ(NewLd->getType(), Ld->getType());
3088   EXPECT_EQ(NewLd->getPointerOperand(), Arg1);
3089   EXPECT_EQ(NewLd->getAlign(), 8);
3090   EXPECT_EQ(NewLd->getName(), "NewLd");
3091   // Check create(InsertBefore, IsVolatile=true)
3092   sandboxir::LoadInst *NewVLd =
3093       sandboxir::LoadInst::create(VLd->getType(), Arg1, Align(8),
3094                                   /*InsertBefore=*/Ret,
3095                                   /*IsVolatile=*/true, Ctx, "NewVLd");
3096 
3097   EXPECT_TRUE(NewVLd->isVolatile());
3098   OrigVolatileValue = NewVLd->isVolatile();
3099   NewVLd->setVolatile(false);
3100   EXPECT_FALSE(NewVLd->isVolatile());
3101   NewVLd->setVolatile(OrigVolatileValue);
3102   EXPECT_TRUE(NewVLd->isVolatile());
3103   EXPECT_EQ(NewVLd->getName(), "NewVLd");
3104   // Check create(InsertAtEnd)
3105   sandboxir::LoadInst *NewLdEnd =
3106       sandboxir::LoadInst::create(Ld->getType(), Arg1, Align(8),
3107                                   /*InsertAtEnd=*/BB, Ctx, "NewLdEnd");
3108   EXPECT_FALSE(NewLdEnd->isVolatile());
3109   EXPECT_EQ(NewLdEnd->getName(), "NewLdEnd");
3110   EXPECT_EQ(NewLdEnd->getType(), Ld->getType());
3111   EXPECT_EQ(NewLdEnd->getPointerOperand(), Arg1);
3112   EXPECT_EQ(NewLdEnd->getAlign(), 8);
3113   EXPECT_EQ(NewLdEnd->getParent(), BB);
3114   EXPECT_EQ(NewLdEnd->getNextNode(), nullptr);
3115   // Check create(InsertAtEnd, IsVolatile=true)
3116   sandboxir::LoadInst *NewVLdEnd =
3117       sandboxir::LoadInst::create(VLd->getType(), Arg1, Align(8),
3118                                   /*InsertAtEnd=*/BB,
3119                                   /*IsVolatile=*/true, Ctx, "NewVLdEnd");
3120   EXPECT_TRUE(NewVLdEnd->isVolatile());
3121   EXPECT_EQ(NewVLdEnd->getName(), "NewVLdEnd");
3122   EXPECT_EQ(NewVLdEnd->getType(), VLd->getType());
3123   EXPECT_EQ(NewVLdEnd->getPointerOperand(), Arg1);
3124   EXPECT_EQ(NewVLdEnd->getAlign(), 8);
3125   EXPECT_EQ(NewVLdEnd->getParent(), BB);
3126   EXPECT_EQ(NewVLdEnd->getNextNode(), nullptr);
3127 }
3128 
3129 TEST_F(SandboxIRTest, StoreInst) {
3130   parseIR(C, R"IR(
3131 define void @foo(i8 %val, ptr %ptr) {
3132   store i8 %val, ptr %ptr, align 64
3133   store volatile i8 %val, ptr %ptr, align 64
3134   ret void
3135 }
3136 )IR");
3137   llvm::Function *LLVMF = &*M->getFunction("foo");
3138   sandboxir::Context Ctx(C);
3139   sandboxir::Function *F = Ctx.createFunction(LLVMF);
3140   auto *Val = F->getArg(0);
3141   auto *Ptr = F->getArg(1);
3142   auto *BB = &*F->begin();
3143   auto It = BB->begin();
3144   auto *St = cast<sandboxir::StoreInst>(&*It++);
3145   auto *VSt = cast<sandboxir::StoreInst>(&*It++);
3146   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
3147   bool OrigVolatileValue;
3148 
3149   // Check that the StoreInst has been created correctly.
3150   EXPECT_FALSE(St->isVolatile());
3151   EXPECT_TRUE(VSt->isVolatile());
3152   // Check getPointerOperand()
3153   EXPECT_EQ(St->getValueOperand(), Val);
3154   EXPECT_EQ(St->getPointerOperand(), Ptr);
3155   // Check getAlign()
3156   EXPECT_EQ(St->getAlign(), 64);
3157   // Check create(InsertBefore)
3158   sandboxir::StoreInst *NewSt =
3159       sandboxir::StoreInst::create(Val, Ptr, Align(8),
3160                                    /*InsertBefore=*/Ret, Ctx);
3161   EXPECT_FALSE(NewSt->isVolatile());
3162   OrigVolatileValue = NewSt->isVolatile();
3163   NewSt->setVolatile(true);
3164   EXPECT_TRUE(NewSt->isVolatile());
3165   NewSt->setVolatile(OrigVolatileValue);
3166   EXPECT_FALSE(NewSt->isVolatile());
3167   EXPECT_EQ(NewSt->getType(), St->getType());
3168   EXPECT_EQ(NewSt->getValueOperand(), Val);
3169   EXPECT_EQ(NewSt->getPointerOperand(), Ptr);
3170   EXPECT_EQ(NewSt->getAlign(), 8);
3171   EXPECT_EQ(NewSt->getNextNode(), Ret);
3172   // Check create(InsertBefore, IsVolatile=true)
3173   sandboxir::StoreInst *NewVSt =
3174       sandboxir::StoreInst::create(Val, Ptr, Align(8),
3175                                    /*InsertBefore=*/Ret,
3176                                    /*IsVolatile=*/true, Ctx);
3177   EXPECT_TRUE(NewVSt->isVolatile());
3178   OrigVolatileValue = NewVSt->isVolatile();
3179   NewVSt->setVolatile(false);
3180   EXPECT_FALSE(NewVSt->isVolatile());
3181   NewVSt->setVolatile(OrigVolatileValue);
3182   EXPECT_TRUE(NewVSt->isVolatile());
3183   EXPECT_EQ(NewVSt->getType(), VSt->getType());
3184   EXPECT_EQ(NewVSt->getValueOperand(), Val);
3185   EXPECT_EQ(NewVSt->getPointerOperand(), Ptr);
3186   EXPECT_EQ(NewVSt->getAlign(), 8);
3187   EXPECT_EQ(NewVSt->getNextNode(), Ret);
3188   // Check create(InsertAtEnd)
3189   sandboxir::StoreInst *NewStEnd =
3190       sandboxir::StoreInst::create(Val, Ptr, Align(8),
3191                                    /*InsertAtEnd=*/BB, Ctx);
3192   EXPECT_FALSE(NewStEnd->isVolatile());
3193   EXPECT_EQ(NewStEnd->getType(), St->getType());
3194   EXPECT_EQ(NewStEnd->getValueOperand(), Val);
3195   EXPECT_EQ(NewStEnd->getPointerOperand(), Ptr);
3196   EXPECT_EQ(NewStEnd->getAlign(), 8);
3197   EXPECT_EQ(NewStEnd->getParent(), BB);
3198   EXPECT_EQ(NewStEnd->getNextNode(), nullptr);
3199   // Check create(InsertAtEnd, IsVolatile=true)
3200   sandboxir::StoreInst *NewVStEnd =
3201       sandboxir::StoreInst::create(Val, Ptr, Align(8),
3202                                    /*InsertAtEnd=*/BB,
3203                                    /*IsVolatile=*/true, Ctx);
3204   EXPECT_TRUE(NewVStEnd->isVolatile());
3205   EXPECT_EQ(NewVStEnd->getType(), VSt->getType());
3206   EXPECT_EQ(NewVStEnd->getValueOperand(), Val);
3207   EXPECT_EQ(NewVStEnd->getPointerOperand(), Ptr);
3208   EXPECT_EQ(NewVStEnd->getAlign(), 8);
3209   EXPECT_EQ(NewVStEnd->getParent(), BB);
3210   EXPECT_EQ(NewVStEnd->getNextNode(), nullptr);
3211 }
3212 
3213 TEST_F(SandboxIRTest, ReturnInst) {
3214   parseIR(C, R"IR(
3215 define i8 @foo(i8 %val) {
3216   %add = add i8 %val, 42
3217   ret i8 %val
3218 }
3219 )IR");
3220   llvm::Function *LLVMF = &*M->getFunction("foo");
3221   sandboxir::Context Ctx(C);
3222   sandboxir::Function *F = Ctx.createFunction(LLVMF);
3223   auto *Val = F->getArg(0);
3224   auto *BB = &*F->begin();
3225   auto It = BB->begin();
3226   It++;
3227   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
3228 
3229   // Check that the ReturnInst has been created correctly.
3230   // Check getReturnValue().
3231   EXPECT_EQ(Ret->getReturnValue(), Val);
3232 
3233   // Check create(InsertBefore) a void ReturnInst.
3234   auto *NewRet1 = cast<sandboxir::ReturnInst>(
3235       sandboxir::ReturnInst::create(nullptr, /*InsertBefore=*/Ret, Ctx));
3236   EXPECT_EQ(NewRet1->getReturnValue(), nullptr);
3237   // Check create(InsertBefore) a non-void ReturnInst.
3238   auto *NewRet2 = cast<sandboxir::ReturnInst>(
3239       sandboxir::ReturnInst::create(Val, /*InsertBefore=*/Ret, Ctx));
3240   EXPECT_EQ(NewRet2->getReturnValue(), Val);
3241 
3242   // Check create(InsertAtEnd) a void ReturnInst.
3243   auto *NewRet3 = cast<sandboxir::ReturnInst>(
3244       sandboxir::ReturnInst::create(nullptr, /*InsertAtEnd=*/BB, Ctx));
3245   EXPECT_EQ(NewRet3->getReturnValue(), nullptr);
3246   // Check create(InsertAtEnd) a non-void ReturnInst.
3247   auto *NewRet4 = cast<sandboxir::ReturnInst>(
3248       sandboxir::ReturnInst::create(Val, /*InsertAtEnd=*/BB, Ctx));
3249   EXPECT_EQ(NewRet4->getReturnValue(), Val);
3250 }
3251 
3252 TEST_F(SandboxIRTest, CallBase) {
3253   parseIR(C, R"IR(
3254 declare void @bar1(i8)
3255 declare void @bar2()
3256 declare void @bar3()
3257 declare void @variadic(ptr, ...)
3258 
3259 define i8 @foo(i8 %arg0, i32 %arg1, ptr %indirectFoo) {
3260   %call = call i8 @foo(i8 %arg0, i32 %arg1)
3261   call void @bar1(i8 %arg0)
3262   call void @bar2()
3263   call void %indirectFoo()
3264   call void @bar2() noreturn
3265   tail call fastcc void @bar2()
3266   call void (ptr, ...) @variadic(ptr %indirectFoo, i32 1)
3267   ret i8 %call
3268 }
3269 )IR");
3270   llvm::Function &LLVMF = *M->getFunction("foo");
3271   unsigned ArgIdx = 0;
3272   llvm::Argument *LLVMArg0 = LLVMF.getArg(ArgIdx++);
3273   llvm::Argument *LLVMArg1 = LLVMF.getArg(ArgIdx++);
3274   llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
3275   SmallVector<llvm::CallBase *, 8> LLVMCalls;
3276   auto LLVMIt = LLVMBB->begin();
3277   while (isa<llvm::CallBase>(&*LLVMIt))
3278     LLVMCalls.push_back(cast<llvm::CallBase>(&*LLVMIt++));
3279 
3280   sandboxir::Context Ctx(C);
3281   sandboxir::Function &F = *Ctx.createFunction(&LLVMF);
3282 
3283   for (llvm::CallBase *LLVMCall : LLVMCalls) {
3284     // Check classof(Instruction *).
3285     auto *Call = cast<sandboxir::CallBase>(Ctx.getValue(LLVMCall));
3286     // Check classof(Value *).
3287     EXPECT_TRUE(isa<sandboxir::CallBase>((sandboxir::Value *)Call));
3288     // Check getFunctionType().
3289     EXPECT_EQ(Call->getFunctionType(),
3290               Ctx.getType(LLVMCall->getFunctionType()));
3291     // Check data_ops().
3292     EXPECT_EQ(range_size(Call->data_ops()), range_size(LLVMCall->data_ops()));
3293     auto DataOpIt = Call->data_operands_begin();
3294     for (llvm::Use &LLVMUse : LLVMCall->data_ops()) {
3295       Value *LLVMOp = LLVMUse.get();
3296       sandboxir::Use Use = *DataOpIt++;
3297       EXPECT_EQ(Ctx.getValue(LLVMOp), Use.get());
3298       // Check isDataOperand().
3299       EXPECT_EQ(Call->isDataOperand(Use), LLVMCall->isDataOperand(&LLVMUse));
3300       // Check getDataOperandNo().
3301       EXPECT_EQ(Call->getDataOperandNo(Use),
3302                 LLVMCall->getDataOperandNo(&LLVMUse));
3303       // Check isArgOperand().
3304       EXPECT_EQ(Call->isArgOperand(Use), LLVMCall->isArgOperand(&LLVMUse));
3305       // Check isCallee().
3306       EXPECT_EQ(Call->isCallee(Use), LLVMCall->isCallee(&LLVMUse));
3307     }
3308     // Check data_operands_empty().
3309     EXPECT_EQ(Call->data_operands_empty(), LLVMCall->data_operands_empty());
3310     // Check data_operands_size().
3311     EXPECT_EQ(Call->data_operands_size(), LLVMCall->data_operands_size());
3312     // Check getNumTotalBundleOperands().
3313     EXPECT_EQ(Call->getNumTotalBundleOperands(),
3314               LLVMCall->getNumTotalBundleOperands());
3315     // Check args().
3316     EXPECT_EQ(range_size(Call->args()), range_size(LLVMCall->args()));
3317     auto ArgIt = Call->arg_begin();
3318     for (llvm::Use &LLVMUse : LLVMCall->args()) {
3319       Value *LLVMArg = LLVMUse.get();
3320       sandboxir::Use Use = *ArgIt++;
3321       EXPECT_EQ(Ctx.getValue(LLVMArg), Use.get());
3322     }
3323     // Check arg_empty().
3324     EXPECT_EQ(Call->arg_empty(), LLVMCall->arg_empty());
3325     // Check arg_size().
3326     EXPECT_EQ(Call->arg_size(), LLVMCall->arg_size());
3327     for (unsigned ArgIdx = 0, E = Call->arg_size(); ArgIdx != E; ++ArgIdx) {
3328       // Check getArgOperand().
3329       EXPECT_EQ(Call->getArgOperand(ArgIdx),
3330                 Ctx.getValue(LLVMCall->getArgOperand(ArgIdx)));
3331       // Check getArgOperandUse().
3332       sandboxir::Use Use = Call->getArgOperandUse(ArgIdx);
3333       llvm::Use &LLVMUse = LLVMCall->getArgOperandUse(ArgIdx);
3334       EXPECT_EQ(Use.get(), Ctx.getValue(LLVMUse.get()));
3335       // Check getArgOperandNo().
3336       EXPECT_EQ(Call->getArgOperandNo(Use),
3337                 LLVMCall->getArgOperandNo(&LLVMUse));
3338     }
3339     // Check hasArgument().
3340     SmallVector<llvm::Value *> TestArgs(
3341         {LLVMArg0, LLVMArg1, &LLVMF, LLVMBB, LLVMCall});
3342     for (llvm::Value *LLVMV : TestArgs) {
3343       sandboxir::Value *V = Ctx.getValue(LLVMV);
3344       EXPECT_EQ(Call->hasArgument(V), LLVMCall->hasArgument(LLVMV));
3345     }
3346     // Check getCalledOperand().
3347     EXPECT_EQ(Call->getCalledOperand(),
3348               Ctx.getValue(LLVMCall->getCalledOperand()));
3349     // Check getCalledOperandUse().
3350     EXPECT_EQ(Call->getCalledOperandUse().get(),
3351               Ctx.getValue(LLVMCall->getCalledOperandUse()));
3352     // Check getCalledFunction().
3353     if (LLVMCall->getCalledFunction() == nullptr)
3354       EXPECT_EQ(Call->getCalledFunction(), nullptr);
3355     else {
3356       auto *LLVMCF = cast<llvm::Function>(LLVMCall->getCalledFunction());
3357       (void)LLVMCF;
3358       EXPECT_EQ(Call->getCalledFunction(),
3359                 cast<sandboxir::Function>(
3360                     Ctx.getValue(LLVMCall->getCalledFunction())));
3361     }
3362     // Check isIndirectCall().
3363     EXPECT_EQ(Call->isIndirectCall(), LLVMCall->isIndirectCall());
3364     // Check getCaller().
3365     EXPECT_EQ(Call->getCaller(), Ctx.getValue(LLVMCall->getCaller()));
3366     // Check isMustTailCall().
3367     EXPECT_EQ(Call->isMustTailCall(), LLVMCall->isMustTailCall());
3368     // Check isTailCall().
3369     EXPECT_EQ(Call->isTailCall(), LLVMCall->isTailCall());
3370     // Check getIntrinsicID().
3371     EXPECT_EQ(Call->getIntrinsicID(), LLVMCall->getIntrinsicID());
3372     // Check getCallingConv().
3373     EXPECT_EQ(Call->getCallingConv(), LLVMCall->getCallingConv());
3374     // Check isInlineAsm().
3375     EXPECT_EQ(Call->isInlineAsm(), LLVMCall->isInlineAsm());
3376   }
3377 
3378   auto *Arg0 = F.getArg(0);
3379   auto *Arg1 = F.getArg(1);
3380   auto *BB = &*F.begin();
3381   auto It = BB->begin();
3382   auto *Call0 = cast<sandboxir::CallBase>(&*It++);
3383   [[maybe_unused]] auto *Call1 = cast<sandboxir::CallBase>(&*It++);
3384   auto *Call2 = cast<sandboxir::CallBase>(&*It++);
3385   // Check setArgOperand
3386   Call0->setArgOperand(0, Arg1);
3387   EXPECT_EQ(Call0->getArgOperand(0), Arg1);
3388   Call0->setArgOperand(0, Arg0);
3389   EXPECT_EQ(Call0->getArgOperand(0), Arg0);
3390 
3391   auto *Bar3F = Ctx.createFunction(M->getFunction("bar3"));
3392 
3393   // Check setCalledOperand
3394   auto *SvOp = Call0->getCalledOperand();
3395   Call0->setCalledOperand(Bar3F);
3396   EXPECT_EQ(Call0->getCalledOperand(), Bar3F);
3397   Call0->setCalledOperand(SvOp);
3398   // Check setCalledFunction
3399   Call2->setCalledFunction(Bar3F);
3400   EXPECT_EQ(Call2->getCalledFunction(), Bar3F);
3401 }
3402 
3403 TEST_F(SandboxIRTest, CallInst) {
3404   parseIR(C, R"IR(
3405 define i8 @foo(i8 %arg) {
3406   %call = call i8 @foo(i8 %arg)
3407   ret i8 %call
3408 }
3409 )IR");
3410   Function &LLVMF = *M->getFunction("foo");
3411   sandboxir::Context Ctx(C);
3412   auto &F = *Ctx.createFunction(&LLVMF);
3413   unsigned ArgIdx = 0;
3414   auto *Arg0 = F.getArg(ArgIdx++);
3415   auto *BB = &*F.begin();
3416   auto It = BB->begin();
3417   auto *Call = cast<sandboxir::CallInst>(&*It++);
3418   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
3419   EXPECT_EQ(Call->getNumOperands(), 2u);
3420   EXPECT_EQ(Ret->getOpcode(), sandboxir::Instruction::Opcode::Ret);
3421   sandboxir::FunctionType *FTy = F.getFunctionType();
3422   SmallVector<sandboxir::Value *, 1> Args;
3423   Args.push_back(Arg0);
3424   {
3425     // Check create() WhereIt.
3426     auto *Call = cast<sandboxir::CallInst>(sandboxir::CallInst::create(
3427         FTy, &F, Args, /*WhereIt=*/Ret->getIterator(), BB, Ctx));
3428     EXPECT_EQ(Call->getNextNode(), Ret);
3429     EXPECT_EQ(Call->getCalledFunction(), &F);
3430     EXPECT_EQ(range_size(Call->args()), 1u);
3431     EXPECT_EQ(Call->getArgOperand(0), Arg0);
3432   }
3433   {
3434     // Check create() InsertBefore.
3435     auto *Call = cast<sandboxir::CallInst>(
3436         sandboxir::CallInst::create(FTy, &F, Args, /*InsertBefore=*/Ret, Ctx));
3437     EXPECT_EQ(Call->getNextNode(), Ret);
3438     EXPECT_EQ(Call->getCalledFunction(), &F);
3439     EXPECT_EQ(range_size(Call->args()), 1u);
3440     EXPECT_EQ(Call->getArgOperand(0), Arg0);
3441   }
3442   {
3443     // Check create() InsertAtEnd.
3444     auto *Call = cast<sandboxir::CallInst>(
3445         sandboxir::CallInst::create(FTy, &F, Args, /*InsertAtEnd=*/BB, Ctx));
3446     EXPECT_EQ(Call->getPrevNode(), Ret);
3447     EXPECT_EQ(Call->getCalledFunction(), &F);
3448     EXPECT_EQ(range_size(Call->args()), 1u);
3449     EXPECT_EQ(Call->getArgOperand(0), Arg0);
3450   }
3451 }
3452 
3453 TEST_F(SandboxIRTest, InvokeInst) {
3454   parseIR(C, R"IR(
3455 define void @foo(i8 %arg) {
3456  bb0:
3457    invoke i8 @foo(i8 %arg) to label %normal_bb
3458                        unwind label %exception_bb
3459  normal_bb:
3460    ret void
3461  exception_bb:
3462    %lpad = landingpad { ptr, i32}
3463            cleanup
3464    ret void
3465  other_bb:
3466    ret void
3467 }
3468 )IR");
3469   Function &LLVMF = *M->getFunction("foo");
3470   sandboxir::Context Ctx(C);
3471   auto &F = *Ctx.createFunction(&LLVMF);
3472   auto *Arg = F.getArg(0);
3473   auto *BB0 = cast<sandboxir::BasicBlock>(
3474       Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
3475   auto *NormalBB = cast<sandboxir::BasicBlock>(
3476       Ctx.getValue(getBasicBlockByName(LLVMF, "normal_bb")));
3477   auto *ExceptionBB = cast<sandboxir::BasicBlock>(
3478       Ctx.getValue(getBasicBlockByName(LLVMF, "exception_bb")));
3479   auto *LandingPad = &*ExceptionBB->begin();
3480   auto *OtherBB = cast<sandboxir::BasicBlock>(
3481       Ctx.getValue(getBasicBlockByName(LLVMF, "other_bb")));
3482   auto It = BB0->begin();
3483   // Check classof(Instruction *).
3484   auto *Invoke = cast<sandboxir::InvokeInst>(&*It++);
3485 
3486   // Check getNormalDest().
3487   EXPECT_EQ(Invoke->getNormalDest(), NormalBB);
3488   // Check getUnwindDest().
3489   EXPECT_EQ(Invoke->getUnwindDest(), ExceptionBB);
3490   // Check getSuccessor().
3491   EXPECT_EQ(Invoke->getSuccessor(0), NormalBB);
3492   EXPECT_EQ(Invoke->getSuccessor(1), ExceptionBB);
3493   // Check setNormalDest().
3494   Invoke->setNormalDest(OtherBB);
3495   EXPECT_EQ(Invoke->getNormalDest(), OtherBB);
3496   EXPECT_EQ(Invoke->getUnwindDest(), ExceptionBB);
3497   // Check setUnwindDest().
3498   Invoke->setUnwindDest(OtherBB);
3499   EXPECT_EQ(Invoke->getNormalDest(), OtherBB);
3500   EXPECT_EQ(Invoke->getUnwindDest(), OtherBB);
3501   // Check setSuccessor().
3502   Invoke->setSuccessor(0, NormalBB);
3503   EXPECT_EQ(Invoke->getNormalDest(), NormalBB);
3504   Invoke->setSuccessor(1, ExceptionBB);
3505   EXPECT_EQ(Invoke->getUnwindDest(), ExceptionBB);
3506   // Check getLandingPadInst().
3507   EXPECT_EQ(Invoke->getLandingPadInst(), LandingPad);
3508 
3509   {
3510     // Check create() WhereIt, WhereBB.
3511     SmallVector<sandboxir::Value *> Args({Arg});
3512     auto *InsertBefore = &*BB0->begin();
3513     auto *NewInvoke = cast<sandboxir::InvokeInst>(sandboxir::InvokeInst::create(
3514         F.getFunctionType(), &F, NormalBB, ExceptionBB, Args,
3515         /*WhereIt=*/InsertBefore->getIterator(), /*WhereBB=*/BB0, Ctx));
3516     EXPECT_EQ(NewInvoke->getNormalDest(), NormalBB);
3517     EXPECT_EQ(NewInvoke->getUnwindDest(), ExceptionBB);
3518     EXPECT_EQ(NewInvoke->getNextNode(), InsertBefore);
3519   }
3520   {
3521     // Check create() InsertBefore.
3522     SmallVector<sandboxir::Value *> Args({Arg});
3523     auto *InsertBefore = &*BB0->begin();
3524     auto *NewInvoke = cast<sandboxir::InvokeInst>(
3525         sandboxir::InvokeInst::create(F.getFunctionType(), &F, NormalBB,
3526                                       ExceptionBB, Args, InsertBefore, Ctx));
3527     EXPECT_EQ(NewInvoke->getNormalDest(), NormalBB);
3528     EXPECT_EQ(NewInvoke->getUnwindDest(), ExceptionBB);
3529     EXPECT_EQ(NewInvoke->getNextNode(), InsertBefore);
3530   }
3531   {
3532     // Check create() InsertAtEnd.
3533     SmallVector<sandboxir::Value *> Args({Arg});
3534     auto *NewInvoke = cast<sandboxir::InvokeInst>(sandboxir::InvokeInst::create(
3535         F.getFunctionType(), &F, NormalBB, ExceptionBB, Args,
3536         /*InsertAtEnd=*/BB0, Ctx));
3537     EXPECT_EQ(NewInvoke->getNormalDest(), NormalBB);
3538     EXPECT_EQ(NewInvoke->getUnwindDest(), ExceptionBB);
3539     EXPECT_EQ(NewInvoke->getParent(), BB0);
3540     EXPECT_EQ(NewInvoke->getNextNode(), nullptr);
3541   }
3542 }
3543 
3544 TEST_F(SandboxIRTest, CallBrInst) {
3545   parseIR(C, R"IR(
3546 define void @foo(i8 %arg) {
3547  bb0:
3548    callbr void asm "", ""()
3549                to label %bb1 [label %bb2]
3550  bb1:
3551    ret void
3552  bb2:
3553    ret void
3554  other_bb:
3555    ret void
3556  bb3:
3557    callbr void @foo(i8 %arg)
3558                to label %bb1 [label %bb2]
3559 }
3560 )IR");
3561   Function &LLVMF = *M->getFunction("foo");
3562   auto *LLVMBB0 = getBasicBlockByName(LLVMF, "bb0");
3563   auto *LLVMCallBr = cast<llvm::CallBrInst>(&*LLVMBB0->begin());
3564   sandboxir::Context Ctx(C);
3565   auto &F = *Ctx.createFunction(&LLVMF);
3566   auto *Arg = F.getArg(0);
3567   auto *BB0 = cast<sandboxir::BasicBlock>(
3568       Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
3569   auto *BB1 = cast<sandboxir::BasicBlock>(
3570       Ctx.getValue(getBasicBlockByName(LLVMF, "bb1")));
3571   auto *BB2 = cast<sandboxir::BasicBlock>(
3572       Ctx.getValue(getBasicBlockByName(LLVMF, "bb2")));
3573   auto *BB3 = cast<sandboxir::BasicBlock>(
3574       Ctx.getValue(getBasicBlockByName(LLVMF, "bb3")));
3575   auto *OtherBB = cast<sandboxir::BasicBlock>(
3576       Ctx.getValue(getBasicBlockByName(LLVMF, "other_bb")));
3577   auto It = BB0->begin();
3578   // Check classof(Instruction *).
3579   auto *CallBr0 = cast<sandboxir::CallBrInst>(&*It++);
3580 
3581   It = BB3->begin();
3582   auto *CallBr1 = cast<sandboxir::CallBrInst>(&*It++);
3583   for (sandboxir::CallBrInst *CallBr : {CallBr0, CallBr1}) {
3584     // Check getNumIndirectDests().
3585     EXPECT_EQ(CallBr->getNumIndirectDests(), 1u);
3586     // Check getIndirectDestLabel().
3587     EXPECT_EQ(CallBr->getIndirectDestLabel(0),
3588               Ctx.getValue(LLVMCallBr->getIndirectDestLabel(0)));
3589     // Check getIndirectDestLabelUse().
3590     EXPECT_EQ(CallBr->getIndirectDestLabelUse(0),
3591               Ctx.getValue(LLVMCallBr->getIndirectDestLabelUse(0)));
3592     // Check getDefaultDest().
3593     EXPECT_EQ(CallBr->getDefaultDest(),
3594               Ctx.getValue(LLVMCallBr->getDefaultDest()));
3595     // Check getIndirectDest().
3596     EXPECT_EQ(CallBr->getIndirectDest(0),
3597               Ctx.getValue(LLVMCallBr->getIndirectDest(0)));
3598     // Check getIndirectDests().
3599     auto Dests = CallBr->getIndirectDests();
3600     EXPECT_EQ(Dests.size(), LLVMCallBr->getIndirectDests().size());
3601     EXPECT_EQ(Dests[0], Ctx.getValue(LLVMCallBr->getIndirectDests()[0]));
3602     // Check getNumSuccessors().
3603     EXPECT_EQ(CallBr->getNumSuccessors(), LLVMCallBr->getNumSuccessors());
3604     // Check getSuccessor().
3605     for (unsigned SuccIdx = 0, E = CallBr->getNumSuccessors(); SuccIdx != E;
3606          ++SuccIdx)
3607       EXPECT_EQ(CallBr->getSuccessor(SuccIdx),
3608                 Ctx.getValue(LLVMCallBr->getSuccessor(SuccIdx)));
3609     // Check setDefaultDest().
3610     auto *SvDefaultDest = CallBr->getDefaultDest();
3611     CallBr->setDefaultDest(OtherBB);
3612     EXPECT_EQ(CallBr->getDefaultDest(), OtherBB);
3613     CallBr->setDefaultDest(SvDefaultDest);
3614     // Check setIndirectDest().
3615     auto *SvIndirectDest = CallBr->getIndirectDest(0);
3616     CallBr->setIndirectDest(0, OtherBB);
3617     EXPECT_EQ(CallBr->getIndirectDest(0), OtherBB);
3618     CallBr->setIndirectDest(0, SvIndirectDest);
3619   }
3620 
3621   {
3622     // Check create() WhereIt, WhereBB.
3623     SmallVector<sandboxir::Value *> Args({Arg});
3624     auto *NewCallBr = cast<sandboxir::CallBrInst>(sandboxir::CallBrInst::create(
3625         F.getFunctionType(), &F, BB1, {BB2}, Args, /*WhereIt=*/BB0->end(),
3626         /*WhereBB=*/BB0, Ctx));
3627     EXPECT_EQ(NewCallBr->getDefaultDest(), BB1);
3628     EXPECT_EQ(NewCallBr->getIndirectDests().size(), 1u);
3629     EXPECT_EQ(NewCallBr->getIndirectDests()[0], BB2);
3630     EXPECT_EQ(NewCallBr->getNextNode(), nullptr);
3631     EXPECT_EQ(NewCallBr->getParent(), BB0);
3632   }
3633   {
3634     // Check create() InsertBefore
3635     SmallVector<sandboxir::Value *> Args({Arg});
3636     auto *InsertBefore = &*BB0->rbegin();
3637     auto *NewCallBr = cast<sandboxir::CallBrInst>(sandboxir::CallBrInst::create(
3638         F.getFunctionType(), &F, BB1, {BB2}, Args, InsertBefore, Ctx));
3639     EXPECT_EQ(NewCallBr->getDefaultDest(), BB1);
3640     EXPECT_EQ(NewCallBr->getIndirectDests().size(), 1u);
3641     EXPECT_EQ(NewCallBr->getIndirectDests()[0], BB2);
3642     EXPECT_EQ(NewCallBr->getNextNode(), InsertBefore);
3643   }
3644   {
3645     // Check create() InsertAtEnd.
3646     SmallVector<sandboxir::Value *> Args({Arg});
3647     auto *NewCallBr = cast<sandboxir::CallBrInst>(
3648         sandboxir::CallBrInst::create(F.getFunctionType(), &F, BB1, {BB2}, Args,
3649                                       /*InsertAtEnd=*/BB0, Ctx));
3650     EXPECT_EQ(NewCallBr->getDefaultDest(), BB1);
3651     EXPECT_EQ(NewCallBr->getIndirectDests().size(), 1u);
3652     EXPECT_EQ(NewCallBr->getIndirectDests()[0], BB2);
3653     EXPECT_EQ(NewCallBr->getNextNode(), nullptr);
3654     EXPECT_EQ(NewCallBr->getParent(), BB0);
3655   }
3656 }
3657 
3658 TEST_F(SandboxIRTest, LandingPadInst) {
3659   parseIR(C, R"IR(
3660 define void @foo() {
3661 entry:
3662   invoke void @foo()
3663       to label %bb unwind label %unwind
3664 unwind:
3665   %lpad = landingpad { ptr, i32 }
3666             catch ptr null
3667   ret void
3668 bb:
3669   ret void
3670 }
3671 )IR");
3672   Function &LLVMF = *M->getFunction("foo");
3673   auto *LLVMUnwind = getBasicBlockByName(LLVMF, "unwind");
3674   auto *LLVMLPad = cast<llvm::LandingPadInst>(&*LLVMUnwind->begin());
3675 
3676   sandboxir::Context Ctx(C);
3677   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
3678   auto *Unwind = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMUnwind));
3679   auto *BB = cast<sandboxir::BasicBlock>(
3680       Ctx.getValue(getBasicBlockByName(LLVMF, "bb")));
3681   auto It = Unwind->begin();
3682   auto *LPad = cast<sandboxir::LandingPadInst>(&*It++);
3683   [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
3684 
3685   // Check isCleanup().
3686   EXPECT_EQ(LPad->isCleanup(), LLVMLPad->isCleanup());
3687   // Check setCleanup().
3688   auto OrigIsCleanup = LPad->isCleanup();
3689   auto NewIsCleanup = true;
3690   EXPECT_NE(NewIsCleanup, OrigIsCleanup);
3691   LPad->setCleanup(NewIsCleanup);
3692   EXPECT_EQ(LPad->isCleanup(), NewIsCleanup);
3693   LPad->setCleanup(OrigIsCleanup);
3694   EXPECT_EQ(LPad->isCleanup(), OrigIsCleanup);
3695   // Check getNumClauses().
3696   EXPECT_EQ(LPad->getNumClauses(), LLVMLPad->getNumClauses());
3697   // Check getClause().
3698   for (auto Idx : seq<unsigned>(0, LPad->getNumClauses()))
3699     EXPECT_EQ(LPad->getClause(Idx), Ctx.getValue(LLVMLPad->getClause(Idx)));
3700   // Check isCatch().
3701   for (auto Idx : seq<unsigned>(0, LPad->getNumClauses()))
3702     EXPECT_EQ(LPad->isCatch(Idx), LLVMLPad->isCatch(Idx));
3703   // Check isFilter().
3704   for (auto Idx : seq<unsigned>(0, LPad->getNumClauses()))
3705     EXPECT_EQ(LPad->isFilter(Idx), LLVMLPad->isFilter(Idx));
3706   // Check create().
3707   auto *BBRet = &*BB->begin();
3708   auto *NewLPad =
3709       cast<sandboxir::LandingPadInst>(sandboxir::LandingPadInst::create(
3710           sandboxir::Type::getInt8Ty(Ctx), 0, BBRet->getIterator(),
3711           BBRet->getParent(), Ctx, "NewLPad"));
3712   EXPECT_EQ(NewLPad->getNextNode(), BBRet);
3713   EXPECT_FALSE(NewLPad->isCleanup());
3714 #ifndef NDEBUG
3715   EXPECT_EQ(NewLPad->getName(), "NewLPad");
3716 #endif // NDEBUG
3717 }
3718 
3719 TEST_F(SandboxIRTest, FuncletPadInst_CatchPadInst_CleanupPadInst) {
3720   parseIR(C, R"IR(
3721 define void @foo() {
3722 dispatch:
3723   %cs = catchswitch within none [label %handler0] unwind to caller
3724 handler0:
3725   %catchpad = catchpad within %cs [ptr @foo]
3726   ret void
3727 handler1:
3728   %cleanuppad = cleanuppad within %cs [ptr @foo]
3729   ret void
3730 bb:
3731   ret void
3732 }
3733 )IR");
3734   Function &LLVMF = *M->getFunction("foo");
3735   BasicBlock *LLVMDispatch = getBasicBlockByName(LLVMF, "dispatch");
3736   BasicBlock *LLVMHandler0 = getBasicBlockByName(LLVMF, "handler0");
3737   BasicBlock *LLVMHandler1 = getBasicBlockByName(LLVMF, "handler1");
3738   auto *LLVMCP = cast<llvm::CatchPadInst>(&*LLVMHandler0->begin());
3739   auto *LLVMCLP = cast<llvm::CleanupPadInst>(&*LLVMHandler1->begin());
3740 
3741   sandboxir::Context Ctx(C);
3742   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
3743   auto *Dispatch = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMDispatch));
3744   auto *Handler0 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler0));
3745   auto *Handler1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler1));
3746   auto *BB = cast<sandboxir::BasicBlock>(
3747       Ctx.getValue(getBasicBlockByName(LLVMF, "bb")));
3748   auto *BBRet = cast<sandboxir::ReturnInst>(&*BB->begin());
3749   auto *CS = cast<sandboxir::CatchSwitchInst>(&*Dispatch->begin());
3750   [[maybe_unused]] auto *CP =
3751       cast<sandboxir::CatchPadInst>(&*Handler0->begin());
3752   [[maybe_unused]] auto *CLP =
3753       cast<sandboxir::CleanupPadInst>(&*Handler1->begin());
3754 
3755   // Check getCatchSwitch().
3756   EXPECT_EQ(CP->getCatchSwitch(), CS);
3757   EXPECT_EQ(CP->getCatchSwitch(), Ctx.getValue(LLVMCP->getCatchSwitch()));
3758 
3759   for (llvm::FuncletPadInst *LLVMFPI :
3760        {static_cast<llvm::FuncletPadInst *>(LLVMCP),
3761         static_cast<llvm::FuncletPadInst *>(LLVMCLP)}) {
3762     auto *FPI = cast<sandboxir::FuncletPadInst>(Ctx.getValue(LLVMFPI));
3763     // Check arg_size().
3764     EXPECT_EQ(FPI->arg_size(), LLVMFPI->arg_size());
3765     // Check getParentPad().
3766     EXPECT_EQ(FPI->getParentPad(), Ctx.getValue(LLVMFPI->getParentPad()));
3767     // Check setParentPad().
3768     auto *OrigParentPad = FPI->getParentPad();
3769     auto *NewParentPad = Dispatch;
3770     EXPECT_NE(NewParentPad, OrigParentPad);
3771     FPI->setParentPad(NewParentPad);
3772     EXPECT_EQ(FPI->getParentPad(), NewParentPad);
3773     FPI->setParentPad(OrigParentPad);
3774     EXPECT_EQ(FPI->getParentPad(), OrigParentPad);
3775     // Check getArgOperand().
3776     for (auto Idx : seq<unsigned>(0, FPI->arg_size()))
3777       EXPECT_EQ(FPI->getArgOperand(Idx),
3778                 Ctx.getValue(LLVMFPI->getArgOperand(Idx)));
3779     // Check setArgOperand().
3780     auto *OrigArgOperand = FPI->getArgOperand(0);
3781     auto *NewArgOperand = Dispatch;
3782     EXPECT_NE(NewArgOperand, OrigArgOperand);
3783     FPI->setArgOperand(0, NewArgOperand);
3784     EXPECT_EQ(FPI->getArgOperand(0), NewArgOperand);
3785     FPI->setArgOperand(0, OrigArgOperand);
3786     EXPECT_EQ(FPI->getArgOperand(0), OrigArgOperand);
3787   }
3788   // Check CatchPadInst::create().
3789   auto *NewCPI = cast<sandboxir::CatchPadInst>(sandboxir::CatchPadInst::create(
3790       CS, {}, BBRet->getIterator(), BB, Ctx, "NewCPI"));
3791   EXPECT_EQ(NewCPI->getCatchSwitch(), CS);
3792   EXPECT_EQ(NewCPI->arg_size(), 0u);
3793   EXPECT_EQ(NewCPI->getNextNode(), BBRet);
3794 #ifndef NDEBUG
3795   EXPECT_EQ(NewCPI->getName(), "NewCPI");
3796 #endif // NDEBUG
3797   // Check CleanupPadInst::create().
3798   auto *NewCLPI =
3799       cast<sandboxir::CleanupPadInst>(sandboxir::CleanupPadInst::create(
3800           CS, {}, BBRet->getIterator(), BB, Ctx, "NewCLPI"));
3801   EXPECT_EQ(NewCLPI->getParentPad(), CS);
3802   EXPECT_EQ(NewCLPI->arg_size(), 0u);
3803   EXPECT_EQ(NewCLPI->getNextNode(), BBRet);
3804 #ifndef NDEBUG
3805   EXPECT_EQ(NewCLPI->getName(), "NewCLPI");
3806 #endif // NDEBUG
3807 }
3808 
3809 TEST_F(SandboxIRTest, CatchReturnInst) {
3810   parseIR(C, R"IR(
3811 define void @foo() {
3812 dispatch:
3813   %cs = catchswitch within none [label %catch] unwind to caller
3814 catch:
3815   %catchpad = catchpad within %cs [ptr @foo]
3816   catchret from %catchpad to label %continue
3817 continue:
3818   ret void
3819 catch2:
3820   %catchpad2 = catchpad within %cs [ptr @foo]
3821   ret void
3822 }
3823 )IR");
3824   Function &LLVMF = *M->getFunction("foo");
3825   BasicBlock *LLVMCatch = getBasicBlockByName(LLVMF, "catch");
3826   auto LLVMIt = LLVMCatch->begin();
3827   [[maybe_unused]] auto *LLVMCP = cast<llvm::CatchPadInst>(&*LLVMIt++);
3828   auto *LLVMCR = cast<llvm::CatchReturnInst>(&*LLVMIt++);
3829 
3830   sandboxir::Context Ctx(C);
3831   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
3832   auto *Catch = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCatch));
3833   auto *Catch2 = cast<sandboxir::BasicBlock>(
3834       Ctx.getValue(getBasicBlockByName(LLVMF, "catch2")));
3835   auto It = Catch->begin();
3836   [[maybe_unused]] auto *CP = cast<sandboxir::CatchPadInst>(&*It++);
3837   auto *CR = cast<sandboxir::CatchReturnInst>(&*It++);
3838   auto *CP2 = cast<sandboxir::CatchPadInst>(&*Catch2->begin());
3839 
3840   // Check getCatchPad().
3841   EXPECT_EQ(CR->getCatchPad(), Ctx.getValue(LLVMCR->getCatchPad()));
3842   // Check setCatchPad().
3843   auto *OrigCP = CR->getCatchPad();
3844   auto *NewCP = CP2;
3845   EXPECT_NE(NewCP, OrigCP);
3846   CR->setCatchPad(NewCP);
3847   EXPECT_EQ(CR->getCatchPad(), NewCP);
3848   CR->setCatchPad(OrigCP);
3849   EXPECT_EQ(CR->getCatchPad(), OrigCP);
3850   // Check getSuccessor().
3851   EXPECT_EQ(CR->getSuccessor(), Ctx.getValue(LLVMCR->getSuccessor()));
3852   // Check setSuccessor().
3853   auto *OrigSucc = CR->getSuccessor();
3854   auto *NewSucc = Catch;
3855   EXPECT_NE(NewSucc, OrigSucc);
3856   CR->setSuccessor(NewSucc);
3857   EXPECT_EQ(CR->getSuccessor(), NewSucc);
3858   CR->setSuccessor(OrigSucc);
3859   EXPECT_EQ(CR->getSuccessor(), OrigSucc);
3860   // Check getNumSuccessors().
3861   EXPECT_EQ(CR->getNumSuccessors(), LLVMCR->getNumSuccessors());
3862   // Check getCatchSwitchParentPad().
3863   EXPECT_EQ(CR->getCatchSwitchParentPad(),
3864             Ctx.getValue(LLVMCR->getCatchSwitchParentPad()));
3865   // Check create().
3866   auto *CRI =
3867       cast<sandboxir::CatchReturnInst>(sandboxir::CatchReturnInst::create(
3868           CP, Catch, CP->getIterator(), Catch, Ctx));
3869   EXPECT_EQ(CRI->getNextNode(), CP);
3870   EXPECT_EQ(CRI->getCatchPad(), CP);
3871   EXPECT_EQ(CRI->getSuccessor(), Catch);
3872 }
3873 
3874 TEST_F(SandboxIRTest, CleanupReturnInst) {
3875   parseIR(C, R"IR(
3876 define void @foo() {
3877 dispatch:
3878   invoke void @foo()
3879               to label %throw unwind label %cleanup
3880 throw:
3881   ret void
3882 cleanup:
3883   %cleanuppad = cleanuppad within none []
3884   cleanupret from %cleanuppad unwind label %cleanup2
3885 cleanup2:
3886   %cleanuppad2 = cleanuppad within none []
3887   ret void
3888 }
3889 )IR");
3890   Function &LLVMF = *M->getFunction("foo");
3891   BasicBlock *LLVMCleanup = getBasicBlockByName(LLVMF, "cleanup");
3892   auto LLVMIt = LLVMCleanup->begin();
3893   [[maybe_unused]] auto *LLVMCP = cast<llvm::CleanupPadInst>(&*LLVMIt++);
3894   auto *LLVMCRI = cast<llvm::CleanupReturnInst>(&*LLVMIt++);
3895 
3896   sandboxir::Context Ctx(C);
3897   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
3898   auto *Throw = cast<sandboxir::BasicBlock>(
3899       Ctx.getValue(getBasicBlockByName(LLVMF, "throw")));
3900   auto *Cleanup = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCleanup));
3901   auto *Cleanup2 = cast<sandboxir::BasicBlock>(
3902       Ctx.getValue(getBasicBlockByName(LLVMF, "cleanup2")));
3903   auto It = Cleanup->begin();
3904   [[maybe_unused]] auto *CP = cast<sandboxir::CleanupPadInst>(&*It++);
3905   auto *CRI = cast<sandboxir::CleanupReturnInst>(&*It++);
3906   It = Cleanup2->begin();
3907   auto *CP2 = cast<sandboxir::CleanupPadInst>(&*It++);
3908   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
3909 
3910   // Check hasUnwindDest().
3911   EXPECT_EQ(CRI->hasUnwindDest(), LLVMCRI->hasUnwindDest());
3912   // Check unwindsToCaller().
3913   EXPECT_EQ(CRI->unwindsToCaller(), LLVMCRI->unwindsToCaller());
3914   // Check getCleanupPad().
3915   EXPECT_EQ(CRI->getCleanupPad(), Ctx.getValue(LLVMCRI->getCleanupPad()));
3916   // Check setCleanupPad().
3917   auto *OrigCleanupPad = CRI->getCleanupPad();
3918   auto *NewCleanupPad = CP2;
3919   EXPECT_NE(NewCleanupPad, OrigCleanupPad);
3920   CRI->setCleanupPad(NewCleanupPad);
3921   EXPECT_EQ(CRI->getCleanupPad(), NewCleanupPad);
3922   CRI->setCleanupPad(OrigCleanupPad);
3923   EXPECT_EQ(CRI->getCleanupPad(), OrigCleanupPad);
3924   // Check setNumSuccessors().
3925   EXPECT_EQ(CRI->getNumSuccessors(), LLVMCRI->getNumSuccessors());
3926   // Check getUnwindDest().
3927   EXPECT_EQ(CRI->getUnwindDest(), Ctx.getValue(LLVMCRI->getUnwindDest()));
3928   // Check setUnwindDest().
3929   auto *OrigUnwindDest = CRI->getUnwindDest();
3930   auto *NewUnwindDest = Throw;
3931   EXPECT_NE(NewUnwindDest, OrigUnwindDest);
3932   CRI->setUnwindDest(NewUnwindDest);
3933   EXPECT_EQ(CRI->getUnwindDest(), NewUnwindDest);
3934   CRI->setUnwindDest(OrigUnwindDest);
3935   EXPECT_EQ(CRI->getUnwindDest(), OrigUnwindDest);
3936   // Check create().
3937   auto *UnwindBB = Cleanup;
3938   auto *NewCRI = sandboxir::CleanupReturnInst::create(
3939       CP2, UnwindBB, Ret->getIterator(), Ret->getParent(), Ctx);
3940   EXPECT_EQ(NewCRI->getCleanupPad(), CP2);
3941   EXPECT_EQ(NewCRI->getUnwindDest(), UnwindBB);
3942   EXPECT_EQ(NewCRI->getNextNode(), Ret);
3943 }
3944 
3945 TEST_F(SandboxIRTest, GetElementPtrInstruction) {
3946   parseIR(C, R"IR(
3947 define void @foo(ptr %ptr, <2 x ptr> %ptrs) {
3948   %gep0 = getelementptr i8, ptr %ptr, i32 0
3949   %gep1 = getelementptr nusw i8, ptr %ptr, i32 0
3950   %gep2 = getelementptr nuw i8, ptr %ptr, i32 0
3951   %gep3 = getelementptr inbounds {i32, {i32, i8}}, ptr %ptr, i32 1, i32 0
3952   %gep4 = getelementptr inbounds {i8, i8, {i32, i16}}, <2 x ptr> %ptrs, i32 2, <2 x i32> <i32 0, i32 0>
3953   ret void
3954 }
3955 )IR");
3956   Function &LLVMF = *M->getFunction("foo");
3957   BasicBlock *LLVMBB = &*LLVMF.begin();
3958   auto LLVMIt = LLVMBB->begin();
3959   SmallVector<llvm::GetElementPtrInst *, 4> LLVMGEPs;
3960   while (isa<llvm::GetElementPtrInst>(&*LLVMIt))
3961     LLVMGEPs.push_back(cast<llvm::GetElementPtrInst>(&*LLVMIt++));
3962   auto *LLVMRet = cast<llvm::ReturnInst>(&*LLVMIt++);
3963   sandboxir::Context Ctx(C);
3964   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
3965 
3966   for (llvm::GetElementPtrInst *LLVMGEP : LLVMGEPs) {
3967     // Check classof().
3968     auto *GEP = cast<sandboxir::GetElementPtrInst>(Ctx.getValue(LLVMGEP));
3969     // Check getSourceElementType().
3970     EXPECT_EQ(GEP->getSourceElementType(),
3971               Ctx.getType(LLVMGEP->getSourceElementType()));
3972     // Check getResultElementType().
3973     EXPECT_EQ(GEP->getResultElementType(),
3974               Ctx.getType(LLVMGEP->getResultElementType()));
3975     // Check getAddressSpace().
3976     EXPECT_EQ(GEP->getAddressSpace(), LLVMGEP->getAddressSpace());
3977     // Check indices().
3978     EXPECT_EQ(range_size(GEP->indices()), range_size(LLVMGEP->indices()));
3979     auto IdxIt = GEP->idx_begin();
3980     for (llvm::Value *LLVMIdxV : LLVMGEP->indices()) {
3981       sandboxir::Value *IdxV = *IdxIt++;
3982       EXPECT_EQ(IdxV, Ctx.getValue(LLVMIdxV));
3983     }
3984     // Check getPointerOperand().
3985     EXPECT_EQ(GEP->getPointerOperand(),
3986               Ctx.getValue(LLVMGEP->getPointerOperand()));
3987     // Check getPointerOperandIndex().
3988     EXPECT_EQ(GEP->getPointerOperandIndex(), LLVMGEP->getPointerOperandIndex());
3989     // Check getPointerOperandType().
3990     EXPECT_EQ(GEP->getPointerOperandType(),
3991               Ctx.getType(LLVMGEP->getPointerOperandType()));
3992     // Check getPointerAddressSpace().
3993     EXPECT_EQ(GEP->getPointerAddressSpace(), LLVMGEP->getPointerAddressSpace());
3994     // Check getNumIndices().
3995     EXPECT_EQ(GEP->getNumIndices(), LLVMGEP->getNumIndices());
3996     // Check hasIndices().
3997     EXPECT_EQ(GEP->hasIndices(), LLVMGEP->hasIndices());
3998     // Check hasAllConstantIndices().
3999     EXPECT_EQ(GEP->hasAllConstantIndices(), LLVMGEP->hasAllConstantIndices());
4000     // Check getNoWrapFlags().
4001     EXPECT_EQ(GEP->getNoWrapFlags(), LLVMGEP->getNoWrapFlags());
4002     // Check isInBounds().
4003     EXPECT_EQ(GEP->isInBounds(), LLVMGEP->isInBounds());
4004     // Check hasNoUnsignedWrap().
4005     EXPECT_EQ(GEP->hasNoUnsignedWrap(), LLVMGEP->hasNoUnsignedWrap());
4006     // Check accumulateConstantOffset().
4007     const DataLayout &DL = M->getDataLayout();
4008     APInt Offset1 =
4009         APInt::getZero(DL.getIndexSizeInBits(GEP->getPointerAddressSpace()));
4010     APInt Offset2 =
4011         APInt::getZero(DL.getIndexSizeInBits(GEP->getPointerAddressSpace()));
4012     EXPECT_EQ(GEP->accumulateConstantOffset(DL, Offset1),
4013               LLVMGEP->accumulateConstantOffset(DL, Offset2));
4014     EXPECT_EQ(Offset1, Offset2);
4015   }
4016 
4017   auto *BB = &*F.begin();
4018   auto *GEP0 = cast<sandboxir::GetElementPtrInst>(&*BB->begin());
4019   auto *Ret = cast<sandboxir::ReturnInst>(Ctx.getValue(LLVMRet));
4020   SmallVector<sandboxir::Value *> Indices(GEP0->indices());
4021 
4022   // Check create() WhereIt, WhereBB.
4023   auto *NewGEP0 =
4024       cast<sandboxir::GetElementPtrInst>(sandboxir::GetElementPtrInst::create(
4025           GEP0->getType(), GEP0->getPointerOperand(), Indices,
4026           /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx,
4027           "NewGEP0"));
4028   EXPECT_EQ(NewGEP0->getName(), "NewGEP0");
4029   EXPECT_EQ(NewGEP0->getType(), GEP0->getType());
4030   EXPECT_EQ(NewGEP0->getPointerOperand(), GEP0->getPointerOperand());
4031   EXPECT_EQ(range_size(NewGEP0->indices()), range_size(GEP0->indices()));
4032   for (auto NewIt = NewGEP0->idx_begin(), NewItE = NewGEP0->idx_end(),
4033             OldIt = GEP0->idx_begin();
4034        NewIt != NewItE; ++NewIt) {
4035     sandboxir::Value *NewIdxV = *NewIt;
4036     sandboxir::Value *OldIdxV = *OldIt;
4037     EXPECT_EQ(NewIdxV, OldIdxV);
4038   }
4039   EXPECT_EQ(NewGEP0->getNextNode(), Ret);
4040 
4041   // Check create() InsertBefore.
4042   auto *NewGEP1 =
4043       cast<sandboxir::GetElementPtrInst>(sandboxir::GetElementPtrInst::create(
4044           GEP0->getType(), GEP0->getPointerOperand(), Indices,
4045           /*InsertBefore=*/Ret, Ctx, "NewGEP1"));
4046   EXPECT_EQ(NewGEP1->getName(), "NewGEP1");
4047   EXPECT_EQ(NewGEP1->getType(), GEP0->getType());
4048   EXPECT_EQ(NewGEP1->getPointerOperand(), GEP0->getPointerOperand());
4049   EXPECT_EQ(range_size(NewGEP1->indices()), range_size(GEP0->indices()));
4050   for (auto NewIt = NewGEP0->idx_begin(), NewItE = NewGEP0->idx_end(),
4051             OldIt = GEP0->idx_begin();
4052        NewIt != NewItE; ++NewIt) {
4053     sandboxir::Value *NewIdxV = *NewIt;
4054     sandboxir::Value *OldIdxV = *OldIt;
4055     EXPECT_EQ(NewIdxV, OldIdxV);
4056   }
4057   EXPECT_EQ(NewGEP1->getNextNode(), Ret);
4058 
4059   // Check create() InsertAtEnd.
4060   auto *NewGEP2 =
4061       cast<sandboxir::GetElementPtrInst>(sandboxir::GetElementPtrInst::create(
4062           GEP0->getType(), GEP0->getPointerOperand(), Indices,
4063           /*InsertAtEnd=*/BB, Ctx, "NewGEP2"));
4064   EXPECT_EQ(NewGEP2->getName(), "NewGEP2");
4065   EXPECT_EQ(NewGEP2->getType(), GEP0->getType());
4066   EXPECT_EQ(NewGEP2->getPointerOperand(), GEP0->getPointerOperand());
4067   EXPECT_EQ(range_size(NewGEP2->indices()), range_size(GEP0->indices()));
4068   for (auto NewIt = NewGEP0->idx_begin(), NewItE = NewGEP0->idx_end(),
4069             OldIt = GEP0->idx_begin();
4070        NewIt != NewItE; ++NewIt) {
4071     sandboxir::Value *NewIdxV = *NewIt;
4072     sandboxir::Value *OldIdxV = *OldIt;
4073     EXPECT_EQ(NewIdxV, OldIdxV);
4074   }
4075   EXPECT_EQ(NewGEP2->getPrevNode(), Ret);
4076   EXPECT_EQ(NewGEP2->getNextNode(), nullptr);
4077 }
4078 
4079 TEST_F(SandboxIRTest, Flags) {
4080   parseIR(C, R"IR(
4081 define void @foo(i32 %arg, float %farg) {
4082   %add = add i32 %arg, %arg
4083   %fadd = fadd float %farg, %farg
4084   %udiv = udiv i32 %arg, %arg
4085   ret void
4086 }
4087 )IR");
4088   Function &LLVMF = *M->getFunction("foo");
4089   BasicBlock *LLVMBB = &*LLVMF.begin();
4090   auto LLVMIt = LLVMBB->begin();
4091   auto *LLVMAdd = &*LLVMIt++;
4092   auto *LLVMFAdd = &*LLVMIt++;
4093   auto *LLVMUDiv = &*LLVMIt++;
4094 
4095   sandboxir::Context Ctx(C);
4096   auto &F = *Ctx.createFunction(&LLVMF);
4097   auto *BB = &*F.begin();
4098   auto It = BB->begin();
4099   auto *Add = &*It++;
4100   auto *FAdd = &*It++;
4101   auto *UDiv = &*It++;
4102 
4103 #define CHECK_FLAG(I, LLVMI, GETTER, SETTER)                                   \
4104   {                                                                            \
4105     EXPECT_EQ(I->GETTER(), LLVMI->GETTER());                                   \
4106     bool NewFlagVal = !I->GETTER();                                            \
4107     I->SETTER(NewFlagVal);                                                     \
4108     EXPECT_EQ(I->GETTER(), NewFlagVal);                                        \
4109     EXPECT_EQ(I->GETTER(), LLVMI->GETTER());                                   \
4110   }
4111 
4112   CHECK_FLAG(Add, LLVMAdd, hasNoUnsignedWrap, setHasNoUnsignedWrap);
4113   CHECK_FLAG(Add, LLVMAdd, hasNoSignedWrap, setHasNoSignedWrap);
4114   CHECK_FLAG(FAdd, LLVMFAdd, isFast, setFast);
4115   CHECK_FLAG(FAdd, LLVMFAdd, hasAllowReassoc, setHasAllowReassoc);
4116   CHECK_FLAG(UDiv, LLVMUDiv, isExact, setIsExact);
4117   CHECK_FLAG(FAdd, LLVMFAdd, hasNoNaNs, setHasNoNaNs);
4118   CHECK_FLAG(FAdd, LLVMFAdd, hasNoInfs, setHasNoInfs);
4119   CHECK_FLAG(FAdd, LLVMFAdd, hasNoSignedZeros, setHasNoSignedZeros);
4120   CHECK_FLAG(FAdd, LLVMFAdd, hasAllowReciprocal, setHasAllowReciprocal);
4121   CHECK_FLAG(FAdd, LLVMFAdd, hasAllowContract, setHasAllowContract);
4122   CHECK_FLAG(FAdd, LLVMFAdd, hasApproxFunc, setHasApproxFunc);
4123 
4124   // Check getFastMathFlags(), copyFastMathFlags().
4125   FAdd->setFastMathFlags(FastMathFlags::getFast());
4126   EXPECT_FALSE(FAdd->getFastMathFlags() != LLVMFAdd->getFastMathFlags());
4127   FastMathFlags OrigFMF = FAdd->getFastMathFlags();
4128   FastMathFlags NewFMF;
4129   NewFMF.setAllowReassoc(true);
4130   EXPECT_TRUE(NewFMF != OrigFMF);
4131   FAdd->setFastMathFlags(NewFMF);
4132   EXPECT_FALSE(FAdd->getFastMathFlags() != OrigFMF);
4133   FAdd->copyFastMathFlags(NewFMF);
4134   EXPECT_FALSE(FAdd->getFastMathFlags() != NewFMF);
4135   EXPECT_FALSE(FAdd->getFastMathFlags() != LLVMFAdd->getFastMathFlags());
4136 }
4137 
4138 TEST_F(SandboxIRTest, CatchSwitchInst) {
4139   parseIR(C, R"IR(
4140 define void @foo(i32 %cond0, i32 %cond1) {
4141   bb0:
4142     %cs0 = catchswitch within none [label %handler0, label %handler1] unwind to caller
4143   bb1:
4144     %cs1 = catchswitch within %cs0 [label %handler0, label %handler1] unwind label %cleanup
4145   handler0:
4146     ret void
4147   handler1:
4148     ret void
4149   cleanup:
4150     ret void
4151 }
4152 )IR");
4153   Function &LLVMF = *M->getFunction("foo");
4154   auto *LLVMBB0 = getBasicBlockByName(LLVMF, "bb0");
4155   auto *LLVMBB1 = getBasicBlockByName(LLVMF, "bb1");
4156   auto *LLVMHandler0 = getBasicBlockByName(LLVMF, "handler0");
4157   auto *LLVMHandler1 = getBasicBlockByName(LLVMF, "handler1");
4158   auto *LLVMCleanup = getBasicBlockByName(LLVMF, "cleanup");
4159   auto *LLVMCS0 = cast<llvm::CatchSwitchInst>(&*LLVMBB0->begin());
4160   auto *LLVMCS1 = cast<llvm::CatchSwitchInst>(&*LLVMBB1->begin());
4161 
4162   sandboxir::Context Ctx(C);
4163   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
4164   auto *BB0 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB0));
4165   auto *BB1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB1));
4166   auto *Handler0 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler0));
4167   auto *Handler1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler1));
4168   auto *Cleanup = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCleanup));
4169   auto *CS0 = cast<sandboxir::CatchSwitchInst>(&*BB0->begin());
4170   auto *CS1 = cast<sandboxir::CatchSwitchInst>(&*BB1->begin());
4171 
4172   // Check getParentPad().
4173   EXPECT_EQ(CS0->getParentPad(), Ctx.getValue(LLVMCS0->getParentPad()));
4174   EXPECT_EQ(CS1->getParentPad(), Ctx.getValue(LLVMCS1->getParentPad()));
4175   // Check setParentPad().
4176   auto *OrigPad = CS0->getParentPad();
4177   auto *NewPad = CS1;
4178   EXPECT_NE(NewPad, OrigPad);
4179   CS0->setParentPad(NewPad);
4180   EXPECT_EQ(CS0->getParentPad(), NewPad);
4181   CS0->setParentPad(OrigPad);
4182   EXPECT_EQ(CS0->getParentPad(), OrigPad);
4183   // Check hasUnwindDest().
4184   EXPECT_EQ(CS0->hasUnwindDest(), LLVMCS0->hasUnwindDest());
4185   EXPECT_EQ(CS1->hasUnwindDest(), LLVMCS1->hasUnwindDest());
4186   // Check unwindsToCaller().
4187   EXPECT_EQ(CS0->unwindsToCaller(), LLVMCS0->unwindsToCaller());
4188   EXPECT_EQ(CS1->unwindsToCaller(), LLVMCS1->unwindsToCaller());
4189   // Check getUnwindDest().
4190   EXPECT_EQ(CS0->getUnwindDest(), Ctx.getValue(LLVMCS0->getUnwindDest()));
4191   EXPECT_EQ(CS1->getUnwindDest(), Ctx.getValue(LLVMCS1->getUnwindDest()));
4192   // Check setUnwindDest().
4193   auto *OrigUnwindDest = CS1->getUnwindDest();
4194   auto *NewUnwindDest = BB0;
4195   EXPECT_NE(NewUnwindDest, OrigUnwindDest);
4196   CS1->setUnwindDest(NewUnwindDest);
4197   EXPECT_EQ(CS1->getUnwindDest(), NewUnwindDest);
4198   CS1->setUnwindDest(OrigUnwindDest);
4199   EXPECT_EQ(CS1->getUnwindDest(), OrigUnwindDest);
4200   // Check getNumHandlers().
4201   EXPECT_EQ(CS0->getNumHandlers(), LLVMCS0->getNumHandlers());
4202   EXPECT_EQ(CS1->getNumHandlers(), LLVMCS1->getNumHandlers());
4203   // Check handler_begin(), handler_end().
4204   auto It = CS0->handler_begin();
4205   EXPECT_EQ(*It++, Handler0);
4206   EXPECT_EQ(*It++, Handler1);
4207   EXPECT_EQ(It, CS0->handler_end());
4208   // Check handlers().
4209   SmallVector<sandboxir::BasicBlock *, 2> Handlers;
4210   for (sandboxir::BasicBlock *Handler : CS0->handlers())
4211     Handlers.push_back(Handler);
4212   EXPECT_EQ(Handlers.size(), 2u);
4213   EXPECT_EQ(Handlers[0], Handler0);
4214   EXPECT_EQ(Handlers[1], Handler1);
4215   // Check addHandler().
4216   CS0->addHandler(BB0);
4217   EXPECT_EQ(CS0->getNumHandlers(), 3u);
4218   EXPECT_EQ(*std::next(CS0->handler_begin(), 2), BB0);
4219   // Check getNumSuccessors().
4220   EXPECT_EQ(CS0->getNumSuccessors(), LLVMCS0->getNumSuccessors());
4221   EXPECT_EQ(CS1->getNumSuccessors(), LLVMCS1->getNumSuccessors());
4222   // Check getSuccessor().
4223   for (auto SuccIdx : seq<unsigned>(0, CS0->getNumSuccessors()))
4224     EXPECT_EQ(CS0->getSuccessor(SuccIdx),
4225               Ctx.getValue(LLVMCS0->getSuccessor(SuccIdx)));
4226   // Check setSuccessor().
4227   auto *OrigSuccessor = CS0->getSuccessor(0);
4228   auto *NewSuccessor = BB0;
4229   EXPECT_NE(NewSuccessor, OrigSuccessor);
4230   CS0->setSuccessor(0, NewSuccessor);
4231   EXPECT_EQ(CS0->getSuccessor(0), NewSuccessor);
4232   CS0->setSuccessor(0, OrigSuccessor);
4233   EXPECT_EQ(CS0->getSuccessor(0), OrigSuccessor);
4234   // Check create().
4235   CS1->eraseFromParent();
4236   auto *NewCSI = sandboxir::CatchSwitchInst::create(
4237       CS0, Cleanup, 2, BB1->begin(), BB1, Ctx, "NewCSI");
4238   EXPECT_TRUE(isa<sandboxir::CatchSwitchInst>(NewCSI));
4239   EXPECT_EQ(NewCSI->getParentPad(), CS0);
4240 }
4241 
4242 TEST_F(SandboxIRTest, ResumeInst) {
4243   parseIR(C, R"IR(
4244 define void @foo() {
4245 entry:
4246   invoke void @foo()
4247       to label %bb unwind label %unwind
4248 bb:
4249   ret void
4250 unwind:
4251   %lpad = landingpad { ptr, i32 }
4252           cleanup
4253   resume { ptr, i32 } %lpad
4254 }
4255 )IR");
4256   Function &LLVMF = *M->getFunction("foo");
4257   auto *LLVMUnwindBB = getBasicBlockByName(LLVMF, "unwind");
4258   auto LLVMIt = LLVMUnwindBB->begin();
4259   [[maybe_unused]] auto *LLVMLPad = cast<llvm::LandingPadInst>(&*LLVMIt++);
4260   auto *LLVMResume = cast<llvm::ResumeInst>(&*LLVMIt++);
4261 
4262   sandboxir::Context Ctx(C);
4263   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
4264   auto *UnwindBB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMUnwindBB));
4265   auto It = UnwindBB->begin();
4266   auto *LPad = cast<sandboxir::LandingPadInst>(&*It++);
4267   auto *Resume = cast<sandboxir::ResumeInst>(&*It++);
4268   // Check getValue().
4269   EXPECT_EQ(Resume->getValue(), LPad);
4270   EXPECT_EQ(Resume->getValue(), Ctx.getValue(LLVMResume->getValue()));
4271   // Check getNumSuccessors().
4272   EXPECT_EQ(Resume->getNumSuccessors(), LLVMResume->getNumSuccessors());
4273   // Check create().
4274   auto *NewResume =
4275       sandboxir::ResumeInst::create(LPad, UnwindBB->end(), UnwindBB, Ctx);
4276   EXPECT_EQ(NewResume->getValue(), LPad);
4277   EXPECT_EQ(NewResume->getParent(), UnwindBB);
4278   EXPECT_EQ(NewResume->getNextNode(), nullptr);
4279 }
4280 
4281 TEST_F(SandboxIRTest, SwitchInst) {
4282   parseIR(C, R"IR(
4283 define void @foo(i32 %cond0, i32 %cond1) {
4284   entry:
4285     switch i32 %cond0, label %default [ i32 0, label %bb0
4286                                         i32 1, label %bb1 ]
4287   bb0:
4288     ret void
4289   bb1:
4290     ret void
4291   default:
4292     ret void
4293 }
4294 )IR");
4295   Function &LLVMF = *M->getFunction("foo");
4296   auto *LLVMEntry = getBasicBlockByName(LLVMF, "entry");
4297   auto *LLVMSwitch = cast<llvm::SwitchInst>(&*LLVMEntry->begin());
4298 
4299   sandboxir::Context Ctx(C);
4300   auto &F = *Ctx.createFunction(&LLVMF);
4301   auto *Cond1 = F.getArg(1);
4302   auto *Entry = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMEntry));
4303   auto *Switch = cast<sandboxir::SwitchInst>(&*Entry->begin());
4304   auto *BB0 = cast<sandboxir::BasicBlock>(
4305       Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
4306   auto *BB1 = cast<sandboxir::BasicBlock>(
4307       Ctx.getValue(getBasicBlockByName(LLVMF, "bb1")));
4308   auto *Default = cast<sandboxir::BasicBlock>(
4309       Ctx.getValue(getBasicBlockByName(LLVMF, "default")));
4310 
4311   // Check getCondition().
4312   EXPECT_EQ(Switch->getCondition(), Ctx.getValue(LLVMSwitch->getCondition()));
4313   // Check setCondition().
4314   auto *OrigCond = Switch->getCondition();
4315   auto *NewCond = Cond1;
4316   EXPECT_NE(NewCond, OrigCond);
4317   Switch->setCondition(NewCond);
4318   EXPECT_EQ(Switch->getCondition(), NewCond);
4319   Switch->setCondition(OrigCond);
4320   EXPECT_EQ(Switch->getCondition(), OrigCond);
4321   // Check getDefaultDest().
4322   EXPECT_EQ(Switch->getDefaultDest(),
4323             Ctx.getValue(LLVMSwitch->getDefaultDest()));
4324   EXPECT_EQ(Switch->getDefaultDest(), Default);
4325   // Check defaultDestUndefined().
4326   EXPECT_EQ(Switch->defaultDestUndefined(), LLVMSwitch->defaultDestUndefined());
4327   // Check setDefaultDest().
4328   auto *OrigDefaultDest = Switch->getDefaultDest();
4329   auto *NewDefaultDest = Entry;
4330   EXPECT_NE(NewDefaultDest, OrigDefaultDest);
4331   Switch->setDefaultDest(NewDefaultDest);
4332   EXPECT_EQ(Switch->getDefaultDest(), NewDefaultDest);
4333   Switch->setDefaultDest(OrigDefaultDest);
4334   EXPECT_EQ(Switch->getDefaultDest(), OrigDefaultDest);
4335   // Check getNumCases().
4336   EXPECT_EQ(Switch->getNumCases(), LLVMSwitch->getNumCases());
4337   // Check getNumSuccessors().
4338   EXPECT_EQ(Switch->getNumSuccessors(), LLVMSwitch->getNumSuccessors());
4339   // Check getSuccessor().
4340   for (auto SuccIdx : seq<unsigned>(0, Switch->getNumSuccessors()))
4341     EXPECT_EQ(Switch->getSuccessor(SuccIdx),
4342               Ctx.getValue(LLVMSwitch->getSuccessor(SuccIdx)));
4343   // Check setSuccessor().
4344   auto *OrigSucc = Switch->getSuccessor(0);
4345   auto *NewSucc = Entry;
4346   EXPECT_NE(NewSucc, OrigSucc);
4347   Switch->setSuccessor(0, NewSucc);
4348   EXPECT_EQ(Switch->getSuccessor(0), NewSucc);
4349   Switch->setSuccessor(0, OrigSucc);
4350   EXPECT_EQ(Switch->getSuccessor(0), OrigSucc);
4351   // Check case_begin(), case_end(), CaseIt.
4352   auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0);
4353   auto *One = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 1);
4354   auto CaseIt = Switch->case_begin();
4355   {
4356     sandboxir::SwitchInst::CaseHandle Case = *CaseIt++;
4357     EXPECT_EQ(Case.getCaseValue(), Zero);
4358     EXPECT_EQ(Case.getCaseSuccessor(), BB0);
4359     EXPECT_EQ(Case.getCaseIndex(), 0u);
4360     EXPECT_EQ(Case.getSuccessorIndex(), 1u);
4361   }
4362   {
4363     sandboxir::SwitchInst::CaseHandle Case = *CaseIt++;
4364     EXPECT_EQ(Case.getCaseValue(), One);
4365     EXPECT_EQ(Case.getCaseSuccessor(), BB1);
4366     EXPECT_EQ(Case.getCaseIndex(), 1u);
4367     EXPECT_EQ(Case.getSuccessorIndex(), 2u);
4368   }
4369   EXPECT_EQ(CaseIt, Switch->case_end());
4370   // Check cases().
4371   unsigned CntCase = 0;
4372   for (auto &Case : Switch->cases()) {
4373     EXPECT_EQ(Case.getCaseIndex(), CntCase);
4374     ++CntCase;
4375   }
4376   EXPECT_EQ(CntCase, 2u);
4377   // Check case_default().
4378   auto CaseDefault = *Switch->case_default();
4379   EXPECT_EQ(CaseDefault.getCaseSuccessor(), Default);
4380   EXPECT_EQ(CaseDefault.getCaseIndex(),
4381             sandboxir::SwitchInst::DefaultPseudoIndex);
4382   // Check findCaseValue().
4383   EXPECT_EQ(Switch->findCaseValue(Zero)->getCaseIndex(), 0u);
4384   EXPECT_EQ(Switch->findCaseValue(One)->getCaseIndex(), 1u);
4385   // Check findCaseDest().
4386   EXPECT_EQ(Switch->findCaseDest(BB0), Zero);
4387   EXPECT_EQ(Switch->findCaseDest(BB1), One);
4388   EXPECT_EQ(Switch->findCaseDest(Entry), nullptr);
4389   // Check addCase().
4390   auto *Two = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 2);
4391   Switch->addCase(Two, Entry);
4392   auto CaseTwoIt = Switch->findCaseValue(Two);
4393   auto CaseTwo = *CaseTwoIt;
4394   EXPECT_EQ(CaseTwo.getCaseValue(), Two);
4395   EXPECT_EQ(CaseTwo.getCaseSuccessor(), Entry);
4396   EXPECT_EQ(Switch->getNumCases(), 3u);
4397   // Check removeCase().
4398   auto RemovedIt = Switch->removeCase(CaseTwoIt);
4399   EXPECT_EQ(RemovedIt, Switch->case_end());
4400   EXPECT_EQ(Switch->getNumCases(), 2u);
4401   // Check create().
4402   auto NewSwitch = sandboxir::SwitchInst::create(
4403       Cond1, Default, 1, Default->begin(), Default, Ctx, "NewSwitch");
4404   EXPECT_TRUE(isa<sandboxir::SwitchInst>(NewSwitch));
4405   EXPECT_EQ(NewSwitch->getCondition(), Cond1);
4406   EXPECT_EQ(NewSwitch->getDefaultDest(), Default);
4407 }
4408 
4409 TEST_F(SandboxIRTest, UnaryOperator) {
4410   parseIR(C, R"IR(
4411 define void @foo(float %arg0) {
4412   %fneg = fneg float %arg0
4413   %copyfrom = fadd reassoc float %arg0, 42.0
4414   ret void
4415 }
4416 )IR");
4417   Function &LLVMF = *M->getFunction("foo");
4418   sandboxir::Context Ctx(C);
4419 
4420   auto &F = *Ctx.createFunction(&LLVMF);
4421   auto *Arg0 = F.getArg(0);
4422   auto *BB = &*F.begin();
4423   auto It = BB->begin();
4424   auto *I = cast<sandboxir::UnaryOperator>(&*It++);
4425   auto *CopyFrom = cast<sandboxir::BinaryOperator>(&*It++);
4426   auto *Ret = &*It++;
4427   EXPECT_EQ(I->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
4428   EXPECT_EQ(I->getOperand(0), Arg0);
4429 
4430   {
4431     // Check create() WhereIt, WhereBB.
4432     auto *NewI =
4433         cast<sandboxir::UnaryOperator>(sandboxir::UnaryOperator::create(
4434             sandboxir::Instruction::Opcode::FNeg, Arg0,
4435             /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx,
4436             "New1"));
4437     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
4438     EXPECT_EQ(NewI->getOperand(0), Arg0);
4439 #ifndef NDEBUG
4440     EXPECT_EQ(NewI->getName(), "New1");
4441 #endif // NDEBUG
4442     EXPECT_EQ(NewI->getNextNode(), Ret);
4443   }
4444   {
4445     // Check create() InsertBefore.
4446     auto *NewI =
4447         cast<sandboxir::UnaryOperator>(sandboxir::UnaryOperator::create(
4448             sandboxir::Instruction::Opcode::FNeg, Arg0,
4449             /*InsertBefore=*/Ret, Ctx, "New2"));
4450     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
4451     EXPECT_EQ(NewI->getOperand(0), Arg0);
4452 #ifndef NDEBUG
4453     EXPECT_EQ(NewI->getName(), "New2");
4454 #endif // NDEBUG
4455     EXPECT_EQ(NewI->getNextNode(), Ret);
4456   }
4457   {
4458     // Check create() InsertAtEnd.
4459     auto *NewI =
4460         cast<sandboxir::UnaryOperator>(sandboxir::UnaryOperator::create(
4461             sandboxir::Instruction::Opcode::FNeg, Arg0,
4462             /*InsertAtEnd=*/BB, Ctx, "New3"));
4463     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
4464     EXPECT_EQ(NewI->getOperand(0), Arg0);
4465 #ifndef NDEBUG
4466     EXPECT_EQ(NewI->getName(), "New3");
4467 #endif // NDEBUG
4468     EXPECT_EQ(NewI->getParent(), BB);
4469     EXPECT_EQ(NewI->getNextNode(), nullptr);
4470   }
4471   {
4472     // Check create() when it gets folded.
4473     auto *FortyTwo = CopyFrom->getOperand(1);
4474     auto *NewV = sandboxir::UnaryOperator::create(
4475         sandboxir::Instruction::Opcode::FNeg, FortyTwo,
4476         /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx,
4477         "Folded");
4478     EXPECT_TRUE(isa<sandboxir::Constant>(NewV));
4479   }
4480 
4481   {
4482     // Check createWithCopiedFlags() WhereIt, WhereBB.
4483     auto *NewI = cast<sandboxir::UnaryOperator>(
4484         sandboxir::UnaryOperator::createWithCopiedFlags(
4485             sandboxir::Instruction::Opcode::FNeg, Arg0, CopyFrom,
4486             /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx,
4487             "NewCopyFrom1"));
4488     EXPECT_EQ(NewI->hasAllowReassoc(), CopyFrom->hasAllowReassoc());
4489     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
4490     EXPECT_EQ(NewI->getOperand(0), Arg0);
4491 #ifndef NDEBUG
4492     EXPECT_EQ(NewI->getName(), "NewCopyFrom1");
4493 #endif // NDEBUG
4494     EXPECT_EQ(NewI->getNextNode(), Ret);
4495   }
4496   {
4497     // Check createWithCopiedFlags() InsertBefore,
4498     auto *NewI = cast<sandboxir::UnaryOperator>(
4499         sandboxir::UnaryOperator::createWithCopiedFlags(
4500             sandboxir::Instruction::Opcode::FNeg, Arg0, CopyFrom,
4501             /*InsertBefore=*/Ret, Ctx, "NewCopyFrom2"));
4502     EXPECT_EQ(NewI->hasAllowReassoc(), CopyFrom->hasAllowReassoc());
4503     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
4504     EXPECT_EQ(NewI->getOperand(0), Arg0);
4505 #ifndef NDEBUG
4506     EXPECT_EQ(NewI->getName(), "NewCopyFrom2");
4507 #endif // NDEBUG
4508     EXPECT_EQ(NewI->getNextNode(), Ret);
4509   }
4510   {
4511     // Check createWithCopiedFlags() InsertAtEnd,
4512     auto *NewI = cast<sandboxir::UnaryOperator>(
4513         sandboxir::UnaryOperator::createWithCopiedFlags(
4514             sandboxir::Instruction::Opcode::FNeg, Arg0, CopyFrom,
4515             /*InsertAtEnd=*/BB, Ctx, "NewCopyFrom3"));
4516     EXPECT_EQ(NewI->hasAllowReassoc(), CopyFrom->hasAllowReassoc());
4517     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
4518     EXPECT_EQ(NewI->getOperand(0), Arg0);
4519 #ifndef NDEBUG
4520     EXPECT_EQ(NewI->getName(), "NewCopyFrom3");
4521 #endif // NDEBUG
4522     EXPECT_EQ(NewI->getParent(), BB);
4523     EXPECT_EQ(NewI->getNextNode(), nullptr);
4524   }
4525   {
4526     // Check createWithCopiedFlags() when it gets folded.
4527     auto *FortyTwo = CopyFrom->getOperand(1);
4528     auto *NewV = sandboxir::UnaryOperator::createWithCopiedFlags(
4529         sandboxir::Instruction::Opcode::FNeg, FortyTwo, CopyFrom,
4530         /*InsertAtEnd=*/BB, Ctx, "Folded");
4531     EXPECT_TRUE(isa<sandboxir::Constant>(NewV));
4532   }
4533 }
4534 
4535 TEST_F(SandboxIRTest, BinaryOperator) {
4536   parseIR(C, R"IR(
4537 define void @foo(i8 %arg0, i8 %arg1, float %farg0, float %farg1) {
4538   %add = add i8 %arg0, %arg1
4539   %fadd = fadd float %farg0, %farg1
4540   %sub = sub i8 %arg0, %arg1
4541   %fsub = fsub float %farg0, %farg1
4542   %mul = mul i8 %arg0, %arg1
4543   %fmul = fmul float %farg0, %farg1
4544   %udiv = udiv i8 %arg0, %arg1
4545   %sdiv = sdiv i8 %arg0, %arg1
4546   %fdiv = fdiv float %farg0, %farg1
4547   %urem = urem i8 %arg0, %arg1
4548   %srem = srem i8 %arg0, %arg1
4549   %frem = frem float %farg0, %farg1
4550   %shl = shl i8 %arg0, %arg1
4551   %lshr = lshr i8 %arg0, %arg1
4552   %ashr = ashr i8 %arg0, %arg1
4553   %and = and i8 %arg0, %arg1
4554   %or = or i8 %arg0, %arg1
4555   %xor = xor i8 %arg0, %arg1
4556 
4557   %copyfrom = add nsw i8 %arg0, %arg1
4558   ret void
4559 }
4560 )IR");
4561   Function &LLVMF = *M->getFunction("foo");
4562   sandboxir::Context Ctx(C);
4563 
4564   auto &F = *Ctx.createFunction(&LLVMF);
4565   auto *Arg0 = F.getArg(0);
4566   auto *Arg1 = F.getArg(1);
4567   auto *FArg0 = F.getArg(2);
4568   auto *FArg1 = F.getArg(3);
4569   auto *BB = &*F.begin();
4570   auto It = BB->begin();
4571 
4572 #define CHECK_IBINOP(OPCODE)                                                   \
4573   {                                                                            \
4574     auto *I = cast<sandboxir::BinaryOperator>(&*It++);                         \
4575     EXPECT_EQ(I->getOpcode(), OPCODE);                                         \
4576     EXPECT_EQ(I->getOperand(0), Arg0);                                         \
4577     EXPECT_EQ(I->getOperand(1), Arg1);                                         \
4578   }
4579 #define CHECK_FBINOP(OPCODE)                                                   \
4580   {                                                                            \
4581     auto *I = cast<sandboxir::BinaryOperator>(&*It++);                         \
4582     EXPECT_EQ(I->getOpcode(), OPCODE);                                         \
4583     EXPECT_EQ(I->getOperand(0), FArg0);                                        \
4584     EXPECT_EQ(I->getOperand(1), FArg1);                                        \
4585   }
4586 
4587   CHECK_IBINOP(sandboxir::Instruction::Opcode::Add);
4588   CHECK_FBINOP(sandboxir::Instruction::Opcode::FAdd);
4589   CHECK_IBINOP(sandboxir::Instruction::Opcode::Sub);
4590   CHECK_FBINOP(sandboxir::Instruction::Opcode::FSub);
4591   CHECK_IBINOP(sandboxir::Instruction::Opcode::Mul);
4592   CHECK_FBINOP(sandboxir::Instruction::Opcode::FMul);
4593   CHECK_IBINOP(sandboxir::Instruction::Opcode::UDiv);
4594   CHECK_IBINOP(sandboxir::Instruction::Opcode::SDiv);
4595   CHECK_FBINOP(sandboxir::Instruction::Opcode::FDiv);
4596   CHECK_IBINOP(sandboxir::Instruction::Opcode::URem);
4597   CHECK_IBINOP(sandboxir::Instruction::Opcode::SRem);
4598   CHECK_FBINOP(sandboxir::Instruction::Opcode::FRem);
4599   CHECK_IBINOP(sandboxir::Instruction::Opcode::Shl);
4600   CHECK_IBINOP(sandboxir::Instruction::Opcode::LShr);
4601   CHECK_IBINOP(sandboxir::Instruction::Opcode::AShr);
4602   CHECK_IBINOP(sandboxir::Instruction::Opcode::And);
4603   CHECK_IBINOP(sandboxir::Instruction::Opcode::Or);
4604   CHECK_IBINOP(sandboxir::Instruction::Opcode::Xor);
4605 
4606   auto *CopyFrom = cast<sandboxir::BinaryOperator>(&*It++);
4607   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
4608 
4609   {
4610     // Check create() WhereIt, WhereBB.
4611     auto *NewI =
4612         cast<sandboxir::BinaryOperator>(sandboxir::BinaryOperator::create(
4613             sandboxir::Instruction::Opcode::Add, Arg0, Arg1,
4614             /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx,
4615             "New1"));
4616     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
4617     EXPECT_EQ(NewI->getOperand(0), Arg0);
4618     EXPECT_EQ(NewI->getOperand(1), Arg1);
4619 #ifndef NDEBUG
4620     EXPECT_EQ(NewI->getName(), "New1");
4621 #endif // NDEBUG
4622     EXPECT_EQ(NewI->getNextNode(), Ret);
4623   }
4624   {
4625     // Check create() InsertBefore.
4626     auto *NewI =
4627         cast<sandboxir::BinaryOperator>(sandboxir::BinaryOperator::create(
4628             sandboxir::Instruction::Opcode::Add, Arg0, Arg1,
4629             /*InsertBefore=*/Ret, Ctx, "New2"));
4630     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
4631     EXPECT_EQ(NewI->getOperand(0), Arg0);
4632     EXPECT_EQ(NewI->getOperand(1), Arg1);
4633 #ifndef NDEBUG
4634     EXPECT_EQ(NewI->getName(), "New2");
4635 #endif // NDEBUG
4636     EXPECT_EQ(NewI->getNextNode(), Ret);
4637   }
4638   {
4639     // Check create() InsertAtEnd.
4640     auto *NewI =
4641         cast<sandboxir::BinaryOperator>(sandboxir::BinaryOperator::create(
4642             sandboxir::Instruction::Opcode::Add, Arg0, Arg1,
4643             /*InsertAtEnd=*/BB, Ctx, "New3"));
4644     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
4645     EXPECT_EQ(NewI->getOperand(0), Arg0);
4646     EXPECT_EQ(NewI->getOperand(1), Arg1);
4647 #ifndef NDEBUG
4648     EXPECT_EQ(NewI->getName(), "New3");
4649 #endif // NDEBUG
4650     EXPECT_EQ(NewI->getNextNode(), nullptr);
4651     EXPECT_EQ(NewI->getParent(), BB);
4652   }
4653   {
4654     // Check create() when it gets folded.
4655     auto *FortyTwo =
4656         sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42);
4657     auto *NewV = sandboxir::BinaryOperator::create(
4658         sandboxir::Instruction::Opcode::Add, FortyTwo, FortyTwo,
4659         /*InsertBefore=*/Ret, Ctx, "Folded");
4660     EXPECT_TRUE(isa<sandboxir::Constant>(NewV));
4661   }
4662 
4663   {
4664     // Check createWithCopiedFlags() WhereIt, WhereBB.
4665     auto *NewI = cast<sandboxir::BinaryOperator>(
4666         sandboxir::BinaryOperator::createWithCopiedFlags(
4667             sandboxir::Instruction::Opcode::Add, Arg0, Arg1, CopyFrom,
4668             /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx,
4669             "NewNSW1"));
4670     EXPECT_EQ(NewI->hasNoSignedWrap(), CopyFrom->hasNoSignedWrap());
4671     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
4672     EXPECT_EQ(NewI->getOperand(0), Arg0);
4673     EXPECT_EQ(NewI->getOperand(1), Arg1);
4674 #ifndef NDEBUG
4675     EXPECT_EQ(NewI->getName(), "NewNSW1");
4676 #endif // NDEBUG
4677     EXPECT_EQ(NewI->getNextNode(), Ret);
4678   }
4679   {
4680     // Check createWithCopiedFlags() InsertBefore.
4681     auto *NewI = cast<sandboxir::BinaryOperator>(
4682         sandboxir::BinaryOperator::createWithCopiedFlags(
4683             sandboxir::Instruction::Opcode::Add, Arg0, Arg1, CopyFrom,
4684             /*InsertBefore=*/Ret, Ctx, "NewNSW2"));
4685     EXPECT_EQ(NewI->hasNoSignedWrap(), CopyFrom->hasNoSignedWrap());
4686     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
4687     EXPECT_EQ(NewI->getOperand(0), Arg0);
4688     EXPECT_EQ(NewI->getOperand(1), Arg1);
4689 #ifndef NDEBUG
4690     EXPECT_EQ(NewI->getName(), "NewNSW2");
4691 #endif // NDEBUG
4692     EXPECT_EQ(NewI->getNextNode(), Ret);
4693   }
4694   {
4695     // Check createWithCopiedFlags() InsertAtEnd.
4696     auto *NewI = cast<sandboxir::BinaryOperator>(
4697         sandboxir::BinaryOperator::createWithCopiedFlags(
4698             sandboxir::Instruction::Opcode::Add, Arg0, Arg1, CopyFrom,
4699             /*InsertAtEnd=*/BB, Ctx, "NewNSW3"));
4700     EXPECT_EQ(NewI->hasNoSignedWrap(), CopyFrom->hasNoSignedWrap());
4701     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
4702     EXPECT_EQ(NewI->getOperand(0), Arg0);
4703     EXPECT_EQ(NewI->getOperand(1), Arg1);
4704 #ifndef NDEBUG
4705     EXPECT_EQ(NewI->getName(), "NewNSW3");
4706 #endif // NDEBUG
4707     EXPECT_EQ(NewI->getParent(), BB);
4708     EXPECT_EQ(NewI->getNextNode(), nullptr);
4709   }
4710   {
4711     // Check createWithCopiedFlags() when it gets folded.
4712     auto *FortyTwo =
4713         sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42);
4714     auto *NewV = sandboxir::BinaryOperator::createWithCopiedFlags(
4715         sandboxir::Instruction::Opcode::Add, FortyTwo, FortyTwo, CopyFrom,
4716         /*InsertBefore=*/Ret, Ctx, "Folded");
4717     EXPECT_TRUE(isa<sandboxir::Constant>(NewV));
4718   }
4719 }
4720 
4721 TEST_F(SandboxIRTest, PossiblyDisjointInst) {
4722   parseIR(C, R"IR(
4723 define void @foo(i8 %arg0, i8 %arg1) {
4724   %or = or i8 %arg0, %arg1
4725   ret void
4726 }
4727 )IR");
4728   Function &LLVMF = *M->getFunction("foo");
4729   sandboxir::Context Ctx(C);
4730 
4731   auto &F = *Ctx.createFunction(&LLVMF);
4732   auto *BB = &*F.begin();
4733   auto It = BB->begin();
4734   auto *PDI = cast<sandboxir::PossiblyDisjointInst>(&*It++);
4735 
4736   // Check setIsDisjoint(), isDisjoint().
4737   auto OrigIsDisjoint = PDI->isDisjoint();
4738   auto NewIsDisjoint = true;
4739   EXPECT_NE(NewIsDisjoint, OrigIsDisjoint);
4740   PDI->setIsDisjoint(NewIsDisjoint);
4741   EXPECT_EQ(PDI->isDisjoint(), NewIsDisjoint);
4742   PDI->setIsDisjoint(OrigIsDisjoint);
4743   EXPECT_EQ(PDI->isDisjoint(), OrigIsDisjoint);
4744 }
4745 
4746 TEST_F(SandboxIRTest, AtomicRMWInst) {
4747   parseIR(C, R"IR(
4748 define void @foo(ptr %ptr, i8 %arg) {
4749   %atomicrmw = atomicrmw add ptr %ptr, i8 %arg acquire, align 128
4750   ret void
4751 }
4752 )IR");
4753   llvm::Function &LLVMF = *M->getFunction("foo");
4754   llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
4755   auto LLVMIt = LLVMBB->begin();
4756   auto *LLVMRMW = cast<llvm::AtomicRMWInst>(&*LLVMIt++);
4757 
4758   sandboxir::Context Ctx(C);
4759   sandboxir::Function *F = Ctx.createFunction(&LLVMF);
4760   auto *Ptr = F->getArg(0);
4761   auto *Arg = F->getArg(1);
4762   auto *BB = &*F->begin();
4763   auto It = BB->begin();
4764   auto *RMW = cast<sandboxir::AtomicRMWInst>(&*It++);
4765   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
4766 
4767   // Check getOperationName().
4768   EXPECT_EQ(
4769       sandboxir::AtomicRMWInst::getOperationName(
4770           sandboxir::AtomicRMWInst::BinOp::Add),
4771       llvm::AtomicRMWInst::getOperationName(llvm::AtomicRMWInst::BinOp::Add));
4772   // Check isFPOperation().
4773   EXPECT_EQ(
4774       sandboxir::AtomicRMWInst::isFPOperation(
4775           sandboxir::AtomicRMWInst::BinOp::Add),
4776       llvm::AtomicRMWInst::isFPOperation(llvm::AtomicRMWInst::BinOp::Add));
4777   EXPECT_FALSE(sandboxir::AtomicRMWInst::isFPOperation(
4778       sandboxir::AtomicRMWInst::BinOp::Add));
4779   EXPECT_TRUE(sandboxir::AtomicRMWInst::isFPOperation(
4780       sandboxir::AtomicRMWInst::BinOp::FAdd));
4781   // Check setOperation(), getOperation().
4782   EXPECT_EQ(RMW->getOperation(), LLVMRMW->getOperation());
4783   RMW->setOperation(sandboxir::AtomicRMWInst::BinOp::Sub);
4784   EXPECT_EQ(RMW->getOperation(), sandboxir::AtomicRMWInst::BinOp::Sub);
4785   RMW->setOperation(sandboxir::AtomicRMWInst::BinOp::Add);
4786   // Check getAlign().
4787   EXPECT_EQ(RMW->getAlign(), LLVMRMW->getAlign());
4788   auto OrigAlign = RMW->getAlign();
4789   Align NewAlign(256);
4790   EXPECT_NE(NewAlign, OrigAlign);
4791   RMW->setAlignment(NewAlign);
4792   EXPECT_EQ(RMW->getAlign(), NewAlign);
4793   RMW->setAlignment(OrigAlign);
4794   EXPECT_EQ(RMW->getAlign(), OrigAlign);
4795   // Check isVolatile(), setVolatile().
4796   EXPECT_EQ(RMW->isVolatile(), LLVMRMW->isVolatile());
4797   bool OrigV = RMW->isVolatile();
4798   bool NewV = true;
4799   EXPECT_NE(NewV, OrigV);
4800   RMW->setVolatile(NewV);
4801   EXPECT_EQ(RMW->isVolatile(), NewV);
4802   RMW->setVolatile(OrigV);
4803   EXPECT_EQ(RMW->isVolatile(), OrigV);
4804   // Check getOrdering(), setOrdering().
4805   EXPECT_EQ(RMW->getOrdering(), LLVMRMW->getOrdering());
4806   auto OldOrdering = RMW->getOrdering();
4807   auto NewOrdering = AtomicOrdering::Monotonic;
4808   EXPECT_NE(NewOrdering, OldOrdering);
4809   RMW->setOrdering(NewOrdering);
4810   EXPECT_EQ(RMW->getOrdering(), NewOrdering);
4811   RMW->setOrdering(OldOrdering);
4812   EXPECT_EQ(RMW->getOrdering(), OldOrdering);
4813   // Check getSyncScopeID(), setSyncScopeID().
4814   EXPECT_EQ(RMW->getSyncScopeID(), LLVMRMW->getSyncScopeID());
4815   auto OrigSSID = RMW->getSyncScopeID();
4816   SyncScope::ID NewSSID = SyncScope::SingleThread;
4817   EXPECT_NE(NewSSID, OrigSSID);
4818   RMW->setSyncScopeID(NewSSID);
4819   EXPECT_EQ(RMW->getSyncScopeID(), NewSSID);
4820   RMW->setSyncScopeID(OrigSSID);
4821   EXPECT_EQ(RMW->getSyncScopeID(), OrigSSID);
4822   // Check getPointerOperand().
4823   EXPECT_EQ(RMW->getPointerOperand(),
4824             Ctx.getValue(LLVMRMW->getPointerOperand()));
4825   // Check getValOperand().
4826   EXPECT_EQ(RMW->getValOperand(), Ctx.getValue(LLVMRMW->getValOperand()));
4827   // Check getPointerAddressSpace().
4828   EXPECT_EQ(RMW->getPointerAddressSpace(), LLVMRMW->getPointerAddressSpace());
4829   // Check isFloatingPointOperation().
4830   EXPECT_EQ(RMW->isFloatingPointOperation(),
4831             LLVMRMW->isFloatingPointOperation());
4832 
4833   Align Align(1024);
4834   auto Ordering = AtomicOrdering::Acquire;
4835   auto SSID = SyncScope::System;
4836   {
4837     // Check create() WhereIt, WhereBB.
4838     auto *NewI =
4839         cast<sandboxir::AtomicRMWInst>(sandboxir::AtomicRMWInst::create(
4840             sandboxir::AtomicRMWInst::BinOp::Sub, Ptr, Arg, Align, Ordering,
4841             /*WhereIt=*/Ret->getIterator(),
4842             /*WhereBB=*/Ret->getParent(), Ctx, SSID, "NewAtomicRMW1"));
4843     // Check getOpcode().
4844     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicRMW);
4845     // Check getAlign().
4846     EXPECT_EQ(NewI->getAlign(), Align);
4847     // Check getSuccessOrdering().
4848     EXPECT_EQ(NewI->getOrdering(), Ordering);
4849     // Check instr position.
4850     EXPECT_EQ(NewI->getNextNode(), Ret);
4851     // Check getPointerOperand().
4852     EXPECT_EQ(NewI->getPointerOperand(), Ptr);
4853     // Check getValOperand().
4854     EXPECT_EQ(NewI->getValOperand(), Arg);
4855 #ifndef NDEBUG
4856     // Check getName().
4857     EXPECT_EQ(NewI->getName(), "NewAtomicRMW1");
4858 #endif // NDEBUG
4859   }
4860   {
4861     // Check create() InsertBefore.
4862     auto *NewI =
4863         cast<sandboxir::AtomicRMWInst>(sandboxir::AtomicRMWInst::create(
4864             sandboxir::AtomicRMWInst::BinOp::Sub, Ptr, Arg, Align, Ordering,
4865             /*InsertBefore=*/Ret, Ctx, SSID, "NewAtomicRMW2"));
4866     // Check getOpcode().
4867     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicRMW);
4868     // Check getAlign().
4869     EXPECT_EQ(NewI->getAlign(), Align);
4870     // Check getSuccessOrdering().
4871     EXPECT_EQ(NewI->getOrdering(), Ordering);
4872     // Check instr position.
4873     EXPECT_EQ(NewI->getNextNode(), Ret);
4874     // Check getPointerOperand().
4875     EXPECT_EQ(NewI->getPointerOperand(), Ptr);
4876     // Check getValOperand().
4877     EXPECT_EQ(NewI->getValOperand(), Arg);
4878 #ifndef NDEBUG
4879     // Check getName().
4880     EXPECT_EQ(NewI->getName(), "NewAtomicRMW2");
4881 #endif // NDEBUG
4882   }
4883   {
4884     // Check create() InsertAtEnd.
4885     auto *NewI =
4886         cast<sandboxir::AtomicRMWInst>(sandboxir::AtomicRMWInst::create(
4887             sandboxir::AtomicRMWInst::BinOp::Sub, Ptr, Arg, Align, Ordering,
4888             /*InsertAtEnd=*/BB, Ctx, SSID, "NewAtomicRMW3"));
4889     // Check getOpcode().
4890     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicRMW);
4891     // Check getAlign().
4892     EXPECT_EQ(NewI->getAlign(), Align);
4893     // Check getSuccessOrdering().
4894     EXPECT_EQ(NewI->getOrdering(), Ordering);
4895     // Check instr position.
4896     EXPECT_EQ(NewI->getParent(), BB);
4897     EXPECT_EQ(NewI->getNextNode(), nullptr);
4898     // Check getPointerOperand().
4899     EXPECT_EQ(NewI->getPointerOperand(), Ptr);
4900     // Check getValOperand().
4901     EXPECT_EQ(NewI->getValOperand(), Arg);
4902 #ifndef NDEBUG
4903     // Check getName().
4904     EXPECT_EQ(NewI->getName(), "NewAtomicRMW3");
4905 #endif // NDEBUG
4906   }
4907 }
4908 
4909 TEST_F(SandboxIRTest, AtomicCmpXchgInst) {
4910   parseIR(C, R"IR(
4911 define void @foo(ptr %ptr, i8 %cmp, i8 %new) {
4912   %cmpxchg = cmpxchg ptr %ptr, i8 %cmp, i8 %new monotonic monotonic, align 128
4913   ret void
4914 }
4915 )IR");
4916   llvm::Function &LLVMF = *M->getFunction("foo");
4917   llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
4918   auto LLVMIt = LLVMBB->begin();
4919   auto *LLVMCmpXchg = cast<llvm::AtomicCmpXchgInst>(&*LLVMIt++);
4920 
4921   sandboxir::Context Ctx(C);
4922   sandboxir::Function *F = Ctx.createFunction(&LLVMF);
4923   auto *Ptr = F->getArg(0);
4924   auto *Cmp = F->getArg(1);
4925   auto *New = F->getArg(2);
4926   auto *BB = &*F->begin();
4927   auto It = BB->begin();
4928   auto *CmpXchg = cast<sandboxir::AtomicCmpXchgInst>(&*It++);
4929   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
4930 
4931   // Check getAlign(), setAlignment().
4932   EXPECT_EQ(CmpXchg->getAlign(), LLVMCmpXchg->getAlign());
4933   auto OrigAlign = CmpXchg->getAlign();
4934   Align NewAlign(256);
4935   EXPECT_NE(NewAlign, OrigAlign);
4936   CmpXchg->setAlignment(NewAlign);
4937   EXPECT_EQ(CmpXchg->getAlign(), NewAlign);
4938   CmpXchg->setAlignment(OrigAlign);
4939   EXPECT_EQ(CmpXchg->getAlign(), OrigAlign);
4940   // Check isVolatile(), setVolatile().
4941   EXPECT_EQ(CmpXchg->isVolatile(), LLVMCmpXchg->isVolatile());
4942   bool OrigV = CmpXchg->isVolatile();
4943   bool NewV = true;
4944   EXPECT_NE(NewV, OrigV);
4945   CmpXchg->setVolatile(NewV);
4946   EXPECT_EQ(CmpXchg->isVolatile(), NewV);
4947   CmpXchg->setVolatile(OrigV);
4948   EXPECT_EQ(CmpXchg->isVolatile(), OrigV);
4949   // Check isWeak(), setWeak().
4950   EXPECT_EQ(CmpXchg->isWeak(), LLVMCmpXchg->isWeak());
4951   bool OrigWeak = CmpXchg->isWeak();
4952   bool NewWeak = true;
4953   EXPECT_NE(NewWeak, OrigWeak);
4954   CmpXchg->setWeak(NewWeak);
4955   EXPECT_EQ(CmpXchg->isWeak(), NewWeak);
4956   CmpXchg->setWeak(OrigWeak);
4957   EXPECT_EQ(CmpXchg->isWeak(), OrigWeak);
4958   // Check isValidSuccessOrdering(), isValidFailureOrdering().
4959   SmallVector<AtomicOrdering> AllOrderings(
4960       {AtomicOrdering::NotAtomic, AtomicOrdering::Unordered,
4961        AtomicOrdering::Monotonic, AtomicOrdering::Acquire,
4962        AtomicOrdering::Release, AtomicOrdering::AcquireRelease,
4963        AtomicOrdering::SequentiallyConsistent});
4964   for (auto Ordering : AllOrderings) {
4965     EXPECT_EQ(sandboxir::AtomicCmpXchgInst::isValidSuccessOrdering(Ordering),
4966               llvm::AtomicCmpXchgInst::isValidSuccessOrdering(Ordering));
4967     EXPECT_EQ(sandboxir::AtomicCmpXchgInst::isValidFailureOrdering(Ordering),
4968               llvm::AtomicCmpXchgInst::isValidFailureOrdering(Ordering));
4969   }
4970   // Check getSuccessOrdering(), setSuccessOrdering().
4971   EXPECT_EQ(CmpXchg->getSuccessOrdering(), LLVMCmpXchg->getSuccessOrdering());
4972   auto OldSuccOrdering = CmpXchg->getSuccessOrdering();
4973   auto NewSuccOrdering = AtomicOrdering::Acquire;
4974   EXPECT_NE(NewSuccOrdering, OldSuccOrdering);
4975   CmpXchg->setSuccessOrdering(NewSuccOrdering);
4976   EXPECT_EQ(CmpXchg->getSuccessOrdering(), NewSuccOrdering);
4977   CmpXchg->setSuccessOrdering(OldSuccOrdering);
4978   EXPECT_EQ(CmpXchg->getSuccessOrdering(), OldSuccOrdering);
4979   // Check getFailureOrdering(), setFailureOrdering().
4980   EXPECT_EQ(CmpXchg->getFailureOrdering(), LLVMCmpXchg->getFailureOrdering());
4981   auto OldFailOrdering = CmpXchg->getFailureOrdering();
4982   auto NewFailOrdering = AtomicOrdering::Acquire;
4983   EXPECT_NE(NewFailOrdering, OldFailOrdering);
4984   CmpXchg->setFailureOrdering(NewFailOrdering);
4985   EXPECT_EQ(CmpXchg->getFailureOrdering(), NewFailOrdering);
4986   CmpXchg->setFailureOrdering(OldFailOrdering);
4987   EXPECT_EQ(CmpXchg->getFailureOrdering(), OldFailOrdering);
4988   // Check getMergedOrdering().
4989   EXPECT_EQ(CmpXchg->getMergedOrdering(), LLVMCmpXchg->getMergedOrdering());
4990   // Check getSyncScopeID(), setSyncScopeID().
4991   EXPECT_EQ(CmpXchg->getSyncScopeID(), LLVMCmpXchg->getSyncScopeID());
4992   auto OrigSSID = CmpXchg->getSyncScopeID();
4993   SyncScope::ID NewSSID = SyncScope::SingleThread;
4994   EXPECT_NE(NewSSID, OrigSSID);
4995   CmpXchg->setSyncScopeID(NewSSID);
4996   EXPECT_EQ(CmpXchg->getSyncScopeID(), NewSSID);
4997   CmpXchg->setSyncScopeID(OrigSSID);
4998   EXPECT_EQ(CmpXchg->getSyncScopeID(), OrigSSID);
4999   // Check getPointerOperand().
5000   EXPECT_EQ(CmpXchg->getPointerOperand(),
5001             Ctx.getValue(LLVMCmpXchg->getPointerOperand()));
5002   // Check getCompareOperand().
5003   EXPECT_EQ(CmpXchg->getCompareOperand(),
5004             Ctx.getValue(LLVMCmpXchg->getCompareOperand()));
5005   // Check getNewValOperand().
5006   EXPECT_EQ(CmpXchg->getNewValOperand(),
5007             Ctx.getValue(LLVMCmpXchg->getNewValOperand()));
5008   // Check getPointerAddressSpace().
5009   EXPECT_EQ(CmpXchg->getPointerAddressSpace(),
5010             LLVMCmpXchg->getPointerAddressSpace());
5011 
5012   Align Align(1024);
5013   auto SuccOrdering = AtomicOrdering::Acquire;
5014   auto FailOrdering = AtomicOrdering::Monotonic;
5015   auto SSID = SyncScope::System;
5016   {
5017     // Check create() WhereIt, WhereBB.
5018     auto *NewI =
5019         cast<sandboxir::AtomicCmpXchgInst>(sandboxir::AtomicCmpXchgInst::create(
5020             Ptr, Cmp, New, Align, SuccOrdering, FailOrdering,
5021             /*WhereIt=*/Ret->getIterator(),
5022             /*WhereBB=*/Ret->getParent(), Ctx, SSID, "NewAtomicCmpXchg1"));
5023     // Check getOpcode().
5024     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicCmpXchg);
5025     // Check getAlign().
5026     EXPECT_EQ(NewI->getAlign(), Align);
5027     // Check getSuccessOrdering().
5028     EXPECT_EQ(NewI->getSuccessOrdering(), SuccOrdering);
5029     // Check getFailureOrdering().
5030     EXPECT_EQ(NewI->getFailureOrdering(), FailOrdering);
5031     // Check instr position.
5032     EXPECT_EQ(NewI->getNextNode(), Ret);
5033     // Check getPointerOperand().
5034     EXPECT_EQ(NewI->getPointerOperand(), Ptr);
5035     // Check getCompareOperand().
5036     EXPECT_EQ(NewI->getCompareOperand(), Cmp);
5037     // Check getNewValOperand().
5038     EXPECT_EQ(NewI->getNewValOperand(), New);
5039 #ifndef NDEBUG
5040     // Check getName().
5041     EXPECT_EQ(NewI->getName(), "NewAtomicCmpXchg1");
5042 #endif // NDEBUG
5043   }
5044   {
5045     // Check create() InsertBefore.
5046     auto *NewI =
5047         cast<sandboxir::AtomicCmpXchgInst>(sandboxir::AtomicCmpXchgInst::create(
5048             Ptr, Cmp, New, Align, SuccOrdering, FailOrdering,
5049             /*InsertBefore=*/Ret, Ctx, SSID, "NewAtomicCmpXchg2"));
5050     // Check getOpcode().
5051     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicCmpXchg);
5052     // Check getAlign().
5053     EXPECT_EQ(NewI->getAlign(), Align);
5054     // Check getSuccessOrdering().
5055     EXPECT_EQ(NewI->getSuccessOrdering(), SuccOrdering);
5056     // Check getFailureOrdering().
5057     EXPECT_EQ(NewI->getFailureOrdering(), FailOrdering);
5058     // Check instr position.
5059     EXPECT_EQ(NewI->getNextNode(), Ret);
5060     // Check getPointerOperand().
5061     EXPECT_EQ(NewI->getPointerOperand(), Ptr);
5062     // Check getCompareOperand().
5063     EXPECT_EQ(NewI->getCompareOperand(), Cmp);
5064     // Check getNewValOperand().
5065     EXPECT_EQ(NewI->getNewValOperand(), New);
5066 #ifndef NDEBUG
5067     // Check getName().
5068     EXPECT_EQ(NewI->getName(), "NewAtomicCmpXchg2");
5069 #endif // NDEBUG
5070   }
5071   {
5072     // Check create() InsertAtEnd.
5073     auto *NewI =
5074         cast<sandboxir::AtomicCmpXchgInst>(sandboxir::AtomicCmpXchgInst::create(
5075             Ptr, Cmp, New, Align, SuccOrdering, FailOrdering,
5076             /*InsertAtEnd=*/BB, Ctx, SSID, "NewAtomicCmpXchg3"));
5077     // Check getOpcode().
5078     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicCmpXchg);
5079     // Check getAlign().
5080     EXPECT_EQ(NewI->getAlign(), Align);
5081     // Check getSuccessOrdering().
5082     EXPECT_EQ(NewI->getSuccessOrdering(), SuccOrdering);
5083     // Check getFailureOrdering().
5084     EXPECT_EQ(NewI->getFailureOrdering(), FailOrdering);
5085     // Check instr position.
5086     EXPECT_EQ(NewI->getParent(), BB);
5087     EXPECT_EQ(NewI->getNextNode(), nullptr);
5088     // Check getPointerOperand().
5089     EXPECT_EQ(NewI->getPointerOperand(), Ptr);
5090     // Check getCompareOperand().
5091     EXPECT_EQ(NewI->getCompareOperand(), Cmp);
5092     // Check getNewValOperand().
5093     EXPECT_EQ(NewI->getNewValOperand(), New);
5094 #ifndef NDEBUG
5095     // Check getName().
5096     EXPECT_EQ(NewI->getName(), "NewAtomicCmpXchg3");
5097 #endif // NDEBUG
5098   }
5099 }
5100 
5101 TEST_F(SandboxIRTest, AllocaInst) {
5102   parseIR(C, R"IR(
5103 define void @foo() {
5104   %allocaScalar = alloca i32, align 1024
5105   %allocaArray = alloca i32, i32 42
5106   ret void
5107 }
5108 )IR");
5109   const DataLayout &DL = M->getDataLayout();
5110   llvm::Function &LLVMF = *M->getFunction("foo");
5111   llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
5112   auto LLVMIt = LLVMBB->begin();
5113   auto *LLVMAllocaScalar = cast<llvm::AllocaInst>(&*LLVMIt++);
5114   auto *LLVMAllocaArray = cast<llvm::AllocaInst>(&*LLVMIt++);
5115 
5116   sandboxir::Context Ctx(C);
5117   sandboxir::Function *F = Ctx.createFunction(&LLVMF);
5118   auto *BB = &*F->begin();
5119   auto It = BB->begin();
5120   auto *AllocaScalar = cast<sandboxir::AllocaInst>(&*It++);
5121   auto *AllocaArray = cast<sandboxir::AllocaInst>(&*It++);
5122   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
5123 
5124   // Check isArrayAllocation().
5125   EXPECT_EQ(AllocaScalar->isArrayAllocation(),
5126             LLVMAllocaScalar->isArrayAllocation());
5127   EXPECT_EQ(AllocaArray->isArrayAllocation(),
5128             LLVMAllocaArray->isArrayAllocation());
5129   // Check getArraySize().
5130   EXPECT_EQ(AllocaScalar->getArraySize(),
5131             Ctx.getValue(LLVMAllocaScalar->getArraySize()));
5132   EXPECT_EQ(AllocaArray->getArraySize(),
5133             Ctx.getValue(LLVMAllocaArray->getArraySize()));
5134   // Check getType().
5135   EXPECT_EQ(AllocaScalar->getType(), Ctx.getType(LLVMAllocaScalar->getType()));
5136   EXPECT_EQ(AllocaArray->getType(), Ctx.getType(LLVMAllocaArray->getType()));
5137   // Check getAddressSpace().
5138   EXPECT_EQ(AllocaScalar->getAddressSpace(),
5139             LLVMAllocaScalar->getAddressSpace());
5140   EXPECT_EQ(AllocaArray->getAddressSpace(), LLVMAllocaArray->getAddressSpace());
5141   // Check getAllocationSize().
5142   EXPECT_EQ(AllocaScalar->getAllocationSize(DL),
5143             LLVMAllocaScalar->getAllocationSize(DL));
5144   EXPECT_EQ(AllocaArray->getAllocationSize(DL),
5145             LLVMAllocaArray->getAllocationSize(DL));
5146   // Check getAllocationSizeInBits().
5147   EXPECT_EQ(AllocaScalar->getAllocationSizeInBits(DL),
5148             LLVMAllocaScalar->getAllocationSizeInBits(DL));
5149   EXPECT_EQ(AllocaArray->getAllocationSizeInBits(DL),
5150             LLVMAllocaArray->getAllocationSizeInBits(DL));
5151   // Check getAllocatedType().
5152   EXPECT_EQ(AllocaScalar->getAllocatedType(),
5153             Ctx.getType(LLVMAllocaScalar->getAllocatedType()));
5154   EXPECT_EQ(AllocaArray->getAllocatedType(),
5155             Ctx.getType(LLVMAllocaArray->getAllocatedType()));
5156   // Check setAllocatedType().
5157   auto *OrigType = AllocaScalar->getAllocatedType();
5158   auto *NewType = sandboxir::PointerType::get(Ctx, 0);
5159   EXPECT_NE(NewType, OrigType);
5160   AllocaScalar->setAllocatedType(NewType);
5161   EXPECT_EQ(AllocaScalar->getAllocatedType(), NewType);
5162   AllocaScalar->setAllocatedType(OrigType);
5163   EXPECT_EQ(AllocaScalar->getAllocatedType(), OrigType);
5164   // Check getAlign().
5165   EXPECT_EQ(AllocaScalar->getAlign(), LLVMAllocaScalar->getAlign());
5166   EXPECT_EQ(AllocaArray->getAlign(), LLVMAllocaArray->getAlign());
5167   // Check setAlignment().
5168   Align OrigAlign = AllocaScalar->getAlign();
5169   Align NewAlign(16);
5170   EXPECT_NE(NewAlign, OrigAlign);
5171   AllocaScalar->setAlignment(NewAlign);
5172   EXPECT_EQ(AllocaScalar->getAlign(), NewAlign);
5173   AllocaScalar->setAlignment(OrigAlign);
5174   EXPECT_EQ(AllocaScalar->getAlign(), OrigAlign);
5175   // Check isStaticAlloca().
5176   EXPECT_EQ(AllocaScalar->isStaticAlloca(), LLVMAllocaScalar->isStaticAlloca());
5177   EXPECT_EQ(AllocaArray->isStaticAlloca(), LLVMAllocaArray->isStaticAlloca());
5178   // Check isUsedWithInAlloca(), setUsedWithInAlloca().
5179   EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(),
5180             LLVMAllocaScalar->isUsedWithInAlloca());
5181   bool OrigUsedWithInAlloca = AllocaScalar->isUsedWithInAlloca();
5182   bool NewUsedWithInAlloca = true;
5183   EXPECT_NE(NewUsedWithInAlloca, OrigUsedWithInAlloca);
5184   AllocaScalar->setUsedWithInAlloca(NewUsedWithInAlloca);
5185   EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(), NewUsedWithInAlloca);
5186   AllocaScalar->setUsedWithInAlloca(OrigUsedWithInAlloca);
5187   EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(), OrigUsedWithInAlloca);
5188 
5189   auto *Ty = sandboxir::Type::getInt32Ty(Ctx);
5190   unsigned AddrSpace = 42;
5191   auto *PtrTy = sandboxir::PointerType::get(Ctx, AddrSpace);
5192   auto *ArraySize = sandboxir::ConstantInt::get(Ty, 43);
5193   {
5194     // Check create() WhereIt, WhereBB.
5195     auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create(
5196         Ty, AddrSpace, /*WhereIt=*/Ret->getIterator(),
5197         /*WhereBB=*/Ret->getParent(), Ctx, ArraySize, "NewAlloca1"));
5198     // Check getOpcode().
5199     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca);
5200     // Check getType().
5201     EXPECT_EQ(NewI->getType(), PtrTy);
5202     // Check getArraySize().
5203     EXPECT_EQ(NewI->getArraySize(), ArraySize);
5204     // Check getAddrSpace().
5205     EXPECT_EQ(NewI->getAddressSpace(), AddrSpace);
5206     // Check instr position.
5207     EXPECT_EQ(NewI->getNextNode(), Ret);
5208   }
5209   {
5210     // Check create() InsertBefore.
5211     auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create(
5212         Ty, AddrSpace, /*InsertBefore=*/Ret, Ctx, ArraySize, "NewAlloca2"));
5213     // Check getOpcode().
5214     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca);
5215     // Check getType().
5216     EXPECT_EQ(NewI->getType(), PtrTy);
5217     // Check getArraySize().
5218     EXPECT_EQ(NewI->getArraySize(), ArraySize);
5219     // Check getAddrSpace().
5220     EXPECT_EQ(NewI->getAddressSpace(), AddrSpace);
5221     // Check instr position.
5222     EXPECT_EQ(NewI->getNextNode(), Ret);
5223   }
5224   {
5225     // Check create() InsertAtEnd.
5226     auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create(
5227         Ty, AddrSpace, /*InsertAtEnd=*/BB, Ctx, ArraySize, "NewAlloca3"));
5228     // Check getOpcode().
5229     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca);
5230     // Check getType().
5231     EXPECT_EQ(NewI->getType(), PtrTy);
5232     // Check getArraySize().
5233     EXPECT_EQ(NewI->getArraySize(), ArraySize);
5234     // Check getAddrSpace().
5235     EXPECT_EQ(NewI->getAddressSpace(), AddrSpace);
5236     // Check instr position.
5237     EXPECT_EQ(NewI->getParent(), BB);
5238     EXPECT_EQ(NewI->getNextNode(), nullptr);
5239   }
5240 }
5241 
5242 TEST_F(SandboxIRTest, CastInst) {
5243   parseIR(C, R"IR(
5244 define void @foo(i32 %arg, float %farg, double %darg, ptr %ptr) {
5245   %zext = zext i32 %arg to i64
5246   %sext = sext i32 %arg to i64
5247   %fptoui = fptoui float %farg to i32
5248   %fptosi = fptosi float %farg to i32
5249   %fpext = fpext float %farg to double
5250   %ptrtoint = ptrtoint ptr %ptr to i32
5251   %inttoptr = inttoptr i32 %arg to ptr
5252   %sitofp = sitofp i32 %arg to float
5253   %uitofp = uitofp i32 %arg to float
5254   %trunc = trunc i32 %arg to i16
5255   %fptrunc = fptrunc double %darg to float
5256   %bitcast = bitcast i32 %arg to float
5257   %addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1)
5258   ret void
5259 }
5260 )IR");
5261   Function &LLVMF = *M->getFunction("foo");
5262   sandboxir::Context Ctx(C);
5263   sandboxir::Function *F = Ctx.createFunction(&LLVMF);
5264   unsigned ArgIdx = 0;
5265   auto *Arg = F->getArg(ArgIdx++);
5266   auto *BB = &*F->begin();
5267   auto It = BB->begin();
5268 
5269   auto *Ti64 = sandboxir::Type::getInt64Ty(Ctx);
5270   auto *Ti32 = sandboxir::Type::getInt32Ty(Ctx);
5271   auto *Ti16 = sandboxir::Type::getInt16Ty(Ctx);
5272   auto *Tdouble = sandboxir::Type::getDoubleTy(Ctx);
5273   auto *Tfloat = sandboxir::Type::getFloatTy(Ctx);
5274   auto *Tptr = sandboxir::PointerType::get(Tfloat, 0);
5275   auto *Tptr1 = sandboxir::PointerType::get(Tfloat, 1);
5276 
5277   // Check classof(), getOpcode(), getSrcTy(), getDstTy()
5278   auto *ZExt = cast<sandboxir::CastInst>(&*It++);
5279   auto *ZExtI = cast<sandboxir::ZExtInst>(ZExt);
5280   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(ZExtI));
5281   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(ZExtI));
5282   EXPECT_EQ(ZExt->getOpcode(), sandboxir::Instruction::Opcode::ZExt);
5283   EXPECT_EQ(ZExt->getSrcTy(), Ti32);
5284   EXPECT_EQ(ZExt->getDestTy(), Ti64);
5285 
5286   auto *SExt = cast<sandboxir::CastInst>(&*It++);
5287   auto *SExtI = cast<sandboxir::SExtInst>(SExt);
5288   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SExt));
5289   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SExtI));
5290   EXPECT_EQ(SExt->getOpcode(), sandboxir::Instruction::Opcode::SExt);
5291   EXPECT_EQ(SExt->getSrcTy(), Ti32);
5292   EXPECT_EQ(SExt->getDestTy(), Ti64);
5293 
5294   auto *FPToUI = cast<sandboxir::CastInst>(&*It++);
5295   auto *FPToUII = cast<sandboxir::FPToUIInst>(FPToUI);
5296   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToUI));
5297   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToUII));
5298   EXPECT_EQ(FPToUI->getOpcode(), sandboxir::Instruction::Opcode::FPToUI);
5299   EXPECT_EQ(FPToUI->getSrcTy(), Tfloat);
5300   EXPECT_EQ(FPToUI->getDestTy(), Ti32);
5301 
5302   auto *FPToSI = cast<sandboxir::CastInst>(&*It++);
5303   auto *FPToSII = cast<sandboxir::FPToSIInst>(FPToSI);
5304   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToSI));
5305   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToSII));
5306   EXPECT_EQ(FPToSI->getOpcode(), sandboxir::Instruction::Opcode::FPToSI);
5307   EXPECT_EQ(FPToSI->getSrcTy(), Tfloat);
5308   EXPECT_EQ(FPToSI->getDestTy(), Ti32);
5309 
5310   auto *FPExt = cast<sandboxir::CastInst>(&*It++);
5311   auto *FPExtI = cast<sandboxir::FPExtInst>(FPExt);
5312   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPExt));
5313   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPExtI));
5314   EXPECT_EQ(FPExt->getOpcode(), sandboxir::Instruction::Opcode::FPExt);
5315   EXPECT_EQ(FPExt->getSrcTy(), Tfloat);
5316   EXPECT_EQ(FPExt->getDestTy(), Tdouble);
5317 
5318   auto *PtrToInt = cast<sandboxir::CastInst>(&*It++);
5319   auto *PtrToIntI = cast<sandboxir::PtrToIntInst>(PtrToInt);
5320   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(PtrToInt));
5321   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(PtrToIntI));
5322   EXPECT_EQ(PtrToInt->getOpcode(), sandboxir::Instruction::Opcode::PtrToInt);
5323   EXPECT_EQ(PtrToInt->getSrcTy(), Tptr);
5324   EXPECT_EQ(PtrToInt->getDestTy(), Ti32);
5325 
5326   auto *IntToPtr = cast<sandboxir::CastInst>(&*It++);
5327   auto *IntToPtrI = cast<sandboxir::IntToPtrInst>(IntToPtr);
5328   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(IntToPtr));
5329   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(IntToPtrI));
5330   EXPECT_EQ(IntToPtr->getOpcode(), sandboxir::Instruction::Opcode::IntToPtr);
5331   EXPECT_EQ(IntToPtr->getSrcTy(), Ti32);
5332   EXPECT_EQ(IntToPtr->getDestTy(), Tptr);
5333 
5334   auto *SIToFP = cast<sandboxir::CastInst>(&*It++);
5335   auto *SIToFPI = cast<sandboxir::SIToFPInst>(SIToFP);
5336   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SIToFP));
5337   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SIToFPI));
5338   EXPECT_EQ(SIToFP->getOpcode(), sandboxir::Instruction::Opcode::SIToFP);
5339   EXPECT_EQ(SIToFP->getSrcTy(), Ti32);
5340   EXPECT_EQ(SIToFP->getDestTy(), Tfloat);
5341 
5342   auto *UIToFP = cast<sandboxir::CastInst>(&*It++);
5343   auto *UIToFPI = cast<sandboxir::UIToFPInst>(UIToFP);
5344   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(UIToFP));
5345   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(UIToFPI));
5346   EXPECT_EQ(UIToFP->getOpcode(), sandboxir::Instruction::Opcode::UIToFP);
5347   EXPECT_EQ(UIToFP->getSrcTy(), Ti32);
5348   EXPECT_EQ(UIToFP->getDestTy(), Tfloat);
5349 
5350   auto *Trunc = cast<sandboxir::CastInst>(&*It++);
5351   auto *TruncI = cast<sandboxir::TruncInst>(Trunc);
5352   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Trunc));
5353   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(TruncI));
5354   EXPECT_EQ(Trunc->getOpcode(), sandboxir::Instruction::Opcode::Trunc);
5355   EXPECT_EQ(Trunc->getSrcTy(), Ti32);
5356   EXPECT_EQ(Trunc->getDestTy(), Ti16);
5357 
5358   auto *FPTrunc = cast<sandboxir::CastInst>(&*It++);
5359   auto *FPTruncI = cast<sandboxir::FPTruncInst>(FPTrunc);
5360   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPTrunc));
5361   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPTruncI));
5362   EXPECT_EQ(FPTrunc->getOpcode(), sandboxir::Instruction::Opcode::FPTrunc);
5363   EXPECT_EQ(FPTrunc->getSrcTy(), Tdouble);
5364   EXPECT_EQ(FPTrunc->getDestTy(), Tfloat);
5365 
5366   auto *BitCast = cast<sandboxir::CastInst>(&*It++);
5367   auto *BitCastI = cast<sandboxir::BitCastInst>(BitCast);
5368   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(BitCast));
5369   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(BitCastI));
5370   EXPECT_EQ(BitCast->getOpcode(), sandboxir::Instruction::Opcode::BitCast);
5371   EXPECT_EQ(BitCast->getSrcTy(), Ti32);
5372   EXPECT_EQ(BitCast->getDestTy(), Tfloat);
5373 
5374   auto *AddrSpaceCast = cast<sandboxir::CastInst>(&*It++);
5375   auto *AddrSpaceCastI = cast<sandboxir::AddrSpaceCastInst>(AddrSpaceCast);
5376   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(AddrSpaceCast));
5377   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(AddrSpaceCastI));
5378   EXPECT_EQ(AddrSpaceCast->getOpcode(),
5379             sandboxir::Instruction::Opcode::AddrSpaceCast);
5380   EXPECT_EQ(AddrSpaceCast->getSrcTy(), Tptr);
5381   EXPECT_EQ(AddrSpaceCast->getDestTy(), Tptr1);
5382 
5383   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
5384 
5385   {
5386     // Check create() WhereIt, WhereBB
5387     auto *NewI = cast<sandboxir::CastInst>(sandboxir::CastInst::create(
5388         Ti64, sandboxir::Instruction::Opcode::SExt, Arg, /*WhereIt=*/BB->end(),
5389         /*WhereBB=*/BB, Ctx, "SExt"));
5390     // Check getOpcode().
5391     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::SExt);
5392     // Check getSrcTy().
5393     EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
5394     // Check getDestTy().
5395     EXPECT_EQ(NewI->getDestTy(), Ti64);
5396     // Check instr position.
5397     EXPECT_EQ(NewI->getNextNode(), nullptr);
5398     EXPECT_EQ(NewI->getPrevNode(), Ret);
5399   }
5400 
5401   {
5402     // Check create() InsertBefore.
5403     auto *NewI = cast<sandboxir::CastInst>(
5404         sandboxir::CastInst::create(Ti64, sandboxir::Instruction::Opcode::ZExt,
5405                                     Arg, /*InsertBefore=*/Ret, Ctx, "ZExt"));
5406     // Check getOpcode().
5407     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::ZExt);
5408     // Check getSrcTy().
5409     EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
5410     // Check getDestTy().
5411     EXPECT_EQ(NewI->getDestTy(), Ti64);
5412     // Check instr position.
5413     EXPECT_EQ(NewI->getNextNode(), Ret);
5414   }
5415   {
5416     // Check create() InsertAtEnd.
5417     auto *NewI = cast<sandboxir::CastInst>(
5418         sandboxir::CastInst::create(Ti64, sandboxir::Instruction::Opcode::ZExt,
5419                                     Arg, /*InsertAtEnd=*/BB, Ctx, "ZExt"));
5420     // Check getOpcode().
5421     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::ZExt);
5422     // Check getSrcTy().
5423     EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
5424     // Check getDestTy().
5425     EXPECT_EQ(NewI->getDestTy(), Ti64);
5426     // Check instr position.
5427     EXPECT_EQ(NewI->getNextNode(), nullptr);
5428     EXPECT_EQ(NewI->getParent(), BB);
5429   }
5430 
5431   {
5432 #ifndef NDEBUG
5433     // Check that passing a non-cast opcode crashes.
5434     EXPECT_DEATH(
5435         sandboxir::CastInst::create(Ti64, sandboxir::Instruction::Opcode::Store,
5436                                     Arg, /*InsertBefore=*/Ret, Ctx, "Bad"),
5437         ".*Opcode.*");
5438 #endif // NDEBUG
5439   }
5440 }
5441 
5442 TEST_F(SandboxIRTest, PossiblyNonNegInst) {
5443   parseIR(C, R"IR(
5444 define void @foo(i32 %arg, float %farg, double %darg, ptr %ptr) {
5445   %zext = zext i32 %arg to i64
5446   %uitofp = uitofp i32 %arg to float
5447 
5448   %sext = sext i32 %arg to i64
5449   %fptoui = fptoui float %farg to i32
5450   %fptosi = fptosi float %farg to i32
5451   %fpext = fpext float %farg to double
5452   %ptrtoint = ptrtoint ptr %ptr to i32
5453   %inttoptr = inttoptr i32 %arg to ptr
5454   %sitofp = sitofp i32 %arg to float
5455   %trunc = trunc i32 %arg to i16
5456   %fptrunc = fptrunc double %darg to float
5457   %bitcast = bitcast i32 %arg to float
5458   %addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1)
5459   ret void
5460 }
5461 )IR");
5462   Function &LLVMF = *M->getFunction("foo");
5463   sandboxir::Context Ctx(C);
5464   sandboxir::Function *F = Ctx.createFunction(&LLVMF);
5465   auto *BB = &*F->begin();
5466   auto It = BB->begin();
5467   auto *PNNI0 = cast<sandboxir::PossiblyNonNegInst>(&*It++);
5468   auto *PNNI1 = cast<sandboxir::PossiblyNonNegInst>(&*It++);
5469   for (auto ItE = BB->end(); It != ItE; ++It)
5470     EXPECT_FALSE(isa<sandboxir::PossiblyNonNegInst>(&*It++));
5471 
5472   for (auto *PNNI : {PNNI0, PNNI1}) {
5473     // Check setNonNeg(), hasNonNeg().
5474     auto OrigNonNeg = PNNI->hasNonNeg();
5475     auto NewNonNeg = true;
5476     EXPECT_NE(NewNonNeg, OrigNonNeg);
5477     PNNI->setNonNeg(NewNonNeg);
5478     EXPECT_EQ(PNNI->hasNonNeg(), NewNonNeg);
5479     PNNI->setNonNeg(OrigNonNeg);
5480     EXPECT_EQ(PNNI->hasNonNeg(), OrigNonNeg);
5481   }
5482 }
5483 
5484 /// CastInst's subclasses are very similar so we can use a common test function
5485 /// for them.
5486 template <typename SubclassT, sandboxir::Instruction::Opcode OpcodeT>
5487 void testCastInst(llvm::Module &M, llvm::Type *LLVMSrcTy,
5488                   llvm::Type *LLVMDstTy) {
5489   Function &LLVMF = *M.getFunction("foo");
5490   sandboxir::Context Ctx(M.getContext());
5491   sandboxir::Function *F = Ctx.createFunction(&LLVMF);
5492   sandboxir::Type *SrcTy = Ctx.getType(LLVMSrcTy);
5493   sandboxir::Type *DstTy = Ctx.getType(LLVMDstTy);
5494   unsigned ArgIdx = 0;
5495   auto *Arg = F->getArg(ArgIdx++);
5496   auto *BB = &*F->begin();
5497   auto It = BB->begin();
5498 
5499   auto *CI = cast<SubclassT>(&*It++);
5500   EXPECT_EQ(CI->getOpcode(), OpcodeT);
5501   EXPECT_EQ(CI->getSrcTy(), SrcTy);
5502   EXPECT_EQ(CI->getDestTy(), DstTy);
5503   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
5504 
5505   {
5506     // Check create() WhereIt, WhereBB
5507     auto *NewI =
5508         cast<SubclassT>(SubclassT::create(Arg, DstTy, /*WhereIt=*/BB->end(),
5509                                           /*WhereBB=*/BB, Ctx, "NewCI"));
5510     // Check getOpcode().
5511     EXPECT_EQ(NewI->getOpcode(), OpcodeT);
5512     // Check getSrcTy().
5513     EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
5514     // Check getDestTy().
5515     EXPECT_EQ(NewI->getDestTy(), DstTy);
5516     // Check instr position.
5517     EXPECT_EQ(NewI->getNextNode(), nullptr);
5518     EXPECT_EQ(NewI->getPrevNode(), Ret);
5519     // Check instr name.
5520     EXPECT_EQ(NewI->getName(), "NewCI");
5521   }
5522   {
5523     // Check create() InsertBefore.
5524     auto *NewI =
5525         cast<SubclassT>(SubclassT::create(Arg, DstTy,
5526                                           /*InsertBefore=*/Ret, Ctx, "NewCI"));
5527     // Check getOpcode().
5528     EXPECT_EQ(NewI->getOpcode(), OpcodeT);
5529     // Check getSrcTy().
5530     EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
5531     // Check getDestTy().
5532     EXPECT_EQ(NewI->getDestTy(), DstTy);
5533     // Check instr position.
5534     EXPECT_EQ(NewI->getNextNode(), Ret);
5535   }
5536   {
5537     // Check create() InsertAtEnd.
5538     auto *NewI =
5539         cast<SubclassT>(SubclassT::create(Arg, DstTy,
5540                                           /*InsertAtEnd=*/BB, Ctx, "NewCI"));
5541     // Check getOpcode().
5542     EXPECT_EQ(NewI->getOpcode(), OpcodeT);
5543     // Check getSrcTy().
5544     EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
5545     // Check getDestTy().
5546     EXPECT_EQ(NewI->getDestTy(), DstTy);
5547     // Check instr position.
5548     EXPECT_EQ(NewI->getNextNode(), nullptr);
5549     EXPECT_EQ(NewI->getParent(), BB);
5550   }
5551 }
5552 
5553 TEST_F(SandboxIRTest, TruncInst) {
5554   parseIR(C, R"IR(
5555 define void @foo(i64 %arg) {
5556   %trunc = trunc i64 %arg to i32
5557   ret void
5558 }
5559 )IR");
5560   testCastInst<sandboxir::TruncInst, sandboxir::Instruction::Opcode::Trunc>(
5561       *M,
5562       /*SrcTy=*/Type::getInt64Ty(C), /*DstTy=*/Type::getInt32Ty(C));
5563 }
5564 
5565 TEST_F(SandboxIRTest, ZExtInst) {
5566   parseIR(C, R"IR(
5567 define void @foo(i32 %arg) {
5568   %zext = zext i32 %arg to i64
5569   ret void
5570 }
5571 )IR");
5572   testCastInst<sandboxir::ZExtInst, sandboxir::Instruction::Opcode::ZExt>(
5573       *M,
5574       /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getInt64Ty(C));
5575 }
5576 
5577 TEST_F(SandboxIRTest, SExtInst) {
5578   parseIR(C, R"IR(
5579 define void @foo(i32 %arg) {
5580   %sext = sext i32 %arg to i64
5581   ret void
5582 }
5583 )IR");
5584   testCastInst<sandboxir::SExtInst, sandboxir::Instruction::Opcode::SExt>(
5585       *M,
5586       /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getInt64Ty(C));
5587 }
5588 
5589 TEST_F(SandboxIRTest, FPTruncInst) {
5590   parseIR(C, R"IR(
5591 define void @foo(double %arg) {
5592   %fptrunc = fptrunc double %arg to float
5593   ret void
5594 }
5595 )IR");
5596   testCastInst<sandboxir::FPTruncInst, sandboxir::Instruction::Opcode::FPTrunc>(
5597       *M,
5598       /*SrcTy=*/Type::getDoubleTy(C), /*DstTy=*/Type::getFloatTy(C));
5599 }
5600 
5601 TEST_F(SandboxIRTest, FPExtInst) {
5602   parseIR(C, R"IR(
5603 define void @foo(float %arg) {
5604   %fpext = fpext float %arg to double
5605   ret void
5606 }
5607 )IR");
5608   testCastInst<sandboxir::FPExtInst, sandboxir::Instruction::Opcode::FPExt>(
5609       *M,
5610       /*SrcTy=*/Type::getFloatTy(C), /*DstTy=*/Type::getDoubleTy(C));
5611 }
5612 
5613 TEST_F(SandboxIRTest, UIToFPInst) {
5614   parseIR(C, R"IR(
5615 define void @foo(i32 %arg) {
5616   %uitofp = uitofp i32 %arg to float
5617   ret void
5618 }
5619 )IR");
5620   testCastInst<sandboxir::UIToFPInst, sandboxir::Instruction::Opcode::UIToFP>(
5621       *M,
5622       /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getFloatTy(C));
5623 }
5624 
5625 TEST_F(SandboxIRTest, SIToFPInst) {
5626   parseIR(C, R"IR(
5627 define void @foo(i32 %arg) {
5628   %sitofp = sitofp i32 %arg to float
5629   ret void
5630 }
5631 )IR");
5632   testCastInst<sandboxir::SIToFPInst, sandboxir::Instruction::Opcode::SIToFP>(
5633       *M,
5634       /*SrcTy=*/Type::getInt32Ty(C),
5635       /*DstTy=*/Type::getFloatTy(C));
5636 }
5637 
5638 TEST_F(SandboxIRTest, FPToUIInst) {
5639   parseIR(C, R"IR(
5640 define void @foo(float %arg) {
5641   %fptoui = fptoui float %arg to i32
5642   ret void
5643 }
5644 )IR");
5645   testCastInst<sandboxir::FPToUIInst, sandboxir::Instruction::Opcode::FPToUI>(
5646 
5647       *M, /*SrcTy=*/Type::getFloatTy(C), /*DstTy=*/Type::getInt32Ty(C));
5648 }
5649 
5650 TEST_F(SandboxIRTest, FPToSIInst) {
5651   parseIR(C, R"IR(
5652 define void @foo(float %arg) {
5653   %fptosi = fptosi float %arg to i32
5654   ret void
5655 }
5656 )IR");
5657   testCastInst<sandboxir::FPToSIInst, sandboxir::Instruction::Opcode::FPToSI>(
5658       *M, /*SrcTy=*/Type::getFloatTy(C), /*DstTy=*/Type::getInt32Ty(C));
5659 }
5660 
5661 TEST_F(SandboxIRTest, IntToPtrInst) {
5662   parseIR(C, R"IR(
5663 define void @foo(i32 %arg) {
5664   %inttoptr = inttoptr i32 %arg to ptr
5665   ret void
5666 }
5667 )IR");
5668   testCastInst<sandboxir::IntToPtrInst,
5669                sandboxir::Instruction::Opcode::IntToPtr>(
5670       *M,
5671       /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/PointerType::get(C, 0));
5672 }
5673 
5674 TEST_F(SandboxIRTest, PtrToIntInst) {
5675   parseIR(C, R"IR(
5676 define void @foo(ptr %ptr) {
5677   %ptrtoint = ptrtoint ptr %ptr to i32
5678   ret void
5679 }
5680 )IR");
5681   testCastInst<sandboxir::PtrToIntInst,
5682                sandboxir::Instruction::Opcode::PtrToInt>(
5683       *M, /*SrcTy=*/PointerType::get(C, 0), /*DstTy=*/Type::getInt32Ty(C));
5684 }
5685 
5686 TEST_F(SandboxIRTest, BitCastInst) {
5687   parseIR(C, R"IR(
5688 define void @foo(i32 %arg) {
5689   %bitcast = bitcast i32 %arg to float
5690   ret void
5691 }
5692 )IR");
5693   testCastInst<sandboxir::BitCastInst, sandboxir::Instruction::Opcode::BitCast>(
5694       *M,
5695       /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getFloatTy(C));
5696 }
5697 
5698 TEST_F(SandboxIRTest, AddrSpaceCastInst) {
5699   parseIR(C, R"IR(
5700 define void @foo(ptr %ptr) {
5701   %addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1)
5702   ret void
5703 }
5704 )IR");
5705   Type *Tptr0 = PointerType::get(C, 0);
5706   Type *Tptr1 = PointerType::get(C, 1);
5707   testCastInst<sandboxir::AddrSpaceCastInst,
5708                sandboxir::Instruction::Opcode::AddrSpaceCast>(*M,
5709                                                               /*SrcTy=*/Tptr0,
5710                                                               /*DstTy=*/Tptr1);
5711   Function &LLVMF = *M->getFunction("foo");
5712   sandboxir::Context Ctx(C);
5713   sandboxir::Function *F = Ctx.createFunction(&LLVMF);
5714   unsigned ArgIdx = 0;
5715   auto *Arg = F->getArg(ArgIdx++);
5716   auto *BB = &*F->begin();
5717   auto It = BB->begin();
5718 
5719   auto *AddrSpaceCast = cast<sandboxir::AddrSpaceCastInst>(&*It++);
5720   EXPECT_EQ(AddrSpaceCast->getOpcode(),
5721             sandboxir::Instruction::Opcode::AddrSpaceCast);
5722   EXPECT_EQ(AddrSpaceCast->getPointerOperand(), Arg);
5723   EXPECT_EQ(sandboxir::AddrSpaceCastInst::getPointerOperandIndex(), 0u);
5724   EXPECT_EQ(AddrSpaceCast->getSrcAddressSpace(),
5725             cast<PointerType>(Tptr0)->getPointerAddressSpace());
5726   EXPECT_EQ(AddrSpaceCast->getDestAddressSpace(),
5727             cast<PointerType>(Tptr1)->getPointerAddressSpace());
5728 }
5729 
5730 TEST_F(SandboxIRTest, PHINode) {
5731   parseIR(C, R"IR(
5732 define void @foo(i32 %arg) {
5733 bb1:
5734   br label %bb2
5735 
5736 bb2:
5737   %phi = phi i32 [ %arg, %bb1 ], [ 0, %bb2 ], [ 1, %bb3 ], [ 2, %bb4 ], [ 3, %bb5 ]
5738   br label %bb2
5739 
5740 bb3:
5741   br label %bb2
5742 
5743 bb4:
5744   br label %bb2
5745 
5746 bb5:
5747   br label %bb2
5748   ret void
5749 }
5750 )IR");
5751   Function &LLVMF = *M->getFunction("foo");
5752   auto *LLVMBB1 = getBasicBlockByName(LLVMF, "bb1");
5753   auto *LLVMBB2 = getBasicBlockByName(LLVMF, "bb2");
5754   auto *LLVMBB3 = getBasicBlockByName(LLVMF, "bb3");
5755   auto LLVMIt = LLVMBB2->begin();
5756   auto *LLVMPHI = cast<llvm::PHINode>(&*LLVMIt++);
5757   sandboxir::Context Ctx(C);
5758   sandboxir::Function *F = Ctx.createFunction(&LLVMF);
5759   auto *Arg = F->getArg(0);
5760   auto *BB1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB1));
5761   auto *BB2 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB2));
5762   auto *BB3 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB3));
5763   auto It = BB2->begin();
5764   // Check classof().
5765   auto *PHI = cast<sandboxir::PHINode>(&*It++);
5766   auto *Br = cast<sandboxir::BranchInst>(&*It++);
5767   // Check blocks().
5768   EXPECT_EQ(range_size(PHI->blocks()), range_size(LLVMPHI->blocks()));
5769   auto BlockIt = PHI->block_begin();
5770   for (llvm::BasicBlock *LLVMBB : LLVMPHI->blocks()) {
5771     sandboxir::BasicBlock *BB = *BlockIt++;
5772     EXPECT_EQ(BB, Ctx.getValue(LLVMBB));
5773   }
5774   // Check incoming_values().
5775   EXPECT_EQ(range_size(PHI->incoming_values()),
5776             range_size(LLVMPHI->incoming_values()));
5777   auto IncIt = PHI->incoming_values().begin();
5778   for (llvm::Value *LLVMV : LLVMPHI->incoming_values()) {
5779     sandboxir::Value *IncV = *IncIt++;
5780     EXPECT_EQ(IncV, Ctx.getValue(LLVMV));
5781   }
5782   // Check getNumIncomingValues().
5783   EXPECT_EQ(PHI->getNumIncomingValues(), LLVMPHI->getNumIncomingValues());
5784   // Check getIncomingValue().
5785   EXPECT_EQ(PHI->getIncomingValue(0),
5786             Ctx.getValue(LLVMPHI->getIncomingValue(0)));
5787   EXPECT_EQ(PHI->getIncomingValue(1),
5788             Ctx.getValue(LLVMPHI->getIncomingValue(1)));
5789   // Check setIncomingValue().
5790   auto *OrigV = PHI->getIncomingValue(0);
5791   PHI->setIncomingValue(0, PHI);
5792   EXPECT_EQ(PHI->getIncomingValue(0), PHI);
5793   PHI->setIncomingValue(0, OrigV);
5794   // Check getOperandNumForIncomingValue().
5795   EXPECT_EQ(sandboxir::PHINode::getOperandNumForIncomingValue(0),
5796             llvm::PHINode::getOperandNumForIncomingValue(0));
5797   // Check getIncomingValueNumForOperand().
5798   EXPECT_EQ(sandboxir::PHINode::getIncomingValueNumForOperand(0),
5799             llvm::PHINode::getIncomingValueNumForOperand(0));
5800   // Check getIncomingBlock(unsigned).
5801   EXPECT_EQ(PHI->getIncomingBlock(0),
5802             Ctx.getValue(LLVMPHI->getIncomingBlock(0)));
5803   // Check getIncomingBlock(Use).
5804   llvm::Use &LLVMUse = LLVMPHI->getOperandUse(0);
5805   sandboxir::Use Use = PHI->getOperandUse(0);
5806   EXPECT_EQ(PHI->getIncomingBlock(Use),
5807             Ctx.getValue(LLVMPHI->getIncomingBlock(LLVMUse)));
5808   // Check setIncomingBlock().
5809   sandboxir::BasicBlock *OrigBB = PHI->getIncomingBlock(0);
5810   EXPECT_NE(OrigBB, BB2);
5811   PHI->setIncomingBlock(0, BB2);
5812   EXPECT_EQ(PHI->getIncomingBlock(0), BB2);
5813   PHI->setIncomingBlock(0, OrigBB);
5814   EXPECT_EQ(PHI->getIncomingBlock(0), OrigBB);
5815   // Check addIncoming().
5816   unsigned OrigNumIncoming = PHI->getNumIncomingValues();
5817   PHI->addIncoming(Arg, BB3);
5818   EXPECT_EQ(PHI->getNumIncomingValues(), LLVMPHI->getNumIncomingValues());
5819   EXPECT_EQ(PHI->getNumIncomingValues(), OrigNumIncoming + 1);
5820   EXPECT_EQ(PHI->getIncomingValue(OrigNumIncoming), Arg);
5821   EXPECT_EQ(PHI->getIncomingBlock(OrigNumIncoming), BB3);
5822   // Check removeIncomingValue(unsigned).
5823   PHI->removeIncomingValue(OrigNumIncoming);
5824   EXPECT_EQ(PHI->getNumIncomingValues(), OrigNumIncoming);
5825   // Check removeIncomingValue(BasicBlock *).
5826   PHI->addIncoming(Arg, BB3);
5827   PHI->removeIncomingValue(BB3);
5828   EXPECT_EQ(PHI->getNumIncomingValues(), OrigNumIncoming);
5829   // Check getBasicBlockIndex().
5830   EXPECT_EQ(PHI->getBasicBlockIndex(BB1), LLVMPHI->getBasicBlockIndex(LLVMBB1));
5831   // Check getIncomingValueForBlock().
5832   EXPECT_EQ(PHI->getIncomingValueForBlock(BB1),
5833             Ctx.getValue(LLVMPHI->getIncomingValueForBlock(LLVMBB1)));
5834   // Check hasConstantValue().
5835   llvm::Value *ConstV = LLVMPHI->hasConstantValue();
5836   EXPECT_EQ(PHI->hasConstantValue(),
5837             ConstV != nullptr ? Ctx.getValue(ConstV) : nullptr);
5838   // Check hasConstantOrUndefValue().
5839   EXPECT_EQ(PHI->hasConstantOrUndefValue(), LLVMPHI->hasConstantOrUndefValue());
5840   // Check isComplete().
5841   EXPECT_EQ(PHI->isComplete(), LLVMPHI->isComplete());
5842   // Check replaceIncomingValueIf
5843   EXPECT_EQ(PHI->getNumIncomingValues(), 5u);
5844   auto *RemainBB0 = PHI->getIncomingBlock(0);
5845   auto *RemoveBB0 = PHI->getIncomingBlock(1);
5846   auto *RemainBB1 = PHI->getIncomingBlock(2);
5847   auto *RemoveBB1 = PHI->getIncomingBlock(3);
5848   auto *RemainBB2 = PHI->getIncomingBlock(4);
5849   PHI->removeIncomingValueIf([&](unsigned Idx) {
5850     return PHI->getIncomingBlock(Idx) == RemoveBB0 ||
5851            PHI->getIncomingBlock(Idx) == RemoveBB1;
5852   });
5853   EXPECT_EQ(PHI->getNumIncomingValues(), 3u);
5854   EXPECT_EQ(PHI->getIncomingBlock(0), RemainBB0);
5855   EXPECT_EQ(PHI->getIncomingBlock(1), RemainBB1);
5856   EXPECT_EQ(PHI->getIncomingBlock(2), RemainBB2);
5857   // Check replaceIncomingBlockWith
5858   OrigBB = RemainBB0;
5859   auto *NewBB = RemainBB1;
5860   EXPECT_NE(NewBB, OrigBB);
5861   PHI->replaceIncomingBlockWith(OrigBB, NewBB);
5862   EXPECT_EQ(PHI->getIncomingBlock(0), NewBB);
5863   EXPECT_EQ(PHI->getIncomingBlock(1), RemainBB1);
5864   EXPECT_EQ(PHI->getIncomingBlock(2), RemainBB2);
5865   // Check create().
5866   auto *NewPHI = cast<sandboxir::PHINode>(
5867       sandboxir::PHINode::create(PHI->getType(), 0, Br, Ctx, "NewPHI"));
5868   EXPECT_EQ(NewPHI->getType(), PHI->getType());
5869   EXPECT_EQ(NewPHI->getNextNode(), Br);
5870   EXPECT_EQ(NewPHI->getName(), "NewPHI");
5871   EXPECT_EQ(NewPHI->getNumIncomingValues(), 0u);
5872   for (auto [Idx, V] : enumerate(PHI->incoming_values())) {
5873     sandboxir::BasicBlock *IncBB = PHI->getIncomingBlock(Idx);
5874     NewPHI->addIncoming(V, IncBB);
5875   }
5876   EXPECT_EQ(NewPHI->getNumIncomingValues(), PHI->getNumIncomingValues());
5877 }
5878 
5879 static void checkSwapOperands(sandboxir::Context &Ctx,
5880                               llvm::sandboxir::CmpInst *Cmp,
5881                               llvm::CmpInst *LLVMCmp) {
5882   auto OrigOp0 = Cmp->getOperand(0);
5883   auto OrigOp1 = Cmp->getOperand(1);
5884   EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(0)), OrigOp0);
5885   EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(1)), OrigOp1);
5886   // This checks the dispatch mechanism in CmpInst, as well as
5887   // the specific implementations.
5888   Cmp->swapOperands();
5889   EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(1)), OrigOp0);
5890   EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(0)), OrigOp1);
5891   EXPECT_EQ(Cmp->getOperand(0), OrigOp1);
5892   EXPECT_EQ(Cmp->getOperand(1), OrigOp0);
5893   // Undo it to keep the rest of the test consistent
5894   Cmp->swapOperands();
5895 }
5896 
5897 static void checkCommonPredicates(sandboxir::CmpInst *Cmp,
5898                                   llvm::CmpInst *LLVMCmp) {
5899   // Check proper creation
5900   auto Pred = Cmp->getPredicate();
5901   auto LLVMPred = LLVMCmp->getPredicate();
5902   EXPECT_EQ(Pred, LLVMPred);
5903   // Check setPredicate
5904   Cmp->setPredicate(llvm::CmpInst::FCMP_FALSE);
5905   EXPECT_EQ(Cmp->getPredicate(), llvm::CmpInst::FCMP_FALSE);
5906   EXPECT_EQ(LLVMCmp->getPredicate(), llvm::CmpInst::FCMP_FALSE);
5907   Cmp->setPredicate(Pred);
5908   EXPECT_EQ(LLVMCmp->getPredicate(), Pred);
5909   // Ensure the accessors properly forward to the underlying implementation
5910   EXPECT_STREQ(sandboxir::CmpInst::getPredicateName(Pred).data(),
5911                llvm::CmpInst::getPredicateName(LLVMPred).data());
5912   EXPECT_EQ(Cmp->isFPPredicate(), LLVMCmp->isFPPredicate());
5913   EXPECT_EQ(Cmp->isIntPredicate(), LLVMCmp->isIntPredicate());
5914   EXPECT_EQ(Cmp->getInversePredicate(), LLVMCmp->getInversePredicate());
5915   EXPECT_EQ(Cmp->getOrderedPredicate(), LLVMCmp->getOrderedPredicate());
5916   EXPECT_EQ(Cmp->getUnorderedPredicate(), LLVMCmp->getUnorderedPredicate());
5917   EXPECT_EQ(Cmp->getSwappedPredicate(), LLVMCmp->getSwappedPredicate());
5918   EXPECT_EQ(Cmp->isStrictPredicate(), LLVMCmp->isStrictPredicate());
5919   EXPECT_EQ(Cmp->isNonStrictPredicate(), LLVMCmp->isNonStrictPredicate());
5920   EXPECT_EQ(Cmp->isRelational(), LLVMCmp->isRelational());
5921   if (Cmp->isRelational()) {
5922     EXPECT_EQ(Cmp->getFlippedStrictnessPredicate(),
5923               LLVMCmp->getFlippedStrictnessPredicate());
5924   }
5925   EXPECT_EQ(Cmp->isCommutative(), LLVMCmp->isCommutative());
5926   EXPECT_EQ(Cmp->isTrueWhenEqual(), LLVMCmp->isTrueWhenEqual());
5927   EXPECT_EQ(Cmp->isFalseWhenEqual(), LLVMCmp->isFalseWhenEqual());
5928   EXPECT_EQ(sandboxir::CmpInst::isOrdered(Pred),
5929             llvm::CmpInst::isOrdered(LLVMPred));
5930   EXPECT_EQ(sandboxir::CmpInst::isUnordered(Pred),
5931             llvm::CmpInst::isUnordered(LLVMPred));
5932 }
5933 
5934 TEST_F(SandboxIRTest, ICmpInst) {
5935   SCOPED_TRACE("SandboxIRTest sandboxir::ICmpInst tests");
5936   parseIR(C, R"IR(
5937 define void @foo(i32 %i0, i32 %i1) {
5938  bb:
5939   %ine  = icmp ne i32 %i0, %i1
5940   %iugt = icmp ugt i32 %i0, %i1
5941   %iuge = icmp uge i32 %i0, %i1
5942   %iult = icmp ult i32 %i0, %i1
5943   %iule = icmp ule i32 %i0, %i1
5944   %isgt = icmp sgt i32 %i0, %i1
5945   %isle = icmp sle i32 %i0, %i1
5946   %ieg  = icmp eq i32 %i0, %i1
5947   ret void
5948 }
5949 )IR");
5950   Function &LLVMF = *M->getFunction("foo");
5951   sandboxir::Context Ctx(C);
5952   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
5953 
5954   auto *LLVMBB = getBasicBlockByName(LLVMF, "bb");
5955   auto LLVMIt = LLVMBB->begin();
5956   auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB));
5957   auto It = BB->begin();
5958   // Check classof()
5959   while (auto *ICmp = dyn_cast<sandboxir::ICmpInst>(&*It++)) {
5960     auto *LLVMICmp = cast<llvm::ICmpInst>(&*LLVMIt++);
5961     checkSwapOperands(Ctx, ICmp, LLVMICmp);
5962     checkCommonPredicates(ICmp, LLVMICmp);
5963     EXPECT_EQ(ICmp->isSigned(), LLVMICmp->isSigned());
5964     EXPECT_EQ(ICmp->isUnsigned(), LLVMICmp->isUnsigned());
5965     EXPECT_EQ(ICmp->getSignedPredicate(), LLVMICmp->getSignedPredicate());
5966     EXPECT_EQ(ICmp->getUnsignedPredicate(), LLVMICmp->getUnsignedPredicate());
5967   }
5968   auto *NewCmp =
5969       sandboxir::CmpInst::create(llvm::CmpInst::ICMP_ULE, F.getArg(0),
5970                                  F.getArg(1), &*BB->begin(), Ctx, "NewCmp");
5971   EXPECT_EQ(NewCmp, &*BB->begin());
5972   EXPECT_EQ(NewCmp->getPredicate(), llvm::CmpInst::ICMP_ULE);
5973   EXPECT_EQ(NewCmp->getOperand(0), F.getArg(0));
5974   EXPECT_EQ(NewCmp->getOperand(1), F.getArg(1));
5975 #ifndef NDEBUG
5976   EXPECT_EQ(NewCmp->getName(), "NewCmp");
5977 #endif // NDEBUG
5978   // TODO: Improve this test when sandboxir::VectorType is more completely
5979   // implemented.
5980   sandboxir::Type *RT =
5981       sandboxir::CmpInst::makeCmpResultType(F.getArg(0)->getType());
5982   EXPECT_TRUE(RT->isIntegerTy(1)); // Only one bit in a single comparison
5983 }
5984 
5985 TEST_F(SandboxIRTest, FCmpInst) {
5986   SCOPED_TRACE("SandboxIRTest sandboxir::FCmpInst tests");
5987   parseIR(C, R"IR(
5988 define void @foo(float %f0, float %f1) {
5989 bb:
5990   %ffalse = fcmp false float %f0, %f1
5991   %foeq = fcmp oeq float %f0, %f1
5992   %fogt = fcmp ogt float %f0, %f1
5993   %folt = fcmp olt float %f0, %f1
5994   %fole = fcmp ole float %f0, %f1
5995   %fone = fcmp one float %f0, %f1
5996   %ford = fcmp ord float %f0, %f1
5997   %funo = fcmp uno float %f0, %f1
5998   %fueq = fcmp ueq float %f0, %f1
5999   %fugt = fcmp ugt float %f0, %f1
6000   %fuge = fcmp uge float %f0, %f1
6001   %fult = fcmp ult float %f0, %f1
6002   %fule = fcmp ule float %f0, %f1
6003   %fune = fcmp une float %f0, %f1
6004   %ftrue = fcmp true float %f0, %f1
6005   ret void
6006 bb1:
6007   %copyfrom = fadd reassoc float %f0, 42.0
6008   ret void
6009 }
6010 )IR");
6011   Function &LLVMF = *M->getFunction("foo");
6012   sandboxir::Context Ctx(C);
6013   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
6014 
6015   auto *LLVMBB = getBasicBlockByName(LLVMF, "bb");
6016   auto LLVMIt = LLVMBB->begin();
6017   auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB));
6018   auto It = BB->begin();
6019   // Check classof()
6020   while (auto *FCmp = dyn_cast<sandboxir::ICmpInst>(&*It++)) {
6021     auto *LLVMFCmp = cast<llvm::ICmpInst>(&*LLVMIt++);
6022     checkSwapOperands(Ctx, FCmp, LLVMFCmp);
6023     checkCommonPredicates(FCmp, LLVMFCmp);
6024   }
6025 
6026   auto *LLVMBB1 = getBasicBlockByName(LLVMF, "bb1");
6027   auto *BB1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB1));
6028   auto It1 = BB1->begin();
6029   auto *CopyFrom = &*It1++;
6030   CopyFrom->setFastMathFlags(FastMathFlags::getFast());
6031 
6032   // create with default flags
6033   auto *NewFCmp = sandboxir::CmpInst::create(
6034       llvm::CmpInst::FCMP_ONE, F.getArg(0), F.getArg(1), &*It1, Ctx, "NewFCmp");
6035   EXPECT_EQ(NewFCmp->getPredicate(), llvm::CmpInst::FCMP_ONE);
6036   EXPECT_EQ(NewFCmp->getOperand(0), F.getArg(0));
6037   EXPECT_EQ(NewFCmp->getOperand(1), F.getArg(1));
6038 #ifndef NDEBUG
6039   EXPECT_EQ(NewFCmp->getName(), "NewFCmp");
6040 #endif // NDEBUG
6041   FastMathFlags DefaultFMF = NewFCmp->getFastMathFlags();
6042   EXPECT_TRUE(CopyFrom->getFastMathFlags() != DefaultFMF);
6043   // create with copied flags
6044   auto *NewFCmpFlags = sandboxir::CmpInst::createWithCopiedFlags(
6045       llvm::CmpInst::FCMP_ONE, F.getArg(0), F.getArg(1), CopyFrom, &*It1, Ctx,
6046       "NewFCmpFlags");
6047   EXPECT_FALSE(NewFCmpFlags->getFastMathFlags() !=
6048                CopyFrom->getFastMathFlags());
6049   EXPECT_EQ(NewFCmpFlags->getPredicate(), llvm::CmpInst::FCMP_ONE);
6050   EXPECT_EQ(NewFCmpFlags->getOperand(0), F.getArg(0));
6051   EXPECT_EQ(NewFCmpFlags->getOperand(1), F.getArg(1));
6052 #ifndef NDEBUG
6053   EXPECT_EQ(NewFCmpFlags->getName(), "NewFCmpFlags");
6054 #endif // NDEBUG
6055 }
6056 
6057 TEST_F(SandboxIRTest, UnreachableInst) {
6058   parseIR(C, R"IR(
6059 define void @foo() {
6060   unreachable
6061 }
6062 )IR");
6063   llvm::Function *LLVMF = &*M->getFunction("foo");
6064   sandboxir::Context Ctx(C);
6065   sandboxir::Function *F = Ctx.createFunction(LLVMF);
6066   auto *BB = &*F->begin();
6067   auto It = BB->begin();
6068   auto *UI = cast<sandboxir::UnreachableInst>(&*It++);
6069 
6070   EXPECT_EQ(UI->getNumSuccessors(), 0u);
6071   EXPECT_EQ(UI->getNumOfIRInstrs(), 1u);
6072   // Check create(InsertBefore)
6073   sandboxir::UnreachableInst *NewUI =
6074       sandboxir::UnreachableInst::create(/*InsertBefore=*/UI, Ctx);
6075   EXPECT_EQ(NewUI->getNextNode(), UI);
6076   // Check create(InsertAtEnd)
6077   sandboxir::UnreachableInst *NewUIEnd =
6078       sandboxir::UnreachableInst::create(/*InsertAtEnd=*/BB, Ctx);
6079   EXPECT_EQ(NewUIEnd->getParent(), BB);
6080   EXPECT_EQ(NewUIEnd->getNextNode(), nullptr);
6081 }
6082 
6083 /// Makes sure that all Instruction sub-classes have a classof().
6084 TEST_F(SandboxIRTest, CheckClassof) {
6085 #define DEF_INSTR(ID, OPC, CLASS)                                              \
6086   EXPECT_NE(&sandboxir::CLASS::classof, &sandboxir::Instruction::classof);
6087 #include "llvm/SandboxIR/SandboxIRValues.def"
6088 }
6089