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