xref: /llvm-project/llvm/unittests/SandboxIR/SandboxIRTest.cpp (revision e22b07e766e415d6a0ed4c73fe5286fcf25f8d98)
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-matchers.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, GetExpected) {
1474   parseIR(C, R"IR(
1475 define float @foo(float %v, ptr %ptr) {
1476   %add = fadd float %v, %v
1477   store float %v, ptr %ptr
1478   ret float %v
1479 }
1480 define void @bar(float %v, ptr %ptr) {
1481   ret void
1482 }
1483 )IR");
1484   llvm::Function &Foo = *M->getFunction("foo");
1485   sandboxir::Context Ctx(C);
1486 
1487   Ctx.createFunction(&Foo);
1488   auto *FooBB = cast<sandboxir::BasicBlock>(Ctx.getValue(&*Foo.begin()));
1489   auto FooIt = FooBB->begin();
1490   auto Add = cast<sandboxir::Instruction>(&*FooIt++);
1491   auto *S0 = cast<sandboxir::Instruction>(&*FooIt++);
1492   auto *RetF = cast<sandboxir::Instruction>(&*FooIt++);
1493   // getExpectedValue
1494   EXPECT_EQ(sandboxir::Utils::getExpectedValue(Add), Add);
1495   EXPECT_EQ(sandboxir::Utils::getExpectedValue(S0),
1496             cast<sandboxir::StoreInst>(S0)->getValueOperand());
1497   EXPECT_EQ(sandboxir::Utils::getExpectedValue(RetF),
1498             cast<sandboxir::ReturnInst>(RetF)->getReturnValue());
1499   // getExpectedType
1500   EXPECT_EQ(sandboxir::Utils::getExpectedType(Add), Add->getType());
1501   EXPECT_EQ(sandboxir::Utils::getExpectedType(S0),
1502             cast<sandboxir::StoreInst>(S0)->getValueOperand()->getType());
1503   EXPECT_EQ(sandboxir::Utils::getExpectedType(RetF),
1504             cast<sandboxir::ReturnInst>(RetF)->getReturnValue()->getType());
1505 
1506   // getExpectedValue for void returns
1507   llvm::Function &Bar = *M->getFunction("bar");
1508   Ctx.createFunction(&Bar);
1509   auto *BarBB = cast<sandboxir::BasicBlock>(Ctx.getValue(&*Bar.begin()));
1510   auto BarIt = BarBB->begin();
1511   auto *RetV = cast<sandboxir::Instruction>(&*BarIt++);
1512   EXPECT_EQ(sandboxir::Utils::getExpectedValue(RetV), nullptr);
1513 }
1514 
1515 TEST_F(SandboxIRTest, GetNumBits) {
1516   parseIR(C, R"IR(
1517 define void @foo(float %arg0, double %arg1, i8 %arg2, i64 %arg3) {
1518 bb0:
1519   ret void
1520 }
1521 )IR");
1522   llvm::Function &Foo = *M->getFunction("foo");
1523   sandboxir::Context Ctx(C);
1524   sandboxir::Function *F = Ctx.createFunction(&Foo);
1525   const DataLayout &DL = M->getDataLayout();
1526   // getNumBits for scalars
1527   EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(0), DL),
1528             DL.getTypeSizeInBits(Type::getFloatTy(C)));
1529   EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(1), DL),
1530             DL.getTypeSizeInBits(Type::getDoubleTy(C)));
1531   EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(2), DL), 8u);
1532   EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(3), DL), 64u);
1533 }
1534 
1535 TEST_F(SandboxIRTest, RAUW_RUWIf) {
1536   parseIR(C, R"IR(
1537 define void @foo(ptr %ptr) {
1538   %ld0 = load float, ptr %ptr
1539   %ld1 = load float, ptr %ptr
1540   store float %ld0, ptr %ptr
1541   store float %ld0, ptr %ptr
1542   ret void
1543 }
1544 )IR");
1545   llvm::Function &LLVMF = *M->getFunction("foo");
1546   sandboxir::Context Ctx(C);
1547   llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
1548 
1549   Ctx.createFunction(&LLVMF);
1550   auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB));
1551   auto It = BB->begin();
1552   sandboxir::Instruction *Ld0 = &*It++;
1553   sandboxir::Instruction *Ld1 = &*It++;
1554   sandboxir::Instruction *St0 = &*It++;
1555   sandboxir::Instruction *St1 = &*It++;
1556   // Check RUWIf when the lambda returns false.
1557   Ld0->replaceUsesWithIf(Ld1, [](const sandboxir::Use &Use) { return false; });
1558   EXPECT_EQ(St0->getOperand(0), Ld0);
1559   EXPECT_EQ(St1->getOperand(0), Ld0);
1560   // Check RUWIf when the lambda returns true.
1561   Ld0->replaceUsesWithIf(Ld1, [](const sandboxir::Use &Use) { return true; });
1562   EXPECT_EQ(St0->getOperand(0), Ld1);
1563   EXPECT_EQ(St1->getOperand(0), Ld1);
1564   St0->setOperand(0, Ld0);
1565   St1->setOperand(0, Ld0);
1566   // Check RUWIf user == St0.
1567   Ld0->replaceUsesWithIf(
1568       Ld1, [St0](const sandboxir::Use &Use) { return Use.getUser() == St0; });
1569   EXPECT_EQ(St0->getOperand(0), Ld1);
1570   EXPECT_EQ(St1->getOperand(0), Ld0);
1571   St0->setOperand(0, Ld0);
1572   // Check RUWIf user == St1.
1573   Ld0->replaceUsesWithIf(
1574       Ld1, [St1](const sandboxir::Use &Use) { return Use.getUser() == St1; });
1575   EXPECT_EQ(St0->getOperand(0), Ld0);
1576   EXPECT_EQ(St1->getOperand(0), Ld1);
1577   St1->setOperand(0, Ld0);
1578   // Check RAUW.
1579   Ld1->replaceAllUsesWith(Ld0);
1580   EXPECT_EQ(St0->getOperand(0), Ld0);
1581   EXPECT_EQ(St1->getOperand(0), Ld0);
1582 }
1583 
1584 // Check that the operands/users are counted correctly.
1585 //  I1
1586 // /  \
1587 // \  /
1588 //  I2
1589 TEST_F(SandboxIRTest, DuplicateUses) {
1590   parseIR(C, R"IR(
1591 define void @foo(i8 %v) {
1592   %I1 = add i8 %v, %v
1593   %I2 = add i8 %I1, %I1
1594   ret void
1595 }
1596 )IR");
1597   Function &LLVMF = *M->getFunction("foo");
1598   sandboxir::Context Ctx(C);
1599   auto *F = Ctx.createFunction(&LLVMF);
1600   auto *BB = &*F->begin();
1601   auto It = BB->begin();
1602   auto *I1 = &*It++;
1603   auto *I2 = &*It++;
1604   EXPECT_EQ(range_size(I1->users()), 2u);
1605   EXPECT_EQ(range_size(I2->operands()), 2u);
1606 }
1607 
1608 TEST_F(SandboxIRTest, Function) {
1609   parseIR(C, R"IR(
1610 define void @foo0(i32 %arg0, i32 %arg1) {
1611 bb0:
1612   br label %bb1
1613 bb1:
1614   ret void
1615 }
1616 define void @foo1() {
1617   ret void
1618 }
1619 
1620 )IR");
1621   llvm::Function *LLVMF0 = &*M->getFunction("foo0");
1622   llvm::Function *LLVMF1 = &*M->getFunction("foo1");
1623   llvm::Argument *LLVMArg0 = LLVMF0->getArg(0);
1624   llvm::Argument *LLVMArg1 = LLVMF0->getArg(1);
1625 
1626   sandboxir::Context Ctx(C);
1627   sandboxir::Function *F0 = Ctx.createFunction(LLVMF0);
1628   sandboxir::Function *F1 = Ctx.createFunction(LLVMF1);
1629 
1630   // Check getIterator().
1631   {
1632     auto It0 = F0->getIterator();
1633     auto It1 = F1->getIterator();
1634     EXPECT_EQ(&*It0, F0);
1635     EXPECT_EQ(&*It1, F1);
1636     EXPECT_EQ(std::next(It0), It1);
1637     EXPECT_EQ(std::prev(It1), It0);
1638     EXPECT_EQ(&*std::next(It0), F1);
1639     EXPECT_EQ(&*std::prev(It1), F0);
1640   }
1641   // Check getReverseIterator().
1642   {
1643     auto RevIt0 = F0->getReverseIterator();
1644     auto RevIt1 = F1->getReverseIterator();
1645     EXPECT_EQ(&*RevIt0, F0);
1646     EXPECT_EQ(&*RevIt1, F1);
1647     EXPECT_EQ(std::prev(RevIt0), RevIt1);
1648     EXPECT_EQ(std::next(RevIt1), RevIt0);
1649     EXPECT_EQ(&*std::prev(RevIt0), F1);
1650     EXPECT_EQ(&*std::next(RevIt1), F0);
1651   }
1652 
1653   // Check F arguments
1654   EXPECT_EQ(F0->arg_size(), 2u);
1655   EXPECT_FALSE(F0->arg_empty());
1656   EXPECT_EQ(F0->getArg(0), Ctx.getValue(LLVMArg0));
1657   EXPECT_EQ(F0->getArg(1), Ctx.getValue(LLVMArg1));
1658 
1659   // Check F.begin(), F.end(), Function::iterator
1660   llvm::BasicBlock *LLVMBB = &*LLVMF0->begin();
1661   for (sandboxir::BasicBlock &BB : *F0) {
1662     EXPECT_EQ(&BB, Ctx.getValue(LLVMBB));
1663     LLVMBB = LLVMBB->getNextNode();
1664   }
1665 
1666 #ifndef NDEBUG
1667   {
1668     // Check F.dumpNameAndArgs()
1669     std::string Buff;
1670     raw_string_ostream BS(Buff);
1671     F0->dumpNameAndArgs(BS);
1672     EXPECT_EQ(Buff, "void @foo0(i32 %arg0, i32 %arg1)");
1673   }
1674   {
1675     // Check F.dump()
1676     std::string Buff;
1677     raw_string_ostream BS(Buff);
1678     BS << "\n";
1679     F0->dumpOS(BS);
1680     EXPECT_EQ(Buff, R"IR(
1681 void @foo0(i32 %arg0, i32 %arg1) {
1682 bb0:
1683   br label %bb1 ; SB4. (Br)
1684 
1685 bb1:
1686   ret void ; SB6. (Ret)
1687 }
1688 )IR");
1689   }
1690 #endif // NDEBUG
1691 }
1692 
1693 TEST_F(SandboxIRTest, Module) {
1694   parseIR(C, R"IR(
1695 @glob0 = global i32 42
1696 @glob1 = global i32 43
1697 @internal0 = internal global i32 42
1698 @const0 = constant i32 42
1699 @alias0 = dso_local alias void(), ptr @foo
1700 @ifunc = ifunc void(), ptr @foo
1701 define void @foo() {
1702   ret void
1703 }
1704 define void @bar() {
1705   ret void
1706 }
1707 )IR");
1708   llvm::Module *LLVMM = &*M;
1709   llvm::Function *LLVMFFoo = &*M->getFunction("foo");
1710   llvm::Function *LLVMFBar = &*M->getFunction("bar");
1711 
1712   sandboxir::Context Ctx(C);
1713   auto *M = Ctx.createModule(LLVMM);
1714   // Check getContext().
1715   EXPECT_EQ(&M->getContext(), &Ctx);
1716   // Check getFunction().
1717   auto *FFoo = M->getFunction("foo");
1718   auto *FBar = M->getFunction("bar");
1719   EXPECT_EQ(FFoo, Ctx.getValue(LLVMFFoo));
1720   EXPECT_EQ(FBar, Ctx.getValue(LLVMFBar));
1721   // Check getDataLayout().
1722   EXPECT_EQ(&M->getDataLayout(), &LLVMM->getDataLayout());
1723   // Check getSourceFileName().
1724   EXPECT_EQ(M->getSourceFileName(), LLVMM->getSourceFileName());
1725   // Check getGlobalVariable().
1726   for (const char *Name : {"global0", "global1", "internal0"})
1727     EXPECT_EQ(M->getGlobalVariable(Name),
1728               Ctx.getValue(LLVMM->getGlobalVariable(Name)));
1729   // Check getGlobalVariable(AllowInternal).
1730   {
1731     auto *Internal0 = M->getGlobalVariable("internal0", /*AllowInternal=*/true);
1732     EXPECT_TRUE(Internal0 != nullptr);
1733     EXPECT_EQ(Internal0, Ctx.getValue(LLVMM->getNamedGlobal("internal0")));
1734   }
1735   // Check getNamedGlobal().
1736   {
1737     auto *Internal = M->getNamedGlobal("internal0");
1738     EXPECT_TRUE(Internal != nullptr);
1739     EXPECT_EQ(Internal, Ctx.getValue(LLVMM->getNamedGlobal("internal0")));
1740   }
1741   // Check getNamedAlias().
1742   auto *Alias0 = M->getNamedAlias("alias0");
1743   EXPECT_EQ(Alias0, Ctx.getValue(LLVMM->getNamedAlias("alias0")));
1744   EXPECT_EQ(M->getNamedAlias("aliasFOO"), nullptr);
1745   // Check getNamedIFunc().
1746   auto *IFunc0 = M->getNamedIFunc("ifunc0");
1747   EXPECT_EQ(IFunc0, Ctx.getValue(LLVMM->getNamedAlias("ifunc0")));
1748   EXPECT_EQ(M->getNamedIFunc("ifuncFOO"), nullptr);
1749 }
1750 
1751 TEST_F(SandboxIRTest, BasicBlock) {
1752   parseIR(C, R"IR(
1753 define void @foo(i32 %v1) {
1754 bb0:
1755   br label %bb1
1756 bb1:
1757   ret void
1758 }
1759 )IR");
1760   llvm::Function *LLVMF = &*M->getFunction("foo");
1761   llvm::BasicBlock *LLVMBB0 = getBasicBlockByName(*LLVMF, "bb0");
1762   llvm::BasicBlock *LLVMBB1 = getBasicBlockByName(*LLVMF, "bb1");
1763 
1764   sandboxir::Context Ctx(C);
1765   sandboxir::Function *F = Ctx.createFunction(LLVMF);
1766   auto &BB0 = cast<sandboxir::BasicBlock>(*Ctx.getValue(LLVMBB0));
1767   auto &BB1 = cast<sandboxir::BasicBlock>(*Ctx.getValue(LLVMBB1));
1768 
1769   // Check BB::classof()
1770   EXPECT_TRUE(isa<sandboxir::Value>(BB0));
1771   EXPECT_FALSE(isa<sandboxir::User>(BB0));
1772   EXPECT_FALSE(isa<sandboxir::Instruction>(BB0));
1773   EXPECT_FALSE(isa<sandboxir::Constant>(BB0));
1774   EXPECT_FALSE(isa<sandboxir::Argument>(BB0));
1775 
1776   // Check BB.getParent()
1777   EXPECT_EQ(BB0.getParent(), F);
1778   EXPECT_EQ(BB1.getParent(), F);
1779 
1780   // Check BBIterator, BB.begin(), BB.end().
1781   llvm::Instruction *LLVMI = &*LLVMBB0->begin();
1782   for (sandboxir::Instruction &I : BB0) {
1783     EXPECT_EQ(&I, Ctx.getValue(LLVMI));
1784     LLVMI = LLVMI->getNextNode();
1785     // Check getNodeParent().
1786     EXPECT_EQ(I.getIterator().getNodeParent(), &BB0);
1787   }
1788   LLVMI = &*LLVMBB1->begin();
1789   for (sandboxir::Instruction &I : BB1) {
1790     EXPECT_EQ(&I, Ctx.getValue(LLVMI));
1791     LLVMI = LLVMI->getNextNode();
1792   }
1793   // Check NodeParent() for BB::end().
1794   EXPECT_EQ(BB0.end().getNodeParent(), &BB0);
1795 
1796   // Check BB.getTerminator()
1797   EXPECT_EQ(BB0.getTerminator(), Ctx.getValue(LLVMBB0->getTerminator()));
1798   EXPECT_EQ(BB1.getTerminator(), Ctx.getValue(LLVMBB1->getTerminator()));
1799 
1800   // Check BB.rbegin(), BB.rend()
1801   EXPECT_EQ(&*BB0.rbegin(), BB0.getTerminator());
1802   EXPECT_EQ(&*std::prev(BB0.rend()), &*BB0.begin());
1803 
1804 #ifndef NDEBUG
1805   {
1806     // Check BB.dump()
1807     std::string Buff;
1808     raw_string_ostream BS(Buff);
1809     BS << "\n";
1810     BB0.dumpOS(BS);
1811     EXPECT_EQ(Buff, R"IR(
1812 bb0:
1813   br label %bb1 ; SB3. (Br)
1814 )IR");
1815   }
1816 #endif // NDEBUG
1817 }
1818 
1819 TEST_F(SandboxIRTest, Instruction) {
1820   parseIR(C, R"IR(
1821 define void @foo(i8 %v1, ptr %ptr) {
1822 bb0:
1823   %add0 = add i8 %v1, %v1
1824   %sub1 = sub i8 %add0, %v1
1825   ret void
1826 
1827 bb1:
1828   %add1 = add i8 %v1, %v1
1829   %sub2 = sub i8 %add1, %v1
1830   %ld0 = load i8, ptr %ptr
1831   store i8 %ld0, ptr %ptr
1832   store volatile i8 %ld0, ptr %ptr
1833   %atomicrmw = atomicrmw add ptr %ptr, i8 %v1 acquire
1834   %udiv = udiv i8 %ld0, %v1
1835   %urem = urem i8 %ld0, %v1
1836   call void @foo(), !dbg !1
1837   ret void, !tbaa !2
1838 }
1839 
1840 !1 = !{}
1841 !2 = !{}
1842 )IR");
1843   llvm::Function *LLVMF = &*M->getFunction("foo");
1844   llvm::BasicBlock *LLVMBB1 = getBasicBlockByName(*LLVMF, "bb1");
1845   sandboxir::Context Ctx(C);
1846   sandboxir::Function *F = Ctx.createFunction(LLVMF);
1847   auto *Arg = F->getArg(0);
1848   auto *BB = cast<sandboxir::BasicBlock>(
1849       Ctx.getValue(getBasicBlockByName(*LLVMF, "bb0")));
1850   auto It = BB->begin();
1851   auto *I0 = &*It++;
1852   auto *I1 = &*It++;
1853   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
1854 
1855   // Check getPrevNode().
1856   EXPECT_EQ(Ret->getPrevNode(), I1);
1857   EXPECT_EQ(I1->getPrevNode(), I0);
1858   EXPECT_EQ(I0->getPrevNode(), nullptr);
1859 
1860   // Check getNextNode().
1861   EXPECT_EQ(I0->getNextNode(), I1);
1862   EXPECT_EQ(I1->getNextNode(), Ret);
1863   EXPECT_EQ(Ret->getNextNode(), nullptr);
1864 
1865   // Check getIterator().
1866   EXPECT_EQ(I0->getIterator(), std::next(BB->begin(), 0));
1867   EXPECT_EQ(I1->getIterator(), std::next(BB->begin(), 1));
1868   EXPECT_EQ(Ret->getIterator(), std::next(BB->begin(), 2));
1869 
1870   // Check getOpcode().
1871   EXPECT_EQ(I0->getOpcode(), sandboxir::Instruction::Opcode::Add);
1872   EXPECT_EQ(I1->getOpcode(), sandboxir::Instruction::Opcode::Sub);
1873   EXPECT_EQ(Ret->getOpcode(), sandboxir::Instruction::Opcode::Ret);
1874 
1875   // Check getOpcodeName().
1876   EXPECT_STREQ(I0->getOpcodeName(), "Add");
1877   EXPECT_STREQ(I1->getOpcodeName(), "Sub");
1878   EXPECT_STREQ(Ret->getOpcodeName(), "Ret");
1879 
1880   EXPECT_STREQ(sandboxir::Instruction::getOpcodeName(
1881                    sandboxir::Instruction::Opcode::Alloca),
1882                "Alloca");
1883 
1884   // Check moveBefore(I).
1885   I1->moveBefore(I0);
1886   EXPECT_EQ(I0->getPrevNode(), I1);
1887   EXPECT_EQ(I1->getNextNode(), I0);
1888 
1889   // Check moveAfter(I).
1890   I1->moveAfter(I0);
1891   EXPECT_EQ(I0->getNextNode(), I1);
1892   EXPECT_EQ(I1->getPrevNode(), I0);
1893 
1894   // Check comesBefore(I).
1895   EXPECT_TRUE(I0->comesBefore(I1));
1896   EXPECT_FALSE(I1->comesBefore(I0));
1897 
1898   // Check moveBefore(BB, It).
1899   I1->moveBefore(*BB, BB->begin());
1900   EXPECT_EQ(I1->getPrevNode(), nullptr);
1901   EXPECT_EQ(I1->getNextNode(), I0);
1902   I1->moveBefore(*BB, BB->end());
1903   EXPECT_EQ(I1->getNextNode(), nullptr);
1904   EXPECT_EQ(Ret->getNextNode(), I1);
1905   I1->moveBefore(*BB, std::next(BB->begin()));
1906   EXPECT_EQ(I0->getNextNode(), I1);
1907   EXPECT_EQ(I1->getNextNode(), Ret);
1908 
1909   // Check removeFromParent().
1910   I0->removeFromParent();
1911 #ifndef NDEBUG
1912   EXPECT_DEATH(I0->getPrevNode(), ".*Detached.*");
1913   EXPECT_DEATH(I0->getNextNode(), ".*Detached.*");
1914 #endif // NDEBUG
1915   EXPECT_EQ(I0->getParent(), nullptr);
1916   EXPECT_EQ(I1->getPrevNode(), nullptr);
1917   EXPECT_EQ(I0->getOperand(0), Arg);
1918 
1919   // Check insertBefore().
1920   I0->insertBefore(I1);
1921   EXPECT_EQ(I1->getPrevNode(), I0);
1922 
1923   // Check insertInto().
1924   I0->removeFromParent();
1925   I0->insertInto(BB, BB->end());
1926   EXPECT_EQ(Ret->getNextNode(), I0);
1927   I0->moveBefore(I1);
1928   EXPECT_EQ(I0->getNextNode(), I1);
1929 
1930   // Check eraseFromParent().
1931 #ifndef NDEBUG
1932   EXPECT_DEATH(I0->eraseFromParent(), "Still connected to users.*");
1933 #endif
1934   I1->eraseFromParent();
1935   EXPECT_EQ(I0->getNumUses(), 0u);
1936   EXPECT_EQ(I0->getNextNode(), Ret);
1937 
1938   for (auto &LLVMI : *LLVMBB1) {
1939     auto &I = cast<sandboxir::Instruction>(*Ctx.getValue(&LLVMI));
1940     // Check isTerminator().
1941     EXPECT_EQ(LLVMI.isTerminator(), I.isTerminator());
1942     // Check isUnaryOp().
1943     EXPECT_EQ(LLVMI.isUnaryOp(), I.isUnaryOp());
1944     // Check isBinaryOp().
1945     EXPECT_EQ(LLVMI.isBinaryOp(), I.isBinaryOp());
1946     // Check isIntDivRem().
1947     EXPECT_EQ(LLVMI.isIntDivRem(), I.isIntDivRem());
1948     // Check isShift().
1949     EXPECT_EQ(LLVMI.isShift(), I.isShift());
1950     // Check isCast().
1951     EXPECT_EQ(LLVMI.isCast(), I.isCast());
1952     // Check isFuncletPad().
1953     EXPECT_EQ(LLVMI.isFuncletPad(), I.isFuncletPad());
1954     // Check isSpecialTerminator().
1955     EXPECT_EQ(LLVMI.isSpecialTerminator(), I.isSpecialTerminator());
1956     // Check isOnlyUserOfAnyOperand().
1957     EXPECT_EQ(LLVMI.isOnlyUserOfAnyOperand(), I.isOnlyUserOfAnyOperand());
1958     // Check isLogicalShift().
1959     EXPECT_EQ(LLVMI.isLogicalShift(), I.isLogicalShift());
1960     // Check hasMetadata().
1961     EXPECT_EQ(LLVMI.hasMetadata(), I.hasMetadata());
1962     // Check hasMetadataOtherThanDebugLoc().
1963     EXPECT_EQ(LLVMI.hasMetadataOtherThanDebugLoc(),
1964               I.hasMetadataOtherThanDebugLoc());
1965     // Check isAssociative().
1966     EXPECT_EQ(LLVMI.isAssociative(), I.isAssociative());
1967     // Check isCommutative().
1968     EXPECT_EQ(LLVMI.isCommutative(), I.isCommutative());
1969     // Check isIdempotent().
1970     EXPECT_EQ(LLVMI.isIdempotent(), I.isIdempotent());
1971     // Check isNilpotent().
1972     EXPECT_EQ(LLVMI.isNilpotent(), I.isNilpotent());
1973     // Check mayWriteToMemory().
1974     EXPECT_EQ(LLVMI.mayWriteToMemory(), I.mayWriteToMemory());
1975     // Check mayReadFromMemory().
1976     EXPECT_EQ(LLVMI.mayReadFromMemory(), I.mayReadFromMemory());
1977     // Check mayReadOrWriteMemory().
1978     EXPECT_EQ(LLVMI.mayReadOrWriteMemory(), I.mayReadOrWriteMemory());
1979     // Check isAtomic().
1980     EXPECT_EQ(LLVMI.isAtomic(), I.isAtomic());
1981     if (I.isAtomic()) {
1982       // Check hasAtomicLoad().
1983       EXPECT_EQ(LLVMI.hasAtomicLoad(), I.hasAtomicLoad());
1984       // Check hasAtomicStore().
1985       EXPECT_EQ(LLVMI.hasAtomicStore(), I.hasAtomicStore());
1986     }
1987     // Check isVolatile().
1988     EXPECT_EQ(LLVMI.isVolatile(), I.isVolatile());
1989     // Check getAccessType().
1990     EXPECT_EQ(Ctx.getType(LLVMI.getAccessType()), I.getAccessType());
1991     // Check mayThrow().
1992     EXPECT_EQ(LLVMI.mayThrow(), I.mayThrow());
1993     // Check isFenceLike().
1994     EXPECT_EQ(LLVMI.isFenceLike(), I.isFenceLike());
1995     // Check mayHaveSideEffects().
1996     EXPECT_EQ(LLVMI.mayHaveSideEffects(), I.mayHaveSideEffects());
1997   }
1998 }
1999 
2000 TEST_F(SandboxIRTest, Instruction_isStackSaveOrRestoreIntrinsic) {
2001   parseIR(C, R"IR(
2002 declare void @llvm.sideeffect()
2003 define void @foo(i8 %v1, ptr %ptr) {
2004   %add = add i8 %v1, %v1
2005   %stacksave = call ptr @llvm.stacksave()
2006   call void @llvm.stackrestore(ptr %stacksave)
2007   call void @llvm.sideeffect()
2008   ret void
2009 }
2010 )IR");
2011   llvm::Function *LLVMF = &*M->getFunction("foo");
2012   sandboxir::Context Ctx(C);
2013   sandboxir::Function *F = Ctx.createFunction(LLVMF);
2014   auto *BB = &*F->begin();
2015   auto It = BB->begin();
2016   auto *Add = cast<sandboxir::BinaryOperator>(&*It++);
2017   auto *StackSave = cast<sandboxir::CallInst>(&*It++);
2018   auto *StackRestore = cast<sandboxir::CallInst>(&*It++);
2019   auto *Other = cast<sandboxir::CallInst>(&*It++);
2020   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
2021 
2022   EXPECT_FALSE(Add->isStackSaveOrRestoreIntrinsic());
2023   EXPECT_TRUE(StackSave->isStackSaveOrRestoreIntrinsic());
2024   EXPECT_TRUE(StackRestore->isStackSaveOrRestoreIntrinsic());
2025   EXPECT_FALSE(Other->isStackSaveOrRestoreIntrinsic());
2026   EXPECT_FALSE(Ret->isStackSaveOrRestoreIntrinsic());
2027 }
2028 
2029 TEST_F(SandboxIRTest, Instruction_isMemDepCandidate) {
2030   parseIR(C, R"IR(
2031 declare void @llvm.fake.use(...)
2032 declare void @llvm.sideeffect()
2033 declare void @llvm.pseudoprobe(i64, i64, i32, i64)
2034 declare void @bar()
2035 define void @foo(i8 %v1, ptr %ptr) {
2036   %add0 = add i8 %v1, %v1
2037   %ld0 = load i8, ptr %ptr
2038   store i8 %v1, ptr %ptr
2039   call void @llvm.sideeffect()
2040   call void @llvm.pseudoprobe(i64 42, i64 1, i32 0, i64 -1)
2041   call void @llvm.fake.use(ptr %ptr)
2042   call void @bar()
2043   ret void
2044 }
2045 )IR");
2046   llvm::Function *LLVMF = &*M->getFunction("foo");
2047   sandboxir::Context Ctx(C);
2048   sandboxir::Function *F = Ctx.createFunction(LLVMF);
2049   auto *BB = &*F->begin();
2050   auto It = BB->begin();
2051   auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
2052   auto *Ld0 = cast<sandboxir::LoadInst>(&*It++);
2053   auto *St0 = cast<sandboxir::StoreInst>(&*It++);
2054   auto *SideEffect0 = cast<sandboxir::CallInst>(&*It++);
2055   auto *PseudoProbe0 = cast<sandboxir::CallInst>(&*It++);
2056   auto *OtherIntrinsic0 = cast<sandboxir::CallInst>(&*It++);
2057   auto *CallBar = cast<sandboxir::CallInst>(&*It++);
2058   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
2059 
2060   EXPECT_FALSE(Add0->isMemDepCandidate());
2061   EXPECT_TRUE(Ld0->isMemDepCandidate());
2062   EXPECT_TRUE(St0->isMemDepCandidate());
2063   EXPECT_FALSE(SideEffect0->isMemDepCandidate());
2064   EXPECT_FALSE(PseudoProbe0->isMemDepCandidate());
2065   EXPECT_TRUE(OtherIntrinsic0->isMemDepCandidate());
2066   EXPECT_TRUE(CallBar->isMemDepCandidate());
2067   EXPECT_FALSE(Ret->isMemDepCandidate());
2068 }
2069 
2070 TEST_F(SandboxIRTest, VAArgInst) {
2071   parseIR(C, R"IR(
2072 define void @foo(ptr %va) {
2073   %va_arg = va_arg ptr %va, i32
2074   ret void
2075 }
2076 )IR");
2077   llvm::Function *LLVMF = &*M->getFunction("foo");
2078 
2079   sandboxir::Context Ctx(C);
2080   sandboxir::Function *F = Ctx.createFunction(LLVMF);
2081   auto *Arg = F->getArg(0);
2082   auto *BB = &*F->begin();
2083   auto It = BB->begin();
2084   auto *VA = cast<sandboxir::VAArgInst>(&*It++);
2085   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
2086 
2087   // Check getPointerOperand().
2088   EXPECT_EQ(VA->getPointerOperand(), Arg);
2089   // Check getPOinterOperandIndex().
2090   EXPECT_EQ(sandboxir::VAArgInst::getPointerOperandIndex(),
2091             llvm::VAArgInst::getPointerOperandIndex());
2092   // Check create().
2093   auto *NewVATy = sandboxir::Type::getInt8Ty(Ctx);
2094   auto *NewVA = sandboxir::VAArgInst::create(Arg, NewVATy, Ret->getIterator(),
2095                                              Ret->getParent(), Ctx, "NewVA");
2096   EXPECT_EQ(NewVA->getNextNode(), Ret);
2097   EXPECT_EQ(NewVA->getType(), NewVATy);
2098 #ifndef NDEBUG
2099   EXPECT_EQ(NewVA->getName(), "NewVA");
2100 #endif // NDEBUG
2101 }
2102 
2103 TEST_F(SandboxIRTest, FreezeInst) {
2104   parseIR(C, R"IR(
2105 define void @foo(i8 %arg) {
2106   freeze i8 %arg
2107   ret void
2108 }
2109 )IR");
2110   llvm::Function *LLVMF = &*M->getFunction("foo");
2111 
2112   sandboxir::Context Ctx(C);
2113   sandboxir::Function *F = Ctx.createFunction(LLVMF);
2114   auto *Arg = F->getArg(0);
2115   auto *BB = &*F->begin();
2116   auto It = BB->begin();
2117   auto *Freeze = cast<sandboxir::FreezeInst>(&*It++);
2118   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
2119 
2120   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Freeze));
2121   EXPECT_EQ(Freeze->getOperand(0), Arg);
2122 
2123   // Check create().
2124   auto *NewFreeze = sandboxir::FreezeInst::create(
2125       Arg, Ret->getIterator(), Ret->getParent(), Ctx, "NewFreeze");
2126   EXPECT_EQ(NewFreeze->getNextNode(), Ret);
2127 #ifndef NDEBUG
2128   EXPECT_EQ(NewFreeze->getName(), "NewFreeze");
2129 #endif // NDEBUG
2130 }
2131 
2132 TEST_F(SandboxIRTest, FenceInst) {
2133   parseIR(C, R"IR(
2134 define void @foo() {
2135   fence syncscope("singlethread") seq_cst
2136   ret void
2137 }
2138 )IR");
2139   llvm::Function *LLVMF = &*M->getFunction("foo");
2140   llvm::BasicBlock *LLVMBB = &*LLVMF->begin();
2141   auto *LLVMFence = cast<llvm::FenceInst>(&*LLVMBB->begin());
2142   sandboxir::Context Ctx(C);
2143   sandboxir::Function *F = Ctx.createFunction(LLVMF);
2144   auto *BB = &*F->begin();
2145   auto It = BB->begin();
2146   auto *Fence = cast<sandboxir::FenceInst>(&*It++);
2147   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
2148 
2149   // Check getOrdering().
2150   EXPECT_EQ(Fence->getOrdering(), LLVMFence->getOrdering());
2151   // Check setOrdering().
2152   auto OrigOrdering = Fence->getOrdering();
2153   auto NewOrdering = AtomicOrdering::Release;
2154   EXPECT_NE(NewOrdering, OrigOrdering);
2155   Fence->setOrdering(NewOrdering);
2156   EXPECT_EQ(Fence->getOrdering(), NewOrdering);
2157   Fence->setOrdering(OrigOrdering);
2158   EXPECT_EQ(Fence->getOrdering(), OrigOrdering);
2159   // Check getSyncScopeID().
2160   EXPECT_EQ(Fence->getSyncScopeID(), LLVMFence->getSyncScopeID());
2161   // Check setSyncScopeID().
2162   auto OrigSSID = Fence->getSyncScopeID();
2163   auto NewSSID = SyncScope::System;
2164   EXPECT_NE(NewSSID, OrigSSID);
2165   Fence->setSyncScopeID(NewSSID);
2166   EXPECT_EQ(Fence->getSyncScopeID(), NewSSID);
2167   Fence->setSyncScopeID(OrigSSID);
2168   EXPECT_EQ(Fence->getSyncScopeID(), OrigSSID);
2169   // Check create().
2170   auto *NewFence =
2171       sandboxir::FenceInst::create(AtomicOrdering::Release, Ret->getIterator(),
2172                                    BB, Ctx, SyncScope::SingleThread);
2173   EXPECT_EQ(NewFence->getNextNode(), Ret);
2174   EXPECT_EQ(NewFence->getOrdering(), AtomicOrdering::Release);
2175   EXPECT_EQ(NewFence->getSyncScopeID(), SyncScope::SingleThread);
2176 }
2177 
2178 TEST_F(SandboxIRTest, SelectInst) {
2179   parseIR(C, R"IR(
2180 define void @foo(i1 %c0, i8 %v0, i8 %v1, i1 %c1) {
2181   %sel = select i1 %c0, i8 %v0, i8 %v1
2182   ret void
2183 }
2184 )IR");
2185   llvm::Function *LLVMF = &*M->getFunction("foo");
2186   sandboxir::Context Ctx(C);
2187   sandboxir::Function *F = Ctx.createFunction(LLVMF);
2188   auto *Cond0 = F->getArg(0);
2189   auto *V0 = F->getArg(1);
2190   auto *V1 = F->getArg(2);
2191   auto *Cond1 = F->getArg(3);
2192   auto *BB = &*F->begin();
2193   auto It = BB->begin();
2194   auto *Select = cast<sandboxir::SelectInst>(&*It++);
2195   const auto *ConstSelect = Select; // To test the const getters.
2196   auto *Ret = &*It++;
2197 
2198   // Check getCondition().
2199   EXPECT_EQ(Select->getCondition(), Cond0);
2200   EXPECT_EQ(ConstSelect->getCondition(), Cond0);
2201   // Check getTrueValue().
2202   EXPECT_EQ(Select->getTrueValue(), V0);
2203   EXPECT_EQ(ConstSelect->getTrueValue(), V0);
2204   // Check getFalseValue().
2205   EXPECT_EQ(Select->getFalseValue(), V1);
2206   EXPECT_EQ(ConstSelect->getFalseValue(), V1);
2207   // Check setCondition().
2208   Select->setCondition(Cond1);
2209   EXPECT_EQ(Select->getCondition(), Cond1);
2210   // Check setTrueValue().
2211   Select->setTrueValue(V1);
2212   EXPECT_EQ(Select->getTrueValue(), V1);
2213   // Check setFalseValue().
2214   Select->setFalseValue(V0);
2215   EXPECT_EQ(Select->getFalseValue(), V0);
2216   // Check swapValues().
2217   Select->swapValues();
2218   EXPECT_EQ(Select->getTrueValue(), V0);
2219   EXPECT_EQ(Select->getFalseValue(), V1);
2220   // Check areInvalidOperands.
2221   EXPECT_EQ(sandboxir::SelectInst::areInvalidOperands(Cond0, V0, V1), nullptr);
2222   EXPECT_NE(sandboxir::SelectInst::areInvalidOperands(V0, V1, Cond0), nullptr);
2223 
2224   {
2225     // Check SelectInst::create() InsertBefore.
2226     auto *NewSel = cast<sandboxir::SelectInst>(sandboxir::SelectInst::create(
2227         Cond0, V0, V1, /*InsertBefore=*/Ret, Ctx));
2228     EXPECT_EQ(NewSel->getCondition(), Cond0);
2229     EXPECT_EQ(NewSel->getTrueValue(), V0);
2230     EXPECT_EQ(NewSel->getFalseValue(), V1);
2231     EXPECT_EQ(NewSel->getNextNode(), Ret);
2232   }
2233   {
2234     // Check SelectInst::create() InsertAtEnd.
2235     auto *NewSel = cast<sandboxir::SelectInst>(
2236         sandboxir::SelectInst::create(Cond0, V0, V1, /*InsertAtEnd=*/BB, Ctx));
2237     EXPECT_EQ(NewSel->getCondition(), Cond0);
2238     EXPECT_EQ(NewSel->getTrueValue(), V0);
2239     EXPECT_EQ(NewSel->getFalseValue(), V1);
2240     EXPECT_EQ(NewSel->getPrevNode(), Ret);
2241   }
2242   {
2243     // Check SelectInst::create() Folded.
2244     auto *False = sandboxir::ConstantInt::get(sandboxir::Type::getInt1Ty(Ctx),
2245                                               0, /*IsSigned=*/false);
2246     auto *FortyTwo =
2247         sandboxir::ConstantInt::get(sandboxir::Type::getInt1Ty(Ctx), 42,
2248                                     /*IsSigned=*/false);
2249     auto *NewSel =
2250         sandboxir::SelectInst::create(False, FortyTwo, FortyTwo, Ret, Ctx);
2251     EXPECT_TRUE(isa<sandboxir::Constant>(NewSel));
2252     EXPECT_EQ(NewSel, FortyTwo);
2253   }
2254 }
2255 
2256 TEST_F(SandboxIRTest, ExtractElementInst) {
2257   parseIR(C, R"IR(
2258 define void @foo(<2 x i8> %vec, i32 %idx) {
2259   %ins0 = extractelement <2 x i8> %vec, i32 %idx
2260   ret void
2261 }
2262 )IR");
2263   Function &LLVMF = *M->getFunction("foo");
2264   sandboxir::Context Ctx(C);
2265   auto &F = *Ctx.createFunction(&LLVMF);
2266   auto *ArgVec = F.getArg(0);
2267   auto *ArgIdx = F.getArg(1);
2268   auto *BB = &*F.begin();
2269   auto It = BB->begin();
2270   auto *EI = cast<sandboxir::ExtractElementInst>(&*It++);
2271   auto *Ret = &*It++;
2272 
2273   EXPECT_EQ(EI->getOpcode(), sandboxir::Instruction::Opcode::ExtractElement);
2274   EXPECT_EQ(EI->getOperand(0), ArgVec);
2275   EXPECT_EQ(EI->getOperand(1), ArgIdx);
2276   EXPECT_EQ(EI->getVectorOperand(), ArgVec);
2277   EXPECT_EQ(EI->getIndexOperand(), ArgIdx);
2278   EXPECT_EQ(EI->getVectorOperandType(), ArgVec->getType());
2279 
2280   auto *NewI1 =
2281       cast<sandboxir::ExtractElementInst>(sandboxir::ExtractElementInst::create(
2282           ArgVec, ArgIdx, Ret, Ctx, "NewExtrBeforeRet"));
2283   EXPECT_EQ(NewI1->getOperand(0), ArgVec);
2284   EXPECT_EQ(NewI1->getOperand(1), ArgIdx);
2285   EXPECT_EQ(NewI1->getNextNode(), Ret);
2286 
2287   auto *NewI2 =
2288       cast<sandboxir::ExtractElementInst>(sandboxir::ExtractElementInst::create(
2289           ArgVec, ArgIdx, BB, Ctx, "NewExtrAtEndOfBB"));
2290   EXPECT_EQ(NewI2->getPrevNode(), Ret);
2291 
2292   auto *LLVMArgVec = LLVMF.getArg(0);
2293   auto *LLVMArgIdx = LLVMF.getArg(1);
2294   EXPECT_EQ(sandboxir::ExtractElementInst::isValidOperands(ArgVec, ArgIdx),
2295             llvm::ExtractElementInst::isValidOperands(LLVMArgVec, LLVMArgIdx));
2296   EXPECT_EQ(sandboxir::ExtractElementInst::isValidOperands(ArgIdx, ArgVec),
2297             llvm::ExtractElementInst::isValidOperands(LLVMArgIdx, LLVMArgVec));
2298 }
2299 
2300 TEST_F(SandboxIRTest, InsertElementInst) {
2301   parseIR(C, R"IR(
2302 define void @foo(i8 %v0, i8 %v1, <2 x i8> %vec) {
2303   %ins0 = insertelement <2 x i8> poison, i8 %v0, i32 0
2304   %ins1 = insertelement <2 x i8> %ins0, i8 %v1, i32 1
2305   ret void
2306 }
2307 )IR");
2308   Function &LLVMF = *M->getFunction("foo");
2309   sandboxir::Context Ctx(C);
2310   auto &F = *Ctx.createFunction(&LLVMF);
2311   auto *Arg0 = F.getArg(0);
2312   auto *Arg1 = F.getArg(1);
2313   auto *ArgVec = F.getArg(2);
2314   auto *BB = &*F.begin();
2315   auto It = BB->begin();
2316   auto *Ins0 = cast<sandboxir::InsertElementInst>(&*It++);
2317   auto *Ins1 = cast<sandboxir::InsertElementInst>(&*It++);
2318   auto *Ret = &*It++;
2319 
2320   EXPECT_EQ(Ins0->getOpcode(), sandboxir::Instruction::Opcode::InsertElement);
2321   EXPECT_EQ(Ins0->getOperand(1), Arg0);
2322   EXPECT_EQ(Ins1->getOperand(1), Arg1);
2323   EXPECT_EQ(Ins1->getOperand(0), Ins0);
2324   auto *Poison = Ins0->getOperand(0);
2325   auto *Idx = Ins0->getOperand(2);
2326   auto *NewI1 =
2327       cast<sandboxir::InsertElementInst>(sandboxir::InsertElementInst::create(
2328           Poison, Arg0, Idx, Ret, Ctx, "NewIns1"));
2329   EXPECT_EQ(NewI1->getOperand(0), Poison);
2330   EXPECT_EQ(NewI1->getNextNode(), Ret);
2331 
2332   auto *NewI2 =
2333       cast<sandboxir::InsertElementInst>(sandboxir::InsertElementInst::create(
2334           Poison, Arg0, Idx, BB, Ctx, "NewIns2"));
2335   EXPECT_EQ(NewI2->getPrevNode(), Ret);
2336 
2337   auto *LLVMArg0 = LLVMF.getArg(0);
2338   auto *LLVMArgVec = LLVMF.getArg(2);
2339   auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 0);
2340   auto *LLVMZero = llvm::ConstantInt::get(Type::getInt8Ty(C), 0);
2341   EXPECT_EQ(
2342       sandboxir::InsertElementInst::isValidOperands(ArgVec, Arg0, Zero),
2343       llvm::InsertElementInst::isValidOperands(LLVMArgVec, LLVMArg0, LLVMZero));
2344   EXPECT_EQ(
2345       sandboxir::InsertElementInst::isValidOperands(Arg0, ArgVec, Zero),
2346       llvm::InsertElementInst::isValidOperands(LLVMArg0, LLVMArgVec, LLVMZero));
2347 }
2348 
2349 TEST_F(SandboxIRTest, ShuffleVectorInst) {
2350   parseIR(C, R"IR(
2351 define void @foo(<2 x i8> %v1, <2 x i8> %v2) {
2352   %shuf = shufflevector <2 x i8> %v1, <2 x i8> %v2, <2 x i32> <i32 0, i32 2>
2353   %extr = extractelement <2 x i8> <i8 0, i8 1>, i32 0
2354   ret void
2355 }
2356 )IR");
2357   Function &LLVMF = *M->getFunction("foo");
2358   sandboxir::Context Ctx(C);
2359   auto &F = *Ctx.createFunction(&LLVMF);
2360   auto *ArgV1 = F.getArg(0);
2361   auto *ArgV2 = F.getArg(1);
2362   auto *BB = &*F.begin();
2363   auto It = BB->begin();
2364   auto *SVI = cast<sandboxir::ShuffleVectorInst>(&*It++);
2365   auto *EEI = cast<sandboxir::ExtractElementInst>(&*It++);
2366   auto *Ret = &*It++;
2367 
2368   EXPECT_EQ(SVI->getOpcode(), sandboxir::Instruction::Opcode::ShuffleVector);
2369   EXPECT_EQ(SVI->getOperand(0), ArgV1);
2370   EXPECT_EQ(SVI->getOperand(1), ArgV2);
2371 
2372   // In order to test all the methods we need masks of different lengths, so we
2373   // can't simply reuse one of the instructions created above. This helper
2374   // creates a new `shufflevector %v1, %2, <mask>` with the given mask indices.
2375   auto CreateShuffleWithMask = [&](auto &&...Indices) {
2376     SmallVector<int, 4> Mask = {Indices...};
2377     return cast<sandboxir::ShuffleVectorInst>(
2378         sandboxir::ShuffleVectorInst::create(ArgV1, ArgV2, Mask, Ret, Ctx));
2379   };
2380 
2381   // create (InsertBefore)
2382   auto *NewI1 =
2383       cast<sandboxir::ShuffleVectorInst>(sandboxir::ShuffleVectorInst::create(
2384           ArgV1, ArgV2, ArrayRef<int>({0, 2, 1, 3}), Ret, Ctx,
2385           "NewShuffleBeforeRet"));
2386   EXPECT_EQ(NewI1->getOperand(0), ArgV1);
2387   EXPECT_EQ(NewI1->getOperand(1), ArgV2);
2388   EXPECT_EQ(NewI1->getNextNode(), Ret);
2389 #ifndef NDEBUG
2390   EXPECT_EQ(NewI1->getName(), "NewShuffleBeforeRet");
2391 #endif
2392 
2393   // create (InsertAtEnd)
2394   auto *NewI2 =
2395       cast<sandboxir::ShuffleVectorInst>(sandboxir::ShuffleVectorInst::create(
2396           ArgV1, ArgV2, ArrayRef<int>({0, 1}), BB, Ctx, "NewShuffleAtEndOfBB"));
2397   EXPECT_EQ(NewI2->getPrevNode(), Ret);
2398 
2399   // Test the path that creates a folded constant. We're currently using an
2400   // extractelement instruction with a constant operand in the textual IR above
2401   // to obtain a constant vector to work with.
2402   // TODO: Refactor this once sandboxir::ConstantVector lands.
2403   auto *ShouldBeConstant = sandboxir::ShuffleVectorInst::create(
2404       EEI->getOperand(0), EEI->getOperand(0), ArrayRef<int>({0, 3}), BB, Ctx);
2405   EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant));
2406 
2407   // isValidOperands
2408   auto *LLVMArgV1 = LLVMF.getArg(0);
2409   auto *LLVMArgV2 = LLVMF.getArg(1);
2410   SmallVector<int, 2> Mask({1, 2});
2411   EXPECT_EQ(
2412       sandboxir::ShuffleVectorInst::isValidOperands(ArgV1, ArgV2, Mask),
2413       llvm::ShuffleVectorInst::isValidOperands(LLVMArgV1, LLVMArgV2, Mask));
2414   EXPECT_EQ(sandboxir::ShuffleVectorInst::isValidOperands(ArgV1, ArgV1, ArgV1),
2415             llvm::ShuffleVectorInst::isValidOperands(LLVMArgV1, LLVMArgV1,
2416                                                      LLVMArgV1));
2417 
2418   // commute
2419   {
2420     auto *I = CreateShuffleWithMask(0, 2);
2421     I->commute();
2422     EXPECT_EQ(I->getOperand(0), ArgV2);
2423     EXPECT_EQ(I->getOperand(1), ArgV1);
2424     EXPECT_THAT(I->getShuffleMask(), testing::ElementsAre(2, 0));
2425   }
2426 
2427   // getType
2428   EXPECT_EQ(SVI->getType(), ArgV1->getType());
2429 
2430   // getMaskValue
2431   EXPECT_EQ(SVI->getMaskValue(0), 0);
2432   EXPECT_EQ(SVI->getMaskValue(1), 2);
2433 
2434   // getShuffleMask / getShuffleMaskForBitcode
2435   {
2436     EXPECT_THAT(SVI->getShuffleMask(), testing::ElementsAre(0, 2));
2437 
2438     SmallVector<int, 2> Result;
2439     SVI->getShuffleMask(Result);
2440     EXPECT_THAT(Result, testing::ElementsAre(0, 2));
2441 
2442     Result.clear();
2443     sandboxir::ShuffleVectorInst::getShuffleMask(
2444         SVI->getShuffleMaskForBitcode(), Result);
2445     EXPECT_THAT(Result, testing::ElementsAre(0, 2));
2446   }
2447 
2448   // convertShuffleMaskForBitcode
2449   {
2450     auto *C = sandboxir::ShuffleVectorInst::convertShuffleMaskForBitcode(
2451         ArrayRef<int>({2, 3}), ArgV1->getType());
2452     SmallVector<int, 2> Result;
2453     sandboxir::ShuffleVectorInst::getShuffleMask(C, Result);
2454     EXPECT_THAT(Result, testing::ElementsAre(2, 3));
2455   }
2456 
2457   // setShuffleMask
2458   {
2459     auto *I = CreateShuffleWithMask(0, 1);
2460     I->setShuffleMask(ArrayRef<int>({2, 3}));
2461     EXPECT_THAT(I->getShuffleMask(), testing::ElementsAre(2, 3));
2462   }
2463 
2464   // The following functions check different mask properties. Note that most
2465   // of these come in three different flavors: a method that checks the mask
2466   // in the current instructions and two static member functions that check
2467   // a mask given as an ArrayRef<int> or Constant*, so there's quite a bit of
2468   // repetition in order to check all of them.
2469 
2470   // changesLength / increasesLength
2471   {
2472     auto *I = CreateShuffleWithMask(1);
2473     EXPECT_TRUE(I->changesLength());
2474     EXPECT_FALSE(I->increasesLength());
2475   }
2476   {
2477     auto *I = CreateShuffleWithMask(1, 1);
2478     EXPECT_FALSE(I->changesLength());
2479     EXPECT_FALSE(I->increasesLength());
2480   }
2481   {
2482     auto *I = CreateShuffleWithMask(1, 1, 1);
2483     EXPECT_TRUE(I->changesLength());
2484     EXPECT_TRUE(I->increasesLength());
2485   }
2486 
2487   // isSingleSource / isSingleSourceMask
2488   {
2489     auto *I = CreateShuffleWithMask(0, 1);
2490     EXPECT_TRUE(I->isSingleSource());
2491     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSingleSourceMask(
2492         I->getShuffleMaskForBitcode(), 2));
2493     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSingleSourceMask(
2494         I->getShuffleMask(), 2));
2495   }
2496   {
2497     auto *I = CreateShuffleWithMask(0, 2);
2498     EXPECT_FALSE(I->isSingleSource());
2499     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSingleSourceMask(
2500         I->getShuffleMaskForBitcode(), 2));
2501     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSingleSourceMask(
2502         I->getShuffleMask(), 2));
2503   }
2504 
2505   // isIdentity / isIdentityMask
2506   {
2507     auto *I = CreateShuffleWithMask(0, 1);
2508     EXPECT_TRUE(I->isIdentity());
2509     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isIdentityMask(
2510         I->getShuffleMaskForBitcode(), 2));
2511     EXPECT_TRUE(
2512         sandboxir::ShuffleVectorInst::isIdentityMask(I->getShuffleMask(), 2));
2513   }
2514   {
2515     auto *I = CreateShuffleWithMask(1, 0);
2516     EXPECT_FALSE(I->isIdentity());
2517     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isIdentityMask(
2518         I->getShuffleMaskForBitcode(), 2));
2519     EXPECT_FALSE(
2520         sandboxir::ShuffleVectorInst::isIdentityMask(I->getShuffleMask(), 2));
2521   }
2522 
2523   // isIdentityWithPadding
2524   EXPECT_TRUE(CreateShuffleWithMask(0, 1, -1, -1)->isIdentityWithPadding());
2525   EXPECT_FALSE(CreateShuffleWithMask(0, 1)->isIdentityWithPadding());
2526 
2527   // isIdentityWithExtract
2528   EXPECT_TRUE(CreateShuffleWithMask(0)->isIdentityWithExtract());
2529   EXPECT_FALSE(CreateShuffleWithMask(0, 1)->isIdentityWithExtract());
2530   EXPECT_FALSE(CreateShuffleWithMask(0, 1, 2)->isIdentityWithExtract());
2531   EXPECT_FALSE(CreateShuffleWithMask(1)->isIdentityWithExtract());
2532 
2533   // isConcat
2534   EXPECT_TRUE(CreateShuffleWithMask(0, 1, 2, 3)->isConcat());
2535   EXPECT_FALSE(CreateShuffleWithMask(0, 3)->isConcat());
2536 
2537   // isSelect / isSelectMask
2538   {
2539     auto *I = CreateShuffleWithMask(0, 3);
2540     EXPECT_TRUE(I->isSelect());
2541     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSelectMask(
2542         I->getShuffleMaskForBitcode(), 2));
2543     EXPECT_TRUE(
2544         sandboxir::ShuffleVectorInst::isSelectMask(I->getShuffleMask(), 2));
2545   }
2546   {
2547     auto *I = CreateShuffleWithMask(0, 2);
2548     EXPECT_FALSE(I->isSelect());
2549     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSelectMask(
2550         I->getShuffleMaskForBitcode(), 2));
2551     EXPECT_FALSE(
2552         sandboxir::ShuffleVectorInst::isSelectMask(I->getShuffleMask(), 2));
2553   }
2554 
2555   // isReverse / isReverseMask
2556   {
2557     auto *I = CreateShuffleWithMask(1, 0);
2558     EXPECT_TRUE(I->isReverse());
2559     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isReverseMask(
2560         I->getShuffleMaskForBitcode(), 2));
2561     EXPECT_TRUE(
2562         sandboxir::ShuffleVectorInst::isReverseMask(I->getShuffleMask(), 2));
2563   }
2564   {
2565     auto *I = CreateShuffleWithMask(1, 2);
2566     EXPECT_FALSE(I->isReverse());
2567     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isReverseMask(
2568         I->getShuffleMaskForBitcode(), 2));
2569     EXPECT_FALSE(
2570         sandboxir::ShuffleVectorInst::isReverseMask(I->getShuffleMask(), 2));
2571   }
2572 
2573   // isZeroEltSplat / isZeroEltSplatMask
2574   {
2575     auto *I = CreateShuffleWithMask(0, 0);
2576     EXPECT_TRUE(I->isZeroEltSplat());
2577     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask(
2578         I->getShuffleMaskForBitcode(), 2));
2579     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask(
2580         I->getShuffleMask(), 2));
2581   }
2582   {
2583     auto *I = CreateShuffleWithMask(1, 1);
2584     EXPECT_FALSE(I->isZeroEltSplat());
2585     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask(
2586         I->getShuffleMaskForBitcode(), 2));
2587     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask(
2588         I->getShuffleMask(), 2));
2589   }
2590 
2591   // isTranspose / isTransposeMask
2592   {
2593     auto *I = CreateShuffleWithMask(0, 2);
2594     EXPECT_TRUE(I->isTranspose());
2595     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isTransposeMask(
2596         I->getShuffleMaskForBitcode(), 2));
2597     EXPECT_TRUE(
2598         sandboxir::ShuffleVectorInst::isTransposeMask(I->getShuffleMask(), 2));
2599   }
2600   {
2601     auto *I = CreateShuffleWithMask(1, 1);
2602     EXPECT_FALSE(I->isTranspose());
2603     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isTransposeMask(
2604         I->getShuffleMaskForBitcode(), 2));
2605     EXPECT_FALSE(
2606         sandboxir::ShuffleVectorInst::isTransposeMask(I->getShuffleMask(), 2));
2607   }
2608 
2609   // isSplice / isSpliceMask
2610   {
2611     auto *I = CreateShuffleWithMask(1, 2);
2612     int Index;
2613     EXPECT_TRUE(I->isSplice(Index));
2614     EXPECT_EQ(Index, 1);
2615     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSpliceMask(
2616         I->getShuffleMaskForBitcode(), 2, Index));
2617     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSpliceMask(I->getShuffleMask(),
2618                                                            2, Index));
2619   }
2620   {
2621     auto *I = CreateShuffleWithMask(2, 1);
2622     int Index;
2623     EXPECT_FALSE(I->isSplice(Index));
2624     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSpliceMask(
2625         I->getShuffleMaskForBitcode(), 2, Index));
2626     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSpliceMask(I->getShuffleMask(),
2627                                                             2, Index));
2628   }
2629 
2630   // isExtractSubvectorMask
2631   {
2632     auto *I = CreateShuffleWithMask(1);
2633     int Index;
2634     EXPECT_TRUE(I->isExtractSubvectorMask(Index));
2635     EXPECT_EQ(Index, 1);
2636     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask(
2637         I->getShuffleMaskForBitcode(), 2, Index));
2638     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask(
2639         I->getShuffleMask(), 2, Index));
2640   }
2641   {
2642     auto *I = CreateShuffleWithMask(1, 2);
2643     int Index;
2644     EXPECT_FALSE(I->isExtractSubvectorMask(Index));
2645     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask(
2646         I->getShuffleMaskForBitcode(), 2, Index));
2647     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask(
2648         I->getShuffleMask(), 2, Index));
2649   }
2650 
2651   // isInsertSubvectorMask
2652   {
2653     auto *I = CreateShuffleWithMask(0, 2);
2654     int NumSubElts, Index;
2655     EXPECT_TRUE(I->isInsertSubvectorMask(NumSubElts, Index));
2656     EXPECT_EQ(Index, 1);
2657     EXPECT_EQ(NumSubElts, 1);
2658     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask(
2659         I->getShuffleMaskForBitcode(), 2, NumSubElts, Index));
2660     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask(
2661         I->getShuffleMask(), 2, NumSubElts, Index));
2662   }
2663   {
2664     auto *I = CreateShuffleWithMask(0, 1);
2665     int NumSubElts, Index;
2666     EXPECT_FALSE(I->isInsertSubvectorMask(NumSubElts, Index));
2667     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask(
2668         I->getShuffleMaskForBitcode(), 2, NumSubElts, Index));
2669     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask(
2670         I->getShuffleMask(), 2, NumSubElts, Index));
2671   }
2672 
2673   // isReplicationMask
2674   {
2675     auto *I = CreateShuffleWithMask(0, 0, 0, 1, 1, 1);
2676     int ReplicationFactor, VF;
2677     EXPECT_TRUE(I->isReplicationMask(ReplicationFactor, VF));
2678     EXPECT_EQ(ReplicationFactor, 3);
2679     EXPECT_EQ(VF, 2);
2680     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isReplicationMask(
2681         I->getShuffleMaskForBitcode(), ReplicationFactor, VF));
2682     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isReplicationMask(
2683         I->getShuffleMask(), ReplicationFactor, VF));
2684   }
2685   {
2686     auto *I = CreateShuffleWithMask(1, 2);
2687     int ReplicationFactor, VF;
2688     EXPECT_FALSE(I->isReplicationMask(ReplicationFactor, VF));
2689     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isReplicationMask(
2690         I->getShuffleMaskForBitcode(), ReplicationFactor, VF));
2691     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isReplicationMask(
2692         I->getShuffleMask(), ReplicationFactor, VF));
2693   }
2694 
2695   // isOneUseSingleSourceMask
2696   {
2697     auto *I = CreateShuffleWithMask(0, 1, 1, 0);
2698     EXPECT_TRUE(I->isOneUseSingleSourceMask(2));
2699     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isOneUseSingleSourceMask(
2700         I->getShuffleMask(), 2));
2701   }
2702   {
2703     auto *I = CreateShuffleWithMask(0, 1, 0, 0);
2704     EXPECT_FALSE(I->isOneUseSingleSourceMask(2));
2705     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isOneUseSingleSourceMask(
2706         I->getShuffleMask(), 2));
2707   }
2708 
2709   // commuteShuffleMask
2710   {
2711     SmallVector<int, 4> M = {0, 2, 1, 3};
2712     ShuffleVectorInst::commuteShuffleMask(M, 2);
2713     EXPECT_THAT(M, testing::ElementsAre(2, 0, 3, 1));
2714   }
2715 
2716   // isInterleave / isInterleaveMask
2717   {
2718     auto *I = CreateShuffleWithMask(0, 2, 1, 3);
2719     EXPECT_TRUE(I->isInterleave(2));
2720     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInterleaveMask(
2721         I->getShuffleMask(), 2, 4));
2722     SmallVector<unsigned, 4> StartIndexes;
2723     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInterleaveMask(
2724         I->getShuffleMask(), 2, 4, StartIndexes));
2725     EXPECT_THAT(StartIndexes, testing::ElementsAre(0, 2));
2726   }
2727   {
2728     auto *I = CreateShuffleWithMask(0, 3, 1, 2);
2729     EXPECT_FALSE(I->isInterleave(2));
2730     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isInterleaveMask(
2731         I->getShuffleMask(), 2, 4));
2732   }
2733 
2734   // isDeInterleaveMaskOfFactor
2735   {
2736     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isDeInterleaveMaskOfFactor(
2737         ArrayRef<int>({0, 2}), 2));
2738     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isDeInterleaveMaskOfFactor(
2739         ArrayRef<int>({0, 1}), 2));
2740 
2741     unsigned Index;
2742     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isDeInterleaveMaskOfFactor(
2743         ArrayRef<int>({1, 3}), 2, Index));
2744     EXPECT_EQ(Index, 1u);
2745   }
2746 
2747   // isBitRotateMask
2748   {
2749     unsigned NumSubElts, RotateAmt;
2750     EXPECT_TRUE(sandboxir::ShuffleVectorInst::isBitRotateMask(
2751         ArrayRef<int>({1, 0, 3, 2, 5, 4, 7, 6}), 8, 2, 2, NumSubElts,
2752         RotateAmt));
2753     EXPECT_EQ(NumSubElts, 2u);
2754     EXPECT_EQ(RotateAmt, 8u);
2755 
2756     EXPECT_FALSE(sandboxir::ShuffleVectorInst::isBitRotateMask(
2757         ArrayRef<int>({0, 7, 1, 6, 2, 5, 3, 4}), 8, 2, 2, NumSubElts,
2758         RotateAmt));
2759   }
2760 }
2761 
2762 TEST_F(SandboxIRTest, ExtractValueInst) {
2763   parseIR(C, R"IR(
2764 define void @foo({i32, float} %agg) {
2765   %ext_simple = extractvalue {i32, float} %agg, 0
2766   %ext_nested = extractvalue {float, {i32}} undef, 1, 0
2767   %const1 = extractvalue {i32, float} {i32 0, float 99.0}, 0
2768   ret void
2769 }
2770 )IR");
2771   Function &LLVMF = *M->getFunction("foo");
2772   auto *LLVMBB = &*LLVMF.begin();
2773   auto LLVMIt = LLVMBB->begin();
2774   [[maybe_unused]] auto *LLVMExtSimple =
2775       cast<llvm::ExtractValueInst>(&*LLVMIt++);
2776   auto *LLVMExtNested = cast<llvm::ExtractValueInst>(&*LLVMIt++);
2777 
2778   sandboxir::Context Ctx(C);
2779   auto &F = *Ctx.createFunction(&LLVMF);
2780   auto *ArgAgg = F.getArg(0);
2781   auto *BB = &*F.begin();
2782   auto It = BB->begin();
2783   auto *ExtSimple = cast<sandboxir::ExtractValueInst>(&*It++);
2784   auto *ExtNested = cast<sandboxir::ExtractValueInst>(&*It++);
2785   auto *Const1 = cast<sandboxir::ExtractValueInst>(&*It++);
2786   auto *Ret = &*It++;
2787 
2788   EXPECT_EQ(ExtSimple->getOperand(0), ArgAgg);
2789 
2790   // create before instruction
2791   auto *NewExtBeforeRet =
2792       cast<sandboxir::ExtractValueInst>(sandboxir::ExtractValueInst::create(
2793           ArgAgg, ArrayRef<unsigned>({0}), Ret->getIterator(), Ret->getParent(),
2794           Ctx, "NewExtBeforeRet"));
2795   EXPECT_EQ(NewExtBeforeRet->getNextNode(), Ret);
2796 #ifndef NDEBUG
2797   EXPECT_EQ(NewExtBeforeRet->getName(), "NewExtBeforeRet");
2798 #endif // NDEBUG
2799 
2800   // create at end of BB
2801   auto *NewExtAtEnd =
2802       cast<sandboxir::ExtractValueInst>(sandboxir::ExtractValueInst::create(
2803           ArgAgg, ArrayRef<unsigned>({0}), BB->end(), BB, Ctx, "NewExtAtEnd"));
2804   EXPECT_EQ(NewExtAtEnd->getPrevNode(), Ret);
2805 #ifndef NDEBUG
2806   EXPECT_EQ(NewExtAtEnd->getName(), "NewExtAtEnd");
2807 #endif // NDEBUG
2808 
2809   // Test the path that creates a folded constant.
2810   auto *ShouldBeConstant = sandboxir::ExtractValueInst::create(
2811       Const1->getOperand(0), ArrayRef<unsigned>({0}), BB->end(), BB, Ctx);
2812   EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant));
2813 
2814   auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0);
2815   EXPECT_EQ(ShouldBeConstant, Zero);
2816 
2817   // getIndexedType
2818   sandboxir::Type *AggType = ExtNested->getAggregateOperand()->getType();
2819   llvm::Type *LLVMAggType = LLVMExtNested->getAggregateOperand()->getType();
2820   EXPECT_EQ(sandboxir::ExtractValueInst::getIndexedType(
2821                 AggType, ArrayRef<unsigned>({1, 0})),
2822             Ctx.getType(llvm::ExtractValueInst::getIndexedType(
2823                 LLVMAggType, ArrayRef<unsigned>({1, 0}))));
2824 
2825   EXPECT_EQ(sandboxir::ExtractValueInst::getIndexedType(
2826                 AggType, ArrayRef<unsigned>({2})),
2827             nullptr);
2828 
2829   // idx_begin / idx_end
2830   {
2831     SmallVector<int, 2> IndicesSimple(ExtSimple->idx_begin(),
2832                                       ExtSimple->idx_end());
2833     EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
2834 
2835     SmallVector<int, 2> IndicesNested(ExtNested->idx_begin(),
2836                                       ExtNested->idx_end());
2837     EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
2838   }
2839 
2840   // indices
2841   {
2842     SmallVector<int, 2> IndicesSimple(ExtSimple->indices());
2843     EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
2844 
2845     SmallVector<int, 2> IndicesNested(ExtNested->indices());
2846     EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
2847   }
2848 
2849   // getAggregateOperand
2850   EXPECT_EQ(ExtSimple->getAggregateOperand(), ArgAgg);
2851   const auto *ConstExtSimple = ExtSimple;
2852   EXPECT_EQ(ConstExtSimple->getAggregateOperand(), ArgAgg);
2853 
2854   // getAggregateOperandIndex
2855   EXPECT_EQ(sandboxir::ExtractValueInst::getAggregateOperandIndex(),
2856             llvm::ExtractValueInst::getAggregateOperandIndex());
2857 
2858   // getIndices
2859   EXPECT_EQ(ExtSimple->getIndices().size(), 1u);
2860   EXPECT_EQ(ExtSimple->getIndices()[0], 0u);
2861 
2862   // getNumIndices
2863   EXPECT_EQ(ExtSimple->getNumIndices(), 1u);
2864 
2865   // hasIndices
2866   EXPECT_EQ(ExtSimple->hasIndices(), true);
2867 }
2868 
2869 TEST_F(SandboxIRTest, InsertValueInst) {
2870   parseIR(C, R"IR(
2871 define void @foo({i32, float} %agg, i32 %i) {
2872   %ins_simple = insertvalue {i32, float} %agg, i32 %i, 0
2873   %ins_nested = insertvalue {float, {i32}} undef, i32 %i, 1, 0
2874   %const1 = insertvalue {i32, float} {i32 99, float 99.0}, i32 %i, 0
2875   %const2 = insertvalue {i32, float} {i32 0, float 99.0}, i32 %i, 0
2876   ret void
2877 }
2878 )IR");
2879   Function &LLVMF = *M->getFunction("foo");
2880   sandboxir::Context Ctx(C);
2881   auto &F = *Ctx.createFunction(&LLVMF);
2882   auto *ArgAgg = F.getArg(0);
2883   auto *ArgInt = F.getArg(1);
2884   auto *BB = &*F.begin();
2885   auto It = BB->begin();
2886   auto *InsSimple = cast<sandboxir::InsertValueInst>(&*It++);
2887   auto *InsNested = cast<sandboxir::InsertValueInst>(&*It++);
2888   // These "const" instructions are helpers to create constant struct operands.
2889   // TODO: Remove them once sandboxir::ConstantStruct gets added.
2890   auto *Const1 = cast<sandboxir::InsertValueInst>(&*It++);
2891   auto *Const2 = cast<sandboxir::InsertValueInst>(&*It++);
2892   auto *Ret = &*It++;
2893 
2894   EXPECT_EQ(InsSimple->getOperand(0), ArgAgg);
2895   EXPECT_EQ(InsSimple->getOperand(1), ArgInt);
2896 
2897   // create before instruction
2898   auto *NewInsBeforeRet =
2899       cast<sandboxir::InsertValueInst>(sandboxir::InsertValueInst::create(
2900           ArgAgg, ArgInt, ArrayRef<unsigned>({0}), Ret->getIterator(),
2901           Ret->getParent(), Ctx, "NewInsBeforeRet"));
2902   EXPECT_EQ(NewInsBeforeRet->getNextNode(), Ret);
2903 #ifndef NDEBUG
2904   EXPECT_EQ(NewInsBeforeRet->getName(), "NewInsBeforeRet");
2905 #endif // NDEBUG
2906 
2907   // create at end of BB
2908   auto *NewInsAtEnd =
2909       cast<sandboxir::InsertValueInst>(sandboxir::InsertValueInst::create(
2910           ArgAgg, ArgInt, ArrayRef<unsigned>({0}), BB->end(), BB, Ctx,
2911           "NewInsAtEnd"));
2912   EXPECT_EQ(NewInsAtEnd->getPrevNode(), Ret);
2913 #ifndef NDEBUG
2914   EXPECT_EQ(NewInsAtEnd->getName(), "NewInsAtEnd");
2915 #endif // NDEBUG
2916 
2917   // Test the path that creates a folded constant.
2918   auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0);
2919   auto *ShouldBeConstant = sandboxir::InsertValueInst::create(
2920       Const1->getOperand(0), Zero, ArrayRef<unsigned>({0}), BB->end(), BB, Ctx);
2921   auto *ExpectedConstant = Const2->getOperand(0);
2922   EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant));
2923   EXPECT_EQ(ShouldBeConstant, ExpectedConstant);
2924 
2925   // idx_begin / idx_end
2926   {
2927     SmallVector<int, 2> IndicesSimple(InsSimple->idx_begin(),
2928                                       InsSimple->idx_end());
2929     EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
2930 
2931     SmallVector<int, 2> IndicesNested(InsNested->idx_begin(),
2932                                       InsNested->idx_end());
2933     EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
2934   }
2935 
2936   // indices
2937   {
2938     SmallVector<int, 2> IndicesSimple(InsSimple->indices());
2939     EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
2940 
2941     SmallVector<int, 2> IndicesNested(InsNested->indices());
2942     EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
2943   }
2944 
2945   // getAggregateOperand
2946   EXPECT_EQ(InsSimple->getAggregateOperand(), ArgAgg);
2947   const auto *ConstInsSimple = InsSimple;
2948   EXPECT_EQ(ConstInsSimple->getAggregateOperand(), ArgAgg);
2949 
2950   // getAggregateOperandIndex
2951   EXPECT_EQ(sandboxir::InsertValueInst::getAggregateOperandIndex(),
2952             llvm::InsertValueInst::getAggregateOperandIndex());
2953 
2954   // getInsertedValueOperand
2955   EXPECT_EQ(InsSimple->getInsertedValueOperand(), ArgInt);
2956   EXPECT_EQ(ConstInsSimple->getInsertedValueOperand(), ArgInt);
2957 
2958   // getInsertedValueOperandIndex
2959   EXPECT_EQ(sandboxir::InsertValueInst::getInsertedValueOperandIndex(),
2960             llvm::InsertValueInst::getInsertedValueOperandIndex());
2961 
2962   // getIndices
2963   EXPECT_EQ(InsSimple->getIndices().size(), 1u);
2964   EXPECT_EQ(InsSimple->getIndices()[0], 0u);
2965 
2966   // getNumIndices
2967   EXPECT_EQ(InsSimple->getNumIndices(), 1u);
2968 
2969   // hasIndices
2970   EXPECT_EQ(InsSimple->hasIndices(), true);
2971 }
2972 
2973 TEST_F(SandboxIRTest, BranchInst) {
2974   parseIR(C, R"IR(
2975 define void @foo(i1 %cond0, i1 %cond2) {
2976  bb0:
2977    br i1 %cond0, label %bb1, label %bb2
2978  bb1:
2979    ret void
2980  bb2:
2981    ret void
2982 }
2983 )IR");
2984   llvm::Function *LLVMF = &*M->getFunction("foo");
2985   sandboxir::Context Ctx(C);
2986   sandboxir::Function *F = Ctx.createFunction(LLVMF);
2987   auto *Cond0 = F->getArg(0);
2988   auto *Cond1 = F->getArg(1);
2989   auto *BB0 = cast<sandboxir::BasicBlock>(
2990       Ctx.getValue(getBasicBlockByName(*LLVMF, "bb0")));
2991   auto *BB1 = cast<sandboxir::BasicBlock>(
2992       Ctx.getValue(getBasicBlockByName(*LLVMF, "bb1")));
2993   auto *Ret1 = BB1->getTerminator();
2994   auto *BB2 = cast<sandboxir::BasicBlock>(
2995       Ctx.getValue(getBasicBlockByName(*LLVMF, "bb2")));
2996   auto *Ret2 = BB2->getTerminator();
2997   auto It = BB0->begin();
2998   auto *Br0 = cast<sandboxir::BranchInst>(&*It++);
2999   // Check isUnconditional().
3000   EXPECT_FALSE(Br0->isUnconditional());
3001   // Check isConditional().
3002   EXPECT_TRUE(Br0->isConditional());
3003   // Check getCondition().
3004   EXPECT_EQ(Br0->getCondition(), Cond0);
3005   // Check setCondition().
3006   Br0->setCondition(Cond1);
3007   EXPECT_EQ(Br0->getCondition(), Cond1);
3008   // Check getNumSuccessors().
3009   EXPECT_EQ(Br0->getNumSuccessors(), 2u);
3010   // Check getSuccessor().
3011   EXPECT_EQ(Br0->getSuccessor(0), BB1);
3012   EXPECT_EQ(Br0->getSuccessor(1), BB2);
3013   // Check swapSuccessors().
3014   Br0->swapSuccessors();
3015   EXPECT_EQ(Br0->getSuccessor(0), BB2);
3016   EXPECT_EQ(Br0->getSuccessor(1), BB1);
3017   // Check successors().
3018   EXPECT_EQ(range_size(Br0->successors()), 2u);
3019   unsigned SuccIdx = 0;
3020   SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1, BB2});
3021   for (sandboxir::BasicBlock *Succ : Br0->successors())
3022     EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
3023 
3024   {
3025     // Check unconditional BranchInst::create() InsertBefore.
3026     auto *Br = sandboxir::BranchInst::create(BB1, /*InsertBefore=*/Ret1, Ctx);
3027     EXPECT_FALSE(Br->isConditional());
3028     EXPECT_TRUE(Br->isUnconditional());
3029 #ifndef NDEBUG
3030     EXPECT_DEATH(Br->getCondition(), ".*condition.*");
3031 #endif // NDEBUG
3032     unsigned SuccIdx = 0;
3033     SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1});
3034     for (sandboxir::BasicBlock *Succ : Br->successors())
3035       EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
3036     EXPECT_EQ(Br->getNextNode(), Ret1);
3037   }
3038   {
3039     // Check unconditional BranchInst::create() InsertAtEnd.
3040     auto *Br = sandboxir::BranchInst::create(BB1, /*InsertAtEnd=*/BB1, Ctx);
3041     EXPECT_FALSE(Br->isConditional());
3042     EXPECT_TRUE(Br->isUnconditional());
3043 #ifndef NDEBUG
3044     EXPECT_DEATH(Br->getCondition(), ".*condition.*");
3045 #endif // NDEBUG
3046     unsigned SuccIdx = 0;
3047     SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1});
3048     for (sandboxir::BasicBlock *Succ : Br->successors())
3049       EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
3050     EXPECT_EQ(Br->getPrevNode(), Ret1);
3051   }
3052   {
3053     // Check conditional BranchInst::create() InsertBefore.
3054     auto *Br = sandboxir::BranchInst::create(BB1, BB2, Cond0,
3055                                              /*InsertBefore=*/Ret1, Ctx);
3056     EXPECT_TRUE(Br->isConditional());
3057     EXPECT_EQ(Br->getCondition(), Cond0);
3058     unsigned SuccIdx = 0;
3059     SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB2, BB1});
3060     for (sandboxir::BasicBlock *Succ : Br->successors())
3061       EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
3062     EXPECT_EQ(Br->getNextNode(), Ret1);
3063   }
3064   {
3065     // Check conditional BranchInst::create() InsertAtEnd.
3066     auto *Br = sandboxir::BranchInst::create(BB1, BB2, Cond0,
3067                                              /*InsertAtEnd=*/BB2, Ctx);
3068     EXPECT_TRUE(Br->isConditional());
3069     EXPECT_EQ(Br->getCondition(), Cond0);
3070     unsigned SuccIdx = 0;
3071     SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB2, BB1});
3072     for (sandboxir::BasicBlock *Succ : Br->successors())
3073       EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
3074     EXPECT_EQ(Br->getPrevNode(), Ret2);
3075   }
3076 }
3077 
3078 TEST_F(SandboxIRTest, LoadInst) {
3079   parseIR(C, R"IR(
3080 define void @foo(ptr %arg0, ptr %arg1) {
3081   %ld = load i8, ptr %arg0, align 64
3082   %vld = load volatile i8, ptr %arg0, align 64
3083   ret void
3084 }
3085 )IR");
3086   llvm::Function *LLVMF = &*M->getFunction("foo");
3087   sandboxir::Context Ctx(C);
3088   sandboxir::Function *F = Ctx.createFunction(LLVMF);
3089   auto *Arg0 = F->getArg(0);
3090   auto *Arg1 = F->getArg(1);
3091   auto *BB = &*F->begin();
3092   auto It = BB->begin();
3093   auto *Ld = cast<sandboxir::LoadInst>(&*It++);
3094   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Ld));
3095   auto *VLd = cast<sandboxir::LoadInst>(&*It++);
3096   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
3097   bool OrigVolatileValue;
3098 
3099   // Check isVolatile()
3100   EXPECT_FALSE(Ld->isVolatile());
3101   // Check isVolatile()
3102   EXPECT_TRUE(VLd->isVolatile());
3103   // Check getPointerOperand()
3104   EXPECT_EQ(Ld->getPointerOperand(), Arg0);
3105   // Check getAlign()
3106   EXPECT_EQ(Ld->getAlign(), 64);
3107   // Check create(InsertBefore)
3108   sandboxir::LoadInst *NewLd =
3109       sandboxir::LoadInst::create(Ld->getType(), Arg1, Align(8),
3110                                   /*InsertBefore=*/Ret, Ctx, "NewLd");
3111   EXPECT_FALSE(NewLd->isVolatile());
3112   OrigVolatileValue = NewLd->isVolatile();
3113   NewLd->setVolatile(true);
3114   EXPECT_TRUE(NewLd->isVolatile());
3115   NewLd->setVolatile(OrigVolatileValue);
3116   EXPECT_FALSE(NewLd->isVolatile());
3117   EXPECT_EQ(NewLd->getType(), Ld->getType());
3118   EXPECT_EQ(NewLd->getPointerOperand(), Arg1);
3119   EXPECT_EQ(NewLd->getAlign(), 8);
3120   EXPECT_EQ(NewLd->getName(), "NewLd");
3121   // Check create(InsertBefore, IsVolatile=true)
3122   sandboxir::LoadInst *NewVLd =
3123       sandboxir::LoadInst::create(VLd->getType(), Arg1, Align(8),
3124                                   /*InsertBefore=*/Ret,
3125                                   /*IsVolatile=*/true, Ctx, "NewVLd");
3126 
3127   EXPECT_TRUE(NewVLd->isVolatile());
3128   OrigVolatileValue = NewVLd->isVolatile();
3129   NewVLd->setVolatile(false);
3130   EXPECT_FALSE(NewVLd->isVolatile());
3131   NewVLd->setVolatile(OrigVolatileValue);
3132   EXPECT_TRUE(NewVLd->isVolatile());
3133   EXPECT_EQ(NewVLd->getName(), "NewVLd");
3134   // Check create(InsertAtEnd)
3135   sandboxir::LoadInst *NewLdEnd =
3136       sandboxir::LoadInst::create(Ld->getType(), Arg1, Align(8),
3137                                   /*InsertAtEnd=*/BB, Ctx, "NewLdEnd");
3138   EXPECT_FALSE(NewLdEnd->isVolatile());
3139   EXPECT_EQ(NewLdEnd->getName(), "NewLdEnd");
3140   EXPECT_EQ(NewLdEnd->getType(), Ld->getType());
3141   EXPECT_EQ(NewLdEnd->getPointerOperand(), Arg1);
3142   EXPECT_EQ(NewLdEnd->getAlign(), 8);
3143   EXPECT_EQ(NewLdEnd->getParent(), BB);
3144   EXPECT_EQ(NewLdEnd->getNextNode(), nullptr);
3145   // Check create(InsertAtEnd, IsVolatile=true)
3146   sandboxir::LoadInst *NewVLdEnd =
3147       sandboxir::LoadInst::create(VLd->getType(), Arg1, Align(8),
3148                                   /*InsertAtEnd=*/BB,
3149                                   /*IsVolatile=*/true, Ctx, "NewVLdEnd");
3150   EXPECT_TRUE(NewVLdEnd->isVolatile());
3151   EXPECT_EQ(NewVLdEnd->getName(), "NewVLdEnd");
3152   EXPECT_EQ(NewVLdEnd->getType(), VLd->getType());
3153   EXPECT_EQ(NewVLdEnd->getPointerOperand(), Arg1);
3154   EXPECT_EQ(NewVLdEnd->getAlign(), 8);
3155   EXPECT_EQ(NewVLdEnd->getParent(), BB);
3156   EXPECT_EQ(NewVLdEnd->getNextNode(), nullptr);
3157 }
3158 
3159 TEST_F(SandboxIRTest, StoreInst) {
3160   parseIR(C, R"IR(
3161 define void @foo(i8 %val, ptr %ptr) {
3162   store i8 %val, ptr %ptr, align 64
3163   store volatile i8 %val, ptr %ptr, align 64
3164   ret void
3165 }
3166 )IR");
3167   llvm::Function *LLVMF = &*M->getFunction("foo");
3168   sandboxir::Context Ctx(C);
3169   sandboxir::Function *F = Ctx.createFunction(LLVMF);
3170   auto *Val = F->getArg(0);
3171   auto *Ptr = F->getArg(1);
3172   auto *BB = &*F->begin();
3173   auto It = BB->begin();
3174   auto *St = cast<sandboxir::StoreInst>(&*It++);
3175   auto *VSt = cast<sandboxir::StoreInst>(&*It++);
3176   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
3177   bool OrigVolatileValue;
3178 
3179   // Check that the StoreInst has been created correctly.
3180   EXPECT_FALSE(St->isVolatile());
3181   EXPECT_TRUE(VSt->isVolatile());
3182   // Check getPointerOperand()
3183   EXPECT_EQ(St->getValueOperand(), Val);
3184   EXPECT_EQ(St->getPointerOperand(), Ptr);
3185   // Check getAlign()
3186   EXPECT_EQ(St->getAlign(), 64);
3187   // Check create(InsertBefore)
3188   sandboxir::StoreInst *NewSt =
3189       sandboxir::StoreInst::create(Val, Ptr, Align(8),
3190                                    /*InsertBefore=*/Ret, Ctx);
3191   EXPECT_FALSE(NewSt->isVolatile());
3192   OrigVolatileValue = NewSt->isVolatile();
3193   NewSt->setVolatile(true);
3194   EXPECT_TRUE(NewSt->isVolatile());
3195   NewSt->setVolatile(OrigVolatileValue);
3196   EXPECT_FALSE(NewSt->isVolatile());
3197   EXPECT_EQ(NewSt->getType(), St->getType());
3198   EXPECT_EQ(NewSt->getValueOperand(), Val);
3199   EXPECT_EQ(NewSt->getPointerOperand(), Ptr);
3200   EXPECT_EQ(NewSt->getAlign(), 8);
3201   EXPECT_EQ(NewSt->getNextNode(), Ret);
3202   // Check create(InsertBefore, IsVolatile=true)
3203   sandboxir::StoreInst *NewVSt =
3204       sandboxir::StoreInst::create(Val, Ptr, Align(8),
3205                                    /*InsertBefore=*/Ret,
3206                                    /*IsVolatile=*/true, Ctx);
3207   EXPECT_TRUE(NewVSt->isVolatile());
3208   OrigVolatileValue = NewVSt->isVolatile();
3209   NewVSt->setVolatile(false);
3210   EXPECT_FALSE(NewVSt->isVolatile());
3211   NewVSt->setVolatile(OrigVolatileValue);
3212   EXPECT_TRUE(NewVSt->isVolatile());
3213   EXPECT_EQ(NewVSt->getType(), VSt->getType());
3214   EXPECT_EQ(NewVSt->getValueOperand(), Val);
3215   EXPECT_EQ(NewVSt->getPointerOperand(), Ptr);
3216   EXPECT_EQ(NewVSt->getAlign(), 8);
3217   EXPECT_EQ(NewVSt->getNextNode(), Ret);
3218   // Check create(InsertAtEnd)
3219   sandboxir::StoreInst *NewStEnd =
3220       sandboxir::StoreInst::create(Val, Ptr, Align(8),
3221                                    /*InsertAtEnd=*/BB, Ctx);
3222   EXPECT_FALSE(NewStEnd->isVolatile());
3223   EXPECT_EQ(NewStEnd->getType(), St->getType());
3224   EXPECT_EQ(NewStEnd->getValueOperand(), Val);
3225   EXPECT_EQ(NewStEnd->getPointerOperand(), Ptr);
3226   EXPECT_EQ(NewStEnd->getAlign(), 8);
3227   EXPECT_EQ(NewStEnd->getParent(), BB);
3228   EXPECT_EQ(NewStEnd->getNextNode(), nullptr);
3229   // Check create(InsertAtEnd, IsVolatile=true)
3230   sandboxir::StoreInst *NewVStEnd =
3231       sandboxir::StoreInst::create(Val, Ptr, Align(8),
3232                                    /*InsertAtEnd=*/BB,
3233                                    /*IsVolatile=*/true, Ctx);
3234   EXPECT_TRUE(NewVStEnd->isVolatile());
3235   EXPECT_EQ(NewVStEnd->getType(), VSt->getType());
3236   EXPECT_EQ(NewVStEnd->getValueOperand(), Val);
3237   EXPECT_EQ(NewVStEnd->getPointerOperand(), Ptr);
3238   EXPECT_EQ(NewVStEnd->getAlign(), 8);
3239   EXPECT_EQ(NewVStEnd->getParent(), BB);
3240   EXPECT_EQ(NewVStEnd->getNextNode(), nullptr);
3241 }
3242 
3243 TEST_F(SandboxIRTest, ReturnInst) {
3244   parseIR(C, R"IR(
3245 define i8 @foo(i8 %val) {
3246   %add = add i8 %val, 42
3247   ret i8 %val
3248 }
3249 )IR");
3250   llvm::Function *LLVMF = &*M->getFunction("foo");
3251   sandboxir::Context Ctx(C);
3252   sandboxir::Function *F = Ctx.createFunction(LLVMF);
3253   auto *Val = F->getArg(0);
3254   auto *BB = &*F->begin();
3255   auto It = BB->begin();
3256   It++;
3257   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
3258 
3259   // Check that the ReturnInst has been created correctly.
3260   // Check getReturnValue().
3261   EXPECT_EQ(Ret->getReturnValue(), Val);
3262 
3263   // Check create(InsertBefore) a void ReturnInst.
3264   auto *NewRet1 = cast<sandboxir::ReturnInst>(
3265       sandboxir::ReturnInst::create(nullptr, /*InsertBefore=*/Ret, Ctx));
3266   EXPECT_EQ(NewRet1->getReturnValue(), nullptr);
3267   // Check create(InsertBefore) a non-void ReturnInst.
3268   auto *NewRet2 = cast<sandboxir::ReturnInst>(
3269       sandboxir::ReturnInst::create(Val, /*InsertBefore=*/Ret, Ctx));
3270   EXPECT_EQ(NewRet2->getReturnValue(), Val);
3271 
3272   // Check create(InsertAtEnd) a void ReturnInst.
3273   auto *NewRet3 = cast<sandboxir::ReturnInst>(
3274       sandboxir::ReturnInst::create(nullptr, /*InsertAtEnd=*/BB, Ctx));
3275   EXPECT_EQ(NewRet3->getReturnValue(), nullptr);
3276   // Check create(InsertAtEnd) a non-void ReturnInst.
3277   auto *NewRet4 = cast<sandboxir::ReturnInst>(
3278       sandboxir::ReturnInst::create(Val, /*InsertAtEnd=*/BB, Ctx));
3279   EXPECT_EQ(NewRet4->getReturnValue(), Val);
3280 }
3281 
3282 TEST_F(SandboxIRTest, CallBase) {
3283   parseIR(C, R"IR(
3284 declare void @bar1(i8)
3285 declare void @bar2()
3286 declare void @bar3()
3287 declare void @variadic(ptr, ...)
3288 
3289 define i8 @foo(i8 %arg0, i32 %arg1, ptr %indirectFoo) {
3290   %call = call i8 @foo(i8 %arg0, i32 %arg1)
3291   call void @bar1(i8 %arg0)
3292   call void @bar2()
3293   call void %indirectFoo()
3294   call void @bar2() noreturn
3295   tail call fastcc void @bar2()
3296   call void (ptr, ...) @variadic(ptr %indirectFoo, i32 1)
3297   ret i8 %call
3298 }
3299 )IR");
3300   llvm::Function &LLVMF = *M->getFunction("foo");
3301   unsigned ArgIdx = 0;
3302   llvm::Argument *LLVMArg0 = LLVMF.getArg(ArgIdx++);
3303   llvm::Argument *LLVMArg1 = LLVMF.getArg(ArgIdx++);
3304   llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
3305   SmallVector<llvm::CallBase *, 8> LLVMCalls;
3306   auto LLVMIt = LLVMBB->begin();
3307   while (isa<llvm::CallBase>(&*LLVMIt))
3308     LLVMCalls.push_back(cast<llvm::CallBase>(&*LLVMIt++));
3309 
3310   sandboxir::Context Ctx(C);
3311   sandboxir::Function &F = *Ctx.createFunction(&LLVMF);
3312 
3313   for (llvm::CallBase *LLVMCall : LLVMCalls) {
3314     // Check classof(Instruction *).
3315     auto *Call = cast<sandboxir::CallBase>(Ctx.getValue(LLVMCall));
3316     // Check classof(Value *).
3317     EXPECT_TRUE(isa<sandboxir::CallBase>((sandboxir::Value *)Call));
3318     // Check getFunctionType().
3319     EXPECT_EQ(Call->getFunctionType(),
3320               Ctx.getType(LLVMCall->getFunctionType()));
3321     // Check data_ops().
3322     EXPECT_EQ(range_size(Call->data_ops()), range_size(LLVMCall->data_ops()));
3323     auto DataOpIt = Call->data_operands_begin();
3324     for (llvm::Use &LLVMUse : LLVMCall->data_ops()) {
3325       Value *LLVMOp = LLVMUse.get();
3326       sandboxir::Use Use = *DataOpIt++;
3327       EXPECT_EQ(Ctx.getValue(LLVMOp), Use.get());
3328       // Check isDataOperand().
3329       EXPECT_EQ(Call->isDataOperand(Use), LLVMCall->isDataOperand(&LLVMUse));
3330       // Check getDataOperandNo().
3331       EXPECT_EQ(Call->getDataOperandNo(Use),
3332                 LLVMCall->getDataOperandNo(&LLVMUse));
3333       // Check isArgOperand().
3334       EXPECT_EQ(Call->isArgOperand(Use), LLVMCall->isArgOperand(&LLVMUse));
3335       // Check isCallee().
3336       EXPECT_EQ(Call->isCallee(Use), LLVMCall->isCallee(&LLVMUse));
3337     }
3338     // Check data_operands_empty().
3339     EXPECT_EQ(Call->data_operands_empty(), LLVMCall->data_operands_empty());
3340     // Check data_operands_size().
3341     EXPECT_EQ(Call->data_operands_size(), LLVMCall->data_operands_size());
3342     // Check getNumTotalBundleOperands().
3343     EXPECT_EQ(Call->getNumTotalBundleOperands(),
3344               LLVMCall->getNumTotalBundleOperands());
3345     // Check args().
3346     EXPECT_EQ(range_size(Call->args()), range_size(LLVMCall->args()));
3347     auto ArgIt = Call->arg_begin();
3348     for (llvm::Use &LLVMUse : LLVMCall->args()) {
3349       Value *LLVMArg = LLVMUse.get();
3350       sandboxir::Use Use = *ArgIt++;
3351       EXPECT_EQ(Ctx.getValue(LLVMArg), Use.get());
3352     }
3353     // Check arg_empty().
3354     EXPECT_EQ(Call->arg_empty(), LLVMCall->arg_empty());
3355     // Check arg_size().
3356     EXPECT_EQ(Call->arg_size(), LLVMCall->arg_size());
3357     for (unsigned ArgIdx = 0, E = Call->arg_size(); ArgIdx != E; ++ArgIdx) {
3358       // Check getArgOperand().
3359       EXPECT_EQ(Call->getArgOperand(ArgIdx),
3360                 Ctx.getValue(LLVMCall->getArgOperand(ArgIdx)));
3361       // Check getArgOperandUse().
3362       sandboxir::Use Use = Call->getArgOperandUse(ArgIdx);
3363       llvm::Use &LLVMUse = LLVMCall->getArgOperandUse(ArgIdx);
3364       EXPECT_EQ(Use.get(), Ctx.getValue(LLVMUse.get()));
3365       // Check getArgOperandNo().
3366       EXPECT_EQ(Call->getArgOperandNo(Use),
3367                 LLVMCall->getArgOperandNo(&LLVMUse));
3368     }
3369     // Check hasArgument().
3370     SmallVector<llvm::Value *> TestArgs(
3371         {LLVMArg0, LLVMArg1, &LLVMF, LLVMBB, LLVMCall});
3372     for (llvm::Value *LLVMV : TestArgs) {
3373       sandboxir::Value *V = Ctx.getValue(LLVMV);
3374       EXPECT_EQ(Call->hasArgument(V), LLVMCall->hasArgument(LLVMV));
3375     }
3376     // Check getCalledOperand().
3377     EXPECT_EQ(Call->getCalledOperand(),
3378               Ctx.getValue(LLVMCall->getCalledOperand()));
3379     // Check getCalledOperandUse().
3380     EXPECT_EQ(Call->getCalledOperandUse().get(),
3381               Ctx.getValue(LLVMCall->getCalledOperandUse()));
3382     // Check getCalledFunction().
3383     if (LLVMCall->getCalledFunction() == nullptr)
3384       EXPECT_EQ(Call->getCalledFunction(), nullptr);
3385     else {
3386       auto *LLVMCF = cast<llvm::Function>(LLVMCall->getCalledFunction());
3387       (void)LLVMCF;
3388       EXPECT_EQ(Call->getCalledFunction(),
3389                 cast<sandboxir::Function>(
3390                     Ctx.getValue(LLVMCall->getCalledFunction())));
3391     }
3392     // Check isIndirectCall().
3393     EXPECT_EQ(Call->isIndirectCall(), LLVMCall->isIndirectCall());
3394     // Check getCaller().
3395     EXPECT_EQ(Call->getCaller(), Ctx.getValue(LLVMCall->getCaller()));
3396     // Check isMustTailCall().
3397     EXPECT_EQ(Call->isMustTailCall(), LLVMCall->isMustTailCall());
3398     // Check isTailCall().
3399     EXPECT_EQ(Call->isTailCall(), LLVMCall->isTailCall());
3400     // Check getIntrinsicID().
3401     EXPECT_EQ(Call->getIntrinsicID(), LLVMCall->getIntrinsicID());
3402     // Check getCallingConv().
3403     EXPECT_EQ(Call->getCallingConv(), LLVMCall->getCallingConv());
3404     // Check isInlineAsm().
3405     EXPECT_EQ(Call->isInlineAsm(), LLVMCall->isInlineAsm());
3406   }
3407 
3408   auto *Arg0 = F.getArg(0);
3409   auto *Arg1 = F.getArg(1);
3410   auto *BB = &*F.begin();
3411   auto It = BB->begin();
3412   auto *Call0 = cast<sandboxir::CallBase>(&*It++);
3413   [[maybe_unused]] auto *Call1 = cast<sandboxir::CallBase>(&*It++);
3414   auto *Call2 = cast<sandboxir::CallBase>(&*It++);
3415   // Check setArgOperand
3416   Call0->setArgOperand(0, Arg1);
3417   EXPECT_EQ(Call0->getArgOperand(0), Arg1);
3418   Call0->setArgOperand(0, Arg0);
3419   EXPECT_EQ(Call0->getArgOperand(0), Arg0);
3420 
3421   auto *Bar3F = Ctx.createFunction(M->getFunction("bar3"));
3422 
3423   // Check setCalledOperand
3424   auto *SvOp = Call0->getCalledOperand();
3425   Call0->setCalledOperand(Bar3F);
3426   EXPECT_EQ(Call0->getCalledOperand(), Bar3F);
3427   Call0->setCalledOperand(SvOp);
3428   // Check setCalledFunction
3429   Call2->setCalledFunction(Bar3F);
3430   EXPECT_EQ(Call2->getCalledFunction(), Bar3F);
3431 }
3432 
3433 TEST_F(SandboxIRTest, CallInst) {
3434   parseIR(C, R"IR(
3435 define i8 @foo(i8 %arg) {
3436   %call = call i8 @foo(i8 %arg)
3437   ret i8 %call
3438 }
3439 )IR");
3440   Function &LLVMF = *M->getFunction("foo");
3441   sandboxir::Context Ctx(C);
3442   auto &F = *Ctx.createFunction(&LLVMF);
3443   unsigned ArgIdx = 0;
3444   auto *Arg0 = F.getArg(ArgIdx++);
3445   auto *BB = &*F.begin();
3446   auto It = BB->begin();
3447   auto *Call = cast<sandboxir::CallInst>(&*It++);
3448   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
3449   EXPECT_EQ(Call->getNumOperands(), 2u);
3450   EXPECT_EQ(Ret->getOpcode(), sandboxir::Instruction::Opcode::Ret);
3451   sandboxir::FunctionType *FTy = F.getFunctionType();
3452   SmallVector<sandboxir::Value *, 1> Args;
3453   Args.push_back(Arg0);
3454   {
3455     // Check create() WhereIt.
3456     auto *Call = cast<sandboxir::CallInst>(sandboxir::CallInst::create(
3457         FTy, &F, Args, /*WhereIt=*/Ret->getIterator(), BB, Ctx));
3458     EXPECT_EQ(Call->getNextNode(), Ret);
3459     EXPECT_EQ(Call->getCalledFunction(), &F);
3460     EXPECT_EQ(range_size(Call->args()), 1u);
3461     EXPECT_EQ(Call->getArgOperand(0), Arg0);
3462   }
3463   {
3464     // Check create() InsertBefore.
3465     auto *Call = cast<sandboxir::CallInst>(
3466         sandboxir::CallInst::create(FTy, &F, Args, /*InsertBefore=*/Ret, Ctx));
3467     EXPECT_EQ(Call->getNextNode(), Ret);
3468     EXPECT_EQ(Call->getCalledFunction(), &F);
3469     EXPECT_EQ(range_size(Call->args()), 1u);
3470     EXPECT_EQ(Call->getArgOperand(0), Arg0);
3471   }
3472   {
3473     // Check create() InsertAtEnd.
3474     auto *Call = cast<sandboxir::CallInst>(
3475         sandboxir::CallInst::create(FTy, &F, Args, /*InsertAtEnd=*/BB, Ctx));
3476     EXPECT_EQ(Call->getPrevNode(), Ret);
3477     EXPECT_EQ(Call->getCalledFunction(), &F);
3478     EXPECT_EQ(range_size(Call->args()), 1u);
3479     EXPECT_EQ(Call->getArgOperand(0), Arg0);
3480   }
3481 }
3482 
3483 TEST_F(SandboxIRTest, InvokeInst) {
3484   parseIR(C, R"IR(
3485 define void @foo(i8 %arg) {
3486  bb0:
3487    invoke i8 @foo(i8 %arg) to label %normal_bb
3488                        unwind label %exception_bb
3489  normal_bb:
3490    ret void
3491  exception_bb:
3492    %lpad = landingpad { ptr, i32}
3493            cleanup
3494    ret void
3495  other_bb:
3496    ret void
3497 }
3498 )IR");
3499   Function &LLVMF = *M->getFunction("foo");
3500   sandboxir::Context Ctx(C);
3501   auto &F = *Ctx.createFunction(&LLVMF);
3502   auto *Arg = F.getArg(0);
3503   auto *BB0 = cast<sandboxir::BasicBlock>(
3504       Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
3505   auto *NormalBB = cast<sandboxir::BasicBlock>(
3506       Ctx.getValue(getBasicBlockByName(LLVMF, "normal_bb")));
3507   auto *ExceptionBB = cast<sandboxir::BasicBlock>(
3508       Ctx.getValue(getBasicBlockByName(LLVMF, "exception_bb")));
3509   auto *LandingPad = &*ExceptionBB->begin();
3510   auto *OtherBB = cast<sandboxir::BasicBlock>(
3511       Ctx.getValue(getBasicBlockByName(LLVMF, "other_bb")));
3512   auto It = BB0->begin();
3513   // Check classof(Instruction *).
3514   auto *Invoke = cast<sandboxir::InvokeInst>(&*It++);
3515 
3516   // Check getNormalDest().
3517   EXPECT_EQ(Invoke->getNormalDest(), NormalBB);
3518   // Check getUnwindDest().
3519   EXPECT_EQ(Invoke->getUnwindDest(), ExceptionBB);
3520   // Check getSuccessor().
3521   EXPECT_EQ(Invoke->getSuccessor(0), NormalBB);
3522   EXPECT_EQ(Invoke->getSuccessor(1), ExceptionBB);
3523   // Check setNormalDest().
3524   Invoke->setNormalDest(OtherBB);
3525   EXPECT_EQ(Invoke->getNormalDest(), OtherBB);
3526   EXPECT_EQ(Invoke->getUnwindDest(), ExceptionBB);
3527   // Check setUnwindDest().
3528   Invoke->setUnwindDest(OtherBB);
3529   EXPECT_EQ(Invoke->getNormalDest(), OtherBB);
3530   EXPECT_EQ(Invoke->getUnwindDest(), OtherBB);
3531   // Check setSuccessor().
3532   Invoke->setSuccessor(0, NormalBB);
3533   EXPECT_EQ(Invoke->getNormalDest(), NormalBB);
3534   Invoke->setSuccessor(1, ExceptionBB);
3535   EXPECT_EQ(Invoke->getUnwindDest(), ExceptionBB);
3536   // Check getLandingPadInst().
3537   EXPECT_EQ(Invoke->getLandingPadInst(), LandingPad);
3538 
3539   {
3540     // Check create() WhereIt, WhereBB.
3541     SmallVector<sandboxir::Value *> Args({Arg});
3542     auto *InsertBefore = &*BB0->begin();
3543     auto *NewInvoke = cast<sandboxir::InvokeInst>(sandboxir::InvokeInst::create(
3544         F.getFunctionType(), &F, NormalBB, ExceptionBB, Args,
3545         /*WhereIt=*/InsertBefore->getIterator(), /*WhereBB=*/BB0, Ctx));
3546     EXPECT_EQ(NewInvoke->getNormalDest(), NormalBB);
3547     EXPECT_EQ(NewInvoke->getUnwindDest(), ExceptionBB);
3548     EXPECT_EQ(NewInvoke->getNextNode(), InsertBefore);
3549   }
3550   {
3551     // Check create() InsertBefore.
3552     SmallVector<sandboxir::Value *> Args({Arg});
3553     auto *InsertBefore = &*BB0->begin();
3554     auto *NewInvoke = cast<sandboxir::InvokeInst>(
3555         sandboxir::InvokeInst::create(F.getFunctionType(), &F, NormalBB,
3556                                       ExceptionBB, Args, InsertBefore, Ctx));
3557     EXPECT_EQ(NewInvoke->getNormalDest(), NormalBB);
3558     EXPECT_EQ(NewInvoke->getUnwindDest(), ExceptionBB);
3559     EXPECT_EQ(NewInvoke->getNextNode(), InsertBefore);
3560   }
3561   {
3562     // Check create() InsertAtEnd.
3563     SmallVector<sandboxir::Value *> Args({Arg});
3564     auto *NewInvoke = cast<sandboxir::InvokeInst>(sandboxir::InvokeInst::create(
3565         F.getFunctionType(), &F, NormalBB, ExceptionBB, Args,
3566         /*InsertAtEnd=*/BB0, Ctx));
3567     EXPECT_EQ(NewInvoke->getNormalDest(), NormalBB);
3568     EXPECT_EQ(NewInvoke->getUnwindDest(), ExceptionBB);
3569     EXPECT_EQ(NewInvoke->getParent(), BB0);
3570     EXPECT_EQ(NewInvoke->getNextNode(), nullptr);
3571   }
3572 }
3573 
3574 TEST_F(SandboxIRTest, CallBrInst) {
3575   parseIR(C, R"IR(
3576 define void @foo(i8 %arg) {
3577  bb0:
3578    callbr void asm "", ""()
3579                to label %bb1 [label %bb2]
3580  bb1:
3581    ret void
3582  bb2:
3583    ret void
3584  other_bb:
3585    ret void
3586  bb3:
3587    callbr void @foo(i8 %arg)
3588                to label %bb1 [label %bb2]
3589 }
3590 )IR");
3591   Function &LLVMF = *M->getFunction("foo");
3592   auto *LLVMBB0 = getBasicBlockByName(LLVMF, "bb0");
3593   auto *LLVMCallBr = cast<llvm::CallBrInst>(&*LLVMBB0->begin());
3594   sandboxir::Context Ctx(C);
3595   auto &F = *Ctx.createFunction(&LLVMF);
3596   auto *Arg = F.getArg(0);
3597   auto *BB0 = cast<sandboxir::BasicBlock>(
3598       Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
3599   auto *BB1 = cast<sandboxir::BasicBlock>(
3600       Ctx.getValue(getBasicBlockByName(LLVMF, "bb1")));
3601   auto *BB2 = cast<sandboxir::BasicBlock>(
3602       Ctx.getValue(getBasicBlockByName(LLVMF, "bb2")));
3603   auto *BB3 = cast<sandboxir::BasicBlock>(
3604       Ctx.getValue(getBasicBlockByName(LLVMF, "bb3")));
3605   auto *OtherBB = cast<sandboxir::BasicBlock>(
3606       Ctx.getValue(getBasicBlockByName(LLVMF, "other_bb")));
3607   auto It = BB0->begin();
3608   // Check classof(Instruction *).
3609   auto *CallBr0 = cast<sandboxir::CallBrInst>(&*It++);
3610 
3611   It = BB3->begin();
3612   auto *CallBr1 = cast<sandboxir::CallBrInst>(&*It++);
3613   for (sandboxir::CallBrInst *CallBr : {CallBr0, CallBr1}) {
3614     // Check getNumIndirectDests().
3615     EXPECT_EQ(CallBr->getNumIndirectDests(), 1u);
3616     // Check getIndirectDestLabel().
3617     EXPECT_EQ(CallBr->getIndirectDestLabel(0),
3618               Ctx.getValue(LLVMCallBr->getIndirectDestLabel(0)));
3619     // Check getIndirectDestLabelUse().
3620     EXPECT_EQ(CallBr->getIndirectDestLabelUse(0),
3621               Ctx.getValue(LLVMCallBr->getIndirectDestLabelUse(0)));
3622     // Check getDefaultDest().
3623     EXPECT_EQ(CallBr->getDefaultDest(),
3624               Ctx.getValue(LLVMCallBr->getDefaultDest()));
3625     // Check getIndirectDest().
3626     EXPECT_EQ(CallBr->getIndirectDest(0),
3627               Ctx.getValue(LLVMCallBr->getIndirectDest(0)));
3628     // Check getIndirectDests().
3629     auto Dests = CallBr->getIndirectDests();
3630     EXPECT_EQ(Dests.size(), LLVMCallBr->getIndirectDests().size());
3631     EXPECT_EQ(Dests[0], Ctx.getValue(LLVMCallBr->getIndirectDests()[0]));
3632     // Check getNumSuccessors().
3633     EXPECT_EQ(CallBr->getNumSuccessors(), LLVMCallBr->getNumSuccessors());
3634     // Check getSuccessor().
3635     for (unsigned SuccIdx = 0, E = CallBr->getNumSuccessors(); SuccIdx != E;
3636          ++SuccIdx)
3637       EXPECT_EQ(CallBr->getSuccessor(SuccIdx),
3638                 Ctx.getValue(LLVMCallBr->getSuccessor(SuccIdx)));
3639     // Check setDefaultDest().
3640     auto *SvDefaultDest = CallBr->getDefaultDest();
3641     CallBr->setDefaultDest(OtherBB);
3642     EXPECT_EQ(CallBr->getDefaultDest(), OtherBB);
3643     CallBr->setDefaultDest(SvDefaultDest);
3644     // Check setIndirectDest().
3645     auto *SvIndirectDest = CallBr->getIndirectDest(0);
3646     CallBr->setIndirectDest(0, OtherBB);
3647     EXPECT_EQ(CallBr->getIndirectDest(0), OtherBB);
3648     CallBr->setIndirectDest(0, SvIndirectDest);
3649   }
3650 
3651   {
3652     // Check create() WhereIt, WhereBB.
3653     SmallVector<sandboxir::Value *> Args({Arg});
3654     auto *NewCallBr = cast<sandboxir::CallBrInst>(sandboxir::CallBrInst::create(
3655         F.getFunctionType(), &F, BB1, {BB2}, Args, /*WhereIt=*/BB0->end(),
3656         /*WhereBB=*/BB0, Ctx));
3657     EXPECT_EQ(NewCallBr->getDefaultDest(), BB1);
3658     EXPECT_EQ(NewCallBr->getIndirectDests().size(), 1u);
3659     EXPECT_EQ(NewCallBr->getIndirectDests()[0], BB2);
3660     EXPECT_EQ(NewCallBr->getNextNode(), nullptr);
3661     EXPECT_EQ(NewCallBr->getParent(), BB0);
3662   }
3663   {
3664     // Check create() InsertBefore
3665     SmallVector<sandboxir::Value *> Args({Arg});
3666     auto *InsertBefore = &*BB0->rbegin();
3667     auto *NewCallBr = cast<sandboxir::CallBrInst>(sandboxir::CallBrInst::create(
3668         F.getFunctionType(), &F, BB1, {BB2}, Args, InsertBefore, Ctx));
3669     EXPECT_EQ(NewCallBr->getDefaultDest(), BB1);
3670     EXPECT_EQ(NewCallBr->getIndirectDests().size(), 1u);
3671     EXPECT_EQ(NewCallBr->getIndirectDests()[0], BB2);
3672     EXPECT_EQ(NewCallBr->getNextNode(), InsertBefore);
3673   }
3674   {
3675     // Check create() InsertAtEnd.
3676     SmallVector<sandboxir::Value *> Args({Arg});
3677     auto *NewCallBr = cast<sandboxir::CallBrInst>(
3678         sandboxir::CallBrInst::create(F.getFunctionType(), &F, BB1, {BB2}, Args,
3679                                       /*InsertAtEnd=*/BB0, Ctx));
3680     EXPECT_EQ(NewCallBr->getDefaultDest(), BB1);
3681     EXPECT_EQ(NewCallBr->getIndirectDests().size(), 1u);
3682     EXPECT_EQ(NewCallBr->getIndirectDests()[0], BB2);
3683     EXPECT_EQ(NewCallBr->getNextNode(), nullptr);
3684     EXPECT_EQ(NewCallBr->getParent(), BB0);
3685   }
3686 }
3687 
3688 TEST_F(SandboxIRTest, LandingPadInst) {
3689   parseIR(C, R"IR(
3690 define void @foo() {
3691 entry:
3692   invoke void @foo()
3693       to label %bb unwind label %unwind
3694 unwind:
3695   %lpad = landingpad { ptr, i32 }
3696             catch ptr null
3697   ret void
3698 bb:
3699   ret void
3700 }
3701 )IR");
3702   Function &LLVMF = *M->getFunction("foo");
3703   auto *LLVMUnwind = getBasicBlockByName(LLVMF, "unwind");
3704   auto *LLVMLPad = cast<llvm::LandingPadInst>(&*LLVMUnwind->begin());
3705 
3706   sandboxir::Context Ctx(C);
3707   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
3708   auto *Unwind = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMUnwind));
3709   auto *BB = cast<sandboxir::BasicBlock>(
3710       Ctx.getValue(getBasicBlockByName(LLVMF, "bb")));
3711   auto It = Unwind->begin();
3712   auto *LPad = cast<sandboxir::LandingPadInst>(&*It++);
3713   [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
3714 
3715   // Check isCleanup().
3716   EXPECT_EQ(LPad->isCleanup(), LLVMLPad->isCleanup());
3717   // Check setCleanup().
3718   auto OrigIsCleanup = LPad->isCleanup();
3719   auto NewIsCleanup = true;
3720   EXPECT_NE(NewIsCleanup, OrigIsCleanup);
3721   LPad->setCleanup(NewIsCleanup);
3722   EXPECT_EQ(LPad->isCleanup(), NewIsCleanup);
3723   LPad->setCleanup(OrigIsCleanup);
3724   EXPECT_EQ(LPad->isCleanup(), OrigIsCleanup);
3725   // Check getNumClauses().
3726   EXPECT_EQ(LPad->getNumClauses(), LLVMLPad->getNumClauses());
3727   // Check getClause().
3728   for (auto Idx : seq<unsigned>(0, LPad->getNumClauses()))
3729     EXPECT_EQ(LPad->getClause(Idx), Ctx.getValue(LLVMLPad->getClause(Idx)));
3730   // Check isCatch().
3731   for (auto Idx : seq<unsigned>(0, LPad->getNumClauses()))
3732     EXPECT_EQ(LPad->isCatch(Idx), LLVMLPad->isCatch(Idx));
3733   // Check isFilter().
3734   for (auto Idx : seq<unsigned>(0, LPad->getNumClauses()))
3735     EXPECT_EQ(LPad->isFilter(Idx), LLVMLPad->isFilter(Idx));
3736   // Check create().
3737   auto *BBRet = &*BB->begin();
3738   auto *NewLPad =
3739       cast<sandboxir::LandingPadInst>(sandboxir::LandingPadInst::create(
3740           sandboxir::Type::getInt8Ty(Ctx), 0, BBRet->getIterator(),
3741           BBRet->getParent(), Ctx, "NewLPad"));
3742   EXPECT_EQ(NewLPad->getNextNode(), BBRet);
3743   EXPECT_FALSE(NewLPad->isCleanup());
3744 #ifndef NDEBUG
3745   EXPECT_EQ(NewLPad->getName(), "NewLPad");
3746 #endif // NDEBUG
3747 }
3748 
3749 TEST_F(SandboxIRTest, FuncletPadInst_CatchPadInst_CleanupPadInst) {
3750   parseIR(C, R"IR(
3751 define void @foo() {
3752 dispatch:
3753   %cs = catchswitch within none [label %handler0] unwind to caller
3754 handler0:
3755   %catchpad = catchpad within %cs [ptr @foo]
3756   ret void
3757 handler1:
3758   %cleanuppad = cleanuppad within %cs [ptr @foo]
3759   ret void
3760 bb:
3761   ret void
3762 }
3763 )IR");
3764   Function &LLVMF = *M->getFunction("foo");
3765   BasicBlock *LLVMDispatch = getBasicBlockByName(LLVMF, "dispatch");
3766   BasicBlock *LLVMHandler0 = getBasicBlockByName(LLVMF, "handler0");
3767   BasicBlock *LLVMHandler1 = getBasicBlockByName(LLVMF, "handler1");
3768   auto *LLVMCP = cast<llvm::CatchPadInst>(&*LLVMHandler0->begin());
3769   auto *LLVMCLP = cast<llvm::CleanupPadInst>(&*LLVMHandler1->begin());
3770 
3771   sandboxir::Context Ctx(C);
3772   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
3773   auto *Dispatch = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMDispatch));
3774   auto *Handler0 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler0));
3775   auto *Handler1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler1));
3776   auto *BB = cast<sandboxir::BasicBlock>(
3777       Ctx.getValue(getBasicBlockByName(LLVMF, "bb")));
3778   auto *BBRet = cast<sandboxir::ReturnInst>(&*BB->begin());
3779   auto *CS = cast<sandboxir::CatchSwitchInst>(&*Dispatch->begin());
3780   [[maybe_unused]] auto *CP =
3781       cast<sandboxir::CatchPadInst>(&*Handler0->begin());
3782   [[maybe_unused]] auto *CLP =
3783       cast<sandboxir::CleanupPadInst>(&*Handler1->begin());
3784 
3785   // Check getCatchSwitch().
3786   EXPECT_EQ(CP->getCatchSwitch(), CS);
3787   EXPECT_EQ(CP->getCatchSwitch(), Ctx.getValue(LLVMCP->getCatchSwitch()));
3788 
3789   for (llvm::FuncletPadInst *LLVMFPI :
3790        {static_cast<llvm::FuncletPadInst *>(LLVMCP),
3791         static_cast<llvm::FuncletPadInst *>(LLVMCLP)}) {
3792     auto *FPI = cast<sandboxir::FuncletPadInst>(Ctx.getValue(LLVMFPI));
3793     // Check arg_size().
3794     EXPECT_EQ(FPI->arg_size(), LLVMFPI->arg_size());
3795     // Check getParentPad().
3796     EXPECT_EQ(FPI->getParentPad(), Ctx.getValue(LLVMFPI->getParentPad()));
3797     // Check setParentPad().
3798     auto *OrigParentPad = FPI->getParentPad();
3799     auto *NewParentPad = Dispatch;
3800     EXPECT_NE(NewParentPad, OrigParentPad);
3801     FPI->setParentPad(NewParentPad);
3802     EXPECT_EQ(FPI->getParentPad(), NewParentPad);
3803     FPI->setParentPad(OrigParentPad);
3804     EXPECT_EQ(FPI->getParentPad(), OrigParentPad);
3805     // Check getArgOperand().
3806     for (auto Idx : seq<unsigned>(0, FPI->arg_size()))
3807       EXPECT_EQ(FPI->getArgOperand(Idx),
3808                 Ctx.getValue(LLVMFPI->getArgOperand(Idx)));
3809     // Check setArgOperand().
3810     auto *OrigArgOperand = FPI->getArgOperand(0);
3811     auto *NewArgOperand = Dispatch;
3812     EXPECT_NE(NewArgOperand, OrigArgOperand);
3813     FPI->setArgOperand(0, NewArgOperand);
3814     EXPECT_EQ(FPI->getArgOperand(0), NewArgOperand);
3815     FPI->setArgOperand(0, OrigArgOperand);
3816     EXPECT_EQ(FPI->getArgOperand(0), OrigArgOperand);
3817   }
3818   // Check CatchPadInst::create().
3819   auto *NewCPI = cast<sandboxir::CatchPadInst>(sandboxir::CatchPadInst::create(
3820       CS, {}, BBRet->getIterator(), BB, Ctx, "NewCPI"));
3821   EXPECT_EQ(NewCPI->getCatchSwitch(), CS);
3822   EXPECT_EQ(NewCPI->arg_size(), 0u);
3823   EXPECT_EQ(NewCPI->getNextNode(), BBRet);
3824 #ifndef NDEBUG
3825   EXPECT_EQ(NewCPI->getName(), "NewCPI");
3826 #endif // NDEBUG
3827   // Check CleanupPadInst::create().
3828   auto *NewCLPI =
3829       cast<sandboxir::CleanupPadInst>(sandboxir::CleanupPadInst::create(
3830           CS, {}, BBRet->getIterator(), BB, Ctx, "NewCLPI"));
3831   EXPECT_EQ(NewCLPI->getParentPad(), CS);
3832   EXPECT_EQ(NewCLPI->arg_size(), 0u);
3833   EXPECT_EQ(NewCLPI->getNextNode(), BBRet);
3834 #ifndef NDEBUG
3835   EXPECT_EQ(NewCLPI->getName(), "NewCLPI");
3836 #endif // NDEBUG
3837 }
3838 
3839 TEST_F(SandboxIRTest, CatchReturnInst) {
3840   parseIR(C, R"IR(
3841 define void @foo() {
3842 dispatch:
3843   %cs = catchswitch within none [label %catch] unwind to caller
3844 catch:
3845   %catchpad = catchpad within %cs [ptr @foo]
3846   catchret from %catchpad to label %continue
3847 continue:
3848   ret void
3849 catch2:
3850   %catchpad2 = catchpad within %cs [ptr @foo]
3851   ret void
3852 }
3853 )IR");
3854   Function &LLVMF = *M->getFunction("foo");
3855   BasicBlock *LLVMCatch = getBasicBlockByName(LLVMF, "catch");
3856   auto LLVMIt = LLVMCatch->begin();
3857   [[maybe_unused]] auto *LLVMCP = cast<llvm::CatchPadInst>(&*LLVMIt++);
3858   auto *LLVMCR = cast<llvm::CatchReturnInst>(&*LLVMIt++);
3859 
3860   sandboxir::Context Ctx(C);
3861   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
3862   auto *Catch = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCatch));
3863   auto *Catch2 = cast<sandboxir::BasicBlock>(
3864       Ctx.getValue(getBasicBlockByName(LLVMF, "catch2")));
3865   auto It = Catch->begin();
3866   [[maybe_unused]] auto *CP = cast<sandboxir::CatchPadInst>(&*It++);
3867   auto *CR = cast<sandboxir::CatchReturnInst>(&*It++);
3868   auto *CP2 = cast<sandboxir::CatchPadInst>(&*Catch2->begin());
3869 
3870   // Check getCatchPad().
3871   EXPECT_EQ(CR->getCatchPad(), Ctx.getValue(LLVMCR->getCatchPad()));
3872   // Check setCatchPad().
3873   auto *OrigCP = CR->getCatchPad();
3874   auto *NewCP = CP2;
3875   EXPECT_NE(NewCP, OrigCP);
3876   CR->setCatchPad(NewCP);
3877   EXPECT_EQ(CR->getCatchPad(), NewCP);
3878   CR->setCatchPad(OrigCP);
3879   EXPECT_EQ(CR->getCatchPad(), OrigCP);
3880   // Check getSuccessor().
3881   EXPECT_EQ(CR->getSuccessor(), Ctx.getValue(LLVMCR->getSuccessor()));
3882   // Check setSuccessor().
3883   auto *OrigSucc = CR->getSuccessor();
3884   auto *NewSucc = Catch;
3885   EXPECT_NE(NewSucc, OrigSucc);
3886   CR->setSuccessor(NewSucc);
3887   EXPECT_EQ(CR->getSuccessor(), NewSucc);
3888   CR->setSuccessor(OrigSucc);
3889   EXPECT_EQ(CR->getSuccessor(), OrigSucc);
3890   // Check getNumSuccessors().
3891   EXPECT_EQ(CR->getNumSuccessors(), LLVMCR->getNumSuccessors());
3892   // Check getCatchSwitchParentPad().
3893   EXPECT_EQ(CR->getCatchSwitchParentPad(),
3894             Ctx.getValue(LLVMCR->getCatchSwitchParentPad()));
3895   // Check create().
3896   auto *CRI =
3897       cast<sandboxir::CatchReturnInst>(sandboxir::CatchReturnInst::create(
3898           CP, Catch, CP->getIterator(), Catch, Ctx));
3899   EXPECT_EQ(CRI->getNextNode(), CP);
3900   EXPECT_EQ(CRI->getCatchPad(), CP);
3901   EXPECT_EQ(CRI->getSuccessor(), Catch);
3902 }
3903 
3904 TEST_F(SandboxIRTest, CleanupReturnInst) {
3905   parseIR(C, R"IR(
3906 define void @foo() {
3907 dispatch:
3908   invoke void @foo()
3909               to label %throw unwind label %cleanup
3910 throw:
3911   ret void
3912 cleanup:
3913   %cleanuppad = cleanuppad within none []
3914   cleanupret from %cleanuppad unwind label %cleanup2
3915 cleanup2:
3916   %cleanuppad2 = cleanuppad within none []
3917   ret void
3918 }
3919 )IR");
3920   Function &LLVMF = *M->getFunction("foo");
3921   BasicBlock *LLVMCleanup = getBasicBlockByName(LLVMF, "cleanup");
3922   auto LLVMIt = LLVMCleanup->begin();
3923   [[maybe_unused]] auto *LLVMCP = cast<llvm::CleanupPadInst>(&*LLVMIt++);
3924   auto *LLVMCRI = cast<llvm::CleanupReturnInst>(&*LLVMIt++);
3925 
3926   sandboxir::Context Ctx(C);
3927   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
3928   auto *Throw = cast<sandboxir::BasicBlock>(
3929       Ctx.getValue(getBasicBlockByName(LLVMF, "throw")));
3930   auto *Cleanup = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCleanup));
3931   auto *Cleanup2 = cast<sandboxir::BasicBlock>(
3932       Ctx.getValue(getBasicBlockByName(LLVMF, "cleanup2")));
3933   auto It = Cleanup->begin();
3934   [[maybe_unused]] auto *CP = cast<sandboxir::CleanupPadInst>(&*It++);
3935   auto *CRI = cast<sandboxir::CleanupReturnInst>(&*It++);
3936   It = Cleanup2->begin();
3937   auto *CP2 = cast<sandboxir::CleanupPadInst>(&*It++);
3938   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
3939 
3940   // Check hasUnwindDest().
3941   EXPECT_EQ(CRI->hasUnwindDest(), LLVMCRI->hasUnwindDest());
3942   // Check unwindsToCaller().
3943   EXPECT_EQ(CRI->unwindsToCaller(), LLVMCRI->unwindsToCaller());
3944   // Check getCleanupPad().
3945   EXPECT_EQ(CRI->getCleanupPad(), Ctx.getValue(LLVMCRI->getCleanupPad()));
3946   // Check setCleanupPad().
3947   auto *OrigCleanupPad = CRI->getCleanupPad();
3948   auto *NewCleanupPad = CP2;
3949   EXPECT_NE(NewCleanupPad, OrigCleanupPad);
3950   CRI->setCleanupPad(NewCleanupPad);
3951   EXPECT_EQ(CRI->getCleanupPad(), NewCleanupPad);
3952   CRI->setCleanupPad(OrigCleanupPad);
3953   EXPECT_EQ(CRI->getCleanupPad(), OrigCleanupPad);
3954   // Check setNumSuccessors().
3955   EXPECT_EQ(CRI->getNumSuccessors(), LLVMCRI->getNumSuccessors());
3956   // Check getUnwindDest().
3957   EXPECT_EQ(CRI->getUnwindDest(), Ctx.getValue(LLVMCRI->getUnwindDest()));
3958   // Check setUnwindDest().
3959   auto *OrigUnwindDest = CRI->getUnwindDest();
3960   auto *NewUnwindDest = Throw;
3961   EXPECT_NE(NewUnwindDest, OrigUnwindDest);
3962   CRI->setUnwindDest(NewUnwindDest);
3963   EXPECT_EQ(CRI->getUnwindDest(), NewUnwindDest);
3964   CRI->setUnwindDest(OrigUnwindDest);
3965   EXPECT_EQ(CRI->getUnwindDest(), OrigUnwindDest);
3966   // Check create().
3967   auto *UnwindBB = Cleanup;
3968   auto *NewCRI = sandboxir::CleanupReturnInst::create(
3969       CP2, UnwindBB, Ret->getIterator(), Ret->getParent(), Ctx);
3970   EXPECT_EQ(NewCRI->getCleanupPad(), CP2);
3971   EXPECT_EQ(NewCRI->getUnwindDest(), UnwindBB);
3972   EXPECT_EQ(NewCRI->getNextNode(), Ret);
3973 }
3974 
3975 TEST_F(SandboxIRTest, GetElementPtrInstruction) {
3976   parseIR(C, R"IR(
3977 define void @foo(ptr %ptr, <2 x ptr> %ptrs) {
3978   %gep0 = getelementptr i8, ptr %ptr, i32 0
3979   %gep1 = getelementptr nusw i8, ptr %ptr, i32 0
3980   %gep2 = getelementptr nuw i8, ptr %ptr, i32 0
3981   %gep3 = getelementptr inbounds {i32, {i32, i8}}, ptr %ptr, i32 1, i32 0
3982   %gep4 = getelementptr inbounds {i8, i8, {i32, i16}}, <2 x ptr> %ptrs, i32 2, <2 x i32> <i32 0, i32 0>
3983   ret void
3984 }
3985 )IR");
3986   Function &LLVMF = *M->getFunction("foo");
3987   BasicBlock *LLVMBB = &*LLVMF.begin();
3988   auto LLVMIt = LLVMBB->begin();
3989   SmallVector<llvm::GetElementPtrInst *, 4> LLVMGEPs;
3990   while (isa<llvm::GetElementPtrInst>(&*LLVMIt))
3991     LLVMGEPs.push_back(cast<llvm::GetElementPtrInst>(&*LLVMIt++));
3992   auto *LLVMRet = cast<llvm::ReturnInst>(&*LLVMIt++);
3993   sandboxir::Context Ctx(C);
3994   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
3995 
3996   for (llvm::GetElementPtrInst *LLVMGEP : LLVMGEPs) {
3997     // Check classof().
3998     auto *GEP = cast<sandboxir::GetElementPtrInst>(Ctx.getValue(LLVMGEP));
3999     // Check getSourceElementType().
4000     EXPECT_EQ(GEP->getSourceElementType(),
4001               Ctx.getType(LLVMGEP->getSourceElementType()));
4002     // Check getResultElementType().
4003     EXPECT_EQ(GEP->getResultElementType(),
4004               Ctx.getType(LLVMGEP->getResultElementType()));
4005     // Check getAddressSpace().
4006     EXPECT_EQ(GEP->getAddressSpace(), LLVMGEP->getAddressSpace());
4007     // Check indices().
4008     EXPECT_EQ(range_size(GEP->indices()), range_size(LLVMGEP->indices()));
4009     auto IdxIt = GEP->idx_begin();
4010     for (llvm::Value *LLVMIdxV : LLVMGEP->indices()) {
4011       sandboxir::Value *IdxV = *IdxIt++;
4012       EXPECT_EQ(IdxV, Ctx.getValue(LLVMIdxV));
4013     }
4014     // Check getPointerOperand().
4015     EXPECT_EQ(GEP->getPointerOperand(),
4016               Ctx.getValue(LLVMGEP->getPointerOperand()));
4017     // Check getPointerOperandIndex().
4018     EXPECT_EQ(GEP->getPointerOperandIndex(), LLVMGEP->getPointerOperandIndex());
4019     // Check getPointerOperandType().
4020     EXPECT_EQ(GEP->getPointerOperandType(),
4021               Ctx.getType(LLVMGEP->getPointerOperandType()));
4022     // Check getPointerAddressSpace().
4023     EXPECT_EQ(GEP->getPointerAddressSpace(), LLVMGEP->getPointerAddressSpace());
4024     // Check getNumIndices().
4025     EXPECT_EQ(GEP->getNumIndices(), LLVMGEP->getNumIndices());
4026     // Check hasIndices().
4027     EXPECT_EQ(GEP->hasIndices(), LLVMGEP->hasIndices());
4028     // Check hasAllConstantIndices().
4029     EXPECT_EQ(GEP->hasAllConstantIndices(), LLVMGEP->hasAllConstantIndices());
4030     // Check getNoWrapFlags().
4031     EXPECT_EQ(GEP->getNoWrapFlags(), LLVMGEP->getNoWrapFlags());
4032     // Check isInBounds().
4033     EXPECT_EQ(GEP->isInBounds(), LLVMGEP->isInBounds());
4034     // Check hasNoUnsignedWrap().
4035     EXPECT_EQ(GEP->hasNoUnsignedWrap(), LLVMGEP->hasNoUnsignedWrap());
4036     // Check accumulateConstantOffset().
4037     const DataLayout &DL = M->getDataLayout();
4038     APInt Offset1 =
4039         APInt::getZero(DL.getIndexSizeInBits(GEP->getPointerAddressSpace()));
4040     APInt Offset2 =
4041         APInt::getZero(DL.getIndexSizeInBits(GEP->getPointerAddressSpace()));
4042     EXPECT_EQ(GEP->accumulateConstantOffset(DL, Offset1),
4043               LLVMGEP->accumulateConstantOffset(DL, Offset2));
4044     EXPECT_EQ(Offset1, Offset2);
4045   }
4046 
4047   auto *BB = &*F.begin();
4048   auto *GEP0 = cast<sandboxir::GetElementPtrInst>(&*BB->begin());
4049   auto *Ret = cast<sandboxir::ReturnInst>(Ctx.getValue(LLVMRet));
4050   SmallVector<sandboxir::Value *> Indices(GEP0->indices());
4051 
4052   // Check create() WhereIt, WhereBB.
4053   auto *NewGEP0 =
4054       cast<sandboxir::GetElementPtrInst>(sandboxir::GetElementPtrInst::create(
4055           GEP0->getType(), GEP0->getPointerOperand(), Indices,
4056           /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx,
4057           "NewGEP0"));
4058   EXPECT_EQ(NewGEP0->getName(), "NewGEP0");
4059   EXPECT_EQ(NewGEP0->getType(), GEP0->getType());
4060   EXPECT_EQ(NewGEP0->getPointerOperand(), GEP0->getPointerOperand());
4061   EXPECT_EQ(range_size(NewGEP0->indices()), range_size(GEP0->indices()));
4062   for (auto NewIt = NewGEP0->idx_begin(), NewItE = NewGEP0->idx_end(),
4063             OldIt = GEP0->idx_begin();
4064        NewIt != NewItE; ++NewIt) {
4065     sandboxir::Value *NewIdxV = *NewIt;
4066     sandboxir::Value *OldIdxV = *OldIt;
4067     EXPECT_EQ(NewIdxV, OldIdxV);
4068   }
4069   EXPECT_EQ(NewGEP0->getNextNode(), Ret);
4070 
4071   // Check create() InsertBefore.
4072   auto *NewGEP1 =
4073       cast<sandboxir::GetElementPtrInst>(sandboxir::GetElementPtrInst::create(
4074           GEP0->getType(), GEP0->getPointerOperand(), Indices,
4075           /*InsertBefore=*/Ret, Ctx, "NewGEP1"));
4076   EXPECT_EQ(NewGEP1->getName(), "NewGEP1");
4077   EXPECT_EQ(NewGEP1->getType(), GEP0->getType());
4078   EXPECT_EQ(NewGEP1->getPointerOperand(), GEP0->getPointerOperand());
4079   EXPECT_EQ(range_size(NewGEP1->indices()), range_size(GEP0->indices()));
4080   for (auto NewIt = NewGEP0->idx_begin(), NewItE = NewGEP0->idx_end(),
4081             OldIt = GEP0->idx_begin();
4082        NewIt != NewItE; ++NewIt) {
4083     sandboxir::Value *NewIdxV = *NewIt;
4084     sandboxir::Value *OldIdxV = *OldIt;
4085     EXPECT_EQ(NewIdxV, OldIdxV);
4086   }
4087   EXPECT_EQ(NewGEP1->getNextNode(), Ret);
4088 
4089   // Check create() InsertAtEnd.
4090   auto *NewGEP2 =
4091       cast<sandboxir::GetElementPtrInst>(sandboxir::GetElementPtrInst::create(
4092           GEP0->getType(), GEP0->getPointerOperand(), Indices,
4093           /*InsertAtEnd=*/BB, Ctx, "NewGEP2"));
4094   EXPECT_EQ(NewGEP2->getName(), "NewGEP2");
4095   EXPECT_EQ(NewGEP2->getType(), GEP0->getType());
4096   EXPECT_EQ(NewGEP2->getPointerOperand(), GEP0->getPointerOperand());
4097   EXPECT_EQ(range_size(NewGEP2->indices()), range_size(GEP0->indices()));
4098   for (auto NewIt = NewGEP0->idx_begin(), NewItE = NewGEP0->idx_end(),
4099             OldIt = GEP0->idx_begin();
4100        NewIt != NewItE; ++NewIt) {
4101     sandboxir::Value *NewIdxV = *NewIt;
4102     sandboxir::Value *OldIdxV = *OldIt;
4103     EXPECT_EQ(NewIdxV, OldIdxV);
4104   }
4105   EXPECT_EQ(NewGEP2->getPrevNode(), Ret);
4106   EXPECT_EQ(NewGEP2->getNextNode(), nullptr);
4107 }
4108 
4109 TEST_F(SandboxIRTest, Flags) {
4110   parseIR(C, R"IR(
4111 define void @foo(i32 %arg, float %farg) {
4112   %add = add i32 %arg, %arg
4113   %fadd = fadd float %farg, %farg
4114   %udiv = udiv i32 %arg, %arg
4115   ret void
4116 }
4117 )IR");
4118   Function &LLVMF = *M->getFunction("foo");
4119   BasicBlock *LLVMBB = &*LLVMF.begin();
4120   auto LLVMIt = LLVMBB->begin();
4121   auto *LLVMAdd = &*LLVMIt++;
4122   auto *LLVMFAdd = &*LLVMIt++;
4123   auto *LLVMUDiv = &*LLVMIt++;
4124 
4125   sandboxir::Context Ctx(C);
4126   auto &F = *Ctx.createFunction(&LLVMF);
4127   auto *BB = &*F.begin();
4128   auto It = BB->begin();
4129   auto *Add = &*It++;
4130   auto *FAdd = &*It++;
4131   auto *UDiv = &*It++;
4132 
4133 #define CHECK_FLAG(I, LLVMI, GETTER, SETTER)                                   \
4134   {                                                                            \
4135     EXPECT_EQ(I->GETTER(), LLVMI->GETTER());                                   \
4136     bool NewFlagVal = !I->GETTER();                                            \
4137     I->SETTER(NewFlagVal);                                                     \
4138     EXPECT_EQ(I->GETTER(), NewFlagVal);                                        \
4139     EXPECT_EQ(I->GETTER(), LLVMI->GETTER());                                   \
4140   }
4141 
4142   CHECK_FLAG(Add, LLVMAdd, hasNoUnsignedWrap, setHasNoUnsignedWrap);
4143   CHECK_FLAG(Add, LLVMAdd, hasNoSignedWrap, setHasNoSignedWrap);
4144   CHECK_FLAG(FAdd, LLVMFAdd, isFast, setFast);
4145   CHECK_FLAG(FAdd, LLVMFAdd, hasAllowReassoc, setHasAllowReassoc);
4146   CHECK_FLAG(UDiv, LLVMUDiv, isExact, setIsExact);
4147   CHECK_FLAG(FAdd, LLVMFAdd, hasNoNaNs, setHasNoNaNs);
4148   CHECK_FLAG(FAdd, LLVMFAdd, hasNoInfs, setHasNoInfs);
4149   CHECK_FLAG(FAdd, LLVMFAdd, hasNoSignedZeros, setHasNoSignedZeros);
4150   CHECK_FLAG(FAdd, LLVMFAdd, hasAllowReciprocal, setHasAllowReciprocal);
4151   CHECK_FLAG(FAdd, LLVMFAdd, hasAllowContract, setHasAllowContract);
4152   CHECK_FLAG(FAdd, LLVMFAdd, hasApproxFunc, setHasApproxFunc);
4153 
4154   // Check getFastMathFlags(), copyFastMathFlags().
4155   FAdd->setFastMathFlags(FastMathFlags::getFast());
4156   EXPECT_FALSE(FAdd->getFastMathFlags() != LLVMFAdd->getFastMathFlags());
4157   FastMathFlags OrigFMF = FAdd->getFastMathFlags();
4158   FastMathFlags NewFMF;
4159   NewFMF.setAllowReassoc(true);
4160   EXPECT_TRUE(NewFMF != OrigFMF);
4161   FAdd->setFastMathFlags(NewFMF);
4162   EXPECT_FALSE(FAdd->getFastMathFlags() != OrigFMF);
4163   FAdd->copyFastMathFlags(NewFMF);
4164   EXPECT_FALSE(FAdd->getFastMathFlags() != NewFMF);
4165   EXPECT_FALSE(FAdd->getFastMathFlags() != LLVMFAdd->getFastMathFlags());
4166 }
4167 
4168 TEST_F(SandboxIRTest, CatchSwitchInst) {
4169   parseIR(C, R"IR(
4170 define void @foo(i32 %cond0, i32 %cond1) {
4171   bb0:
4172     %cs0 = catchswitch within none [label %handler0, label %handler1] unwind to caller
4173   bb1:
4174     %cs1 = catchswitch within %cs0 [label %handler0, label %handler1] unwind label %cleanup
4175   handler0:
4176     ret void
4177   handler1:
4178     ret void
4179   cleanup:
4180     ret void
4181 }
4182 )IR");
4183   Function &LLVMF = *M->getFunction("foo");
4184   auto *LLVMBB0 = getBasicBlockByName(LLVMF, "bb0");
4185   auto *LLVMBB1 = getBasicBlockByName(LLVMF, "bb1");
4186   auto *LLVMHandler0 = getBasicBlockByName(LLVMF, "handler0");
4187   auto *LLVMHandler1 = getBasicBlockByName(LLVMF, "handler1");
4188   auto *LLVMCleanup = getBasicBlockByName(LLVMF, "cleanup");
4189   auto *LLVMCS0 = cast<llvm::CatchSwitchInst>(&*LLVMBB0->begin());
4190   auto *LLVMCS1 = cast<llvm::CatchSwitchInst>(&*LLVMBB1->begin());
4191 
4192   sandboxir::Context Ctx(C);
4193   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
4194   auto *BB0 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB0));
4195   auto *BB1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB1));
4196   auto *Handler0 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler0));
4197   auto *Handler1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler1));
4198   auto *Cleanup = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCleanup));
4199   auto *CS0 = cast<sandboxir::CatchSwitchInst>(&*BB0->begin());
4200   auto *CS1 = cast<sandboxir::CatchSwitchInst>(&*BB1->begin());
4201 
4202   // Check getParentPad().
4203   EXPECT_EQ(CS0->getParentPad(), Ctx.getValue(LLVMCS0->getParentPad()));
4204   EXPECT_EQ(CS1->getParentPad(), Ctx.getValue(LLVMCS1->getParentPad()));
4205   // Check setParentPad().
4206   auto *OrigPad = CS0->getParentPad();
4207   auto *NewPad = CS1;
4208   EXPECT_NE(NewPad, OrigPad);
4209   CS0->setParentPad(NewPad);
4210   EXPECT_EQ(CS0->getParentPad(), NewPad);
4211   CS0->setParentPad(OrigPad);
4212   EXPECT_EQ(CS0->getParentPad(), OrigPad);
4213   // Check hasUnwindDest().
4214   EXPECT_EQ(CS0->hasUnwindDest(), LLVMCS0->hasUnwindDest());
4215   EXPECT_EQ(CS1->hasUnwindDest(), LLVMCS1->hasUnwindDest());
4216   // Check unwindsToCaller().
4217   EXPECT_EQ(CS0->unwindsToCaller(), LLVMCS0->unwindsToCaller());
4218   EXPECT_EQ(CS1->unwindsToCaller(), LLVMCS1->unwindsToCaller());
4219   // Check getUnwindDest().
4220   EXPECT_EQ(CS0->getUnwindDest(), Ctx.getValue(LLVMCS0->getUnwindDest()));
4221   EXPECT_EQ(CS1->getUnwindDest(), Ctx.getValue(LLVMCS1->getUnwindDest()));
4222   // Check setUnwindDest().
4223   auto *OrigUnwindDest = CS1->getUnwindDest();
4224   auto *NewUnwindDest = BB0;
4225   EXPECT_NE(NewUnwindDest, OrigUnwindDest);
4226   CS1->setUnwindDest(NewUnwindDest);
4227   EXPECT_EQ(CS1->getUnwindDest(), NewUnwindDest);
4228   CS1->setUnwindDest(OrigUnwindDest);
4229   EXPECT_EQ(CS1->getUnwindDest(), OrigUnwindDest);
4230   // Check getNumHandlers().
4231   EXPECT_EQ(CS0->getNumHandlers(), LLVMCS0->getNumHandlers());
4232   EXPECT_EQ(CS1->getNumHandlers(), LLVMCS1->getNumHandlers());
4233   // Check handler_begin(), handler_end().
4234   auto It = CS0->handler_begin();
4235   EXPECT_EQ(*It++, Handler0);
4236   EXPECT_EQ(*It++, Handler1);
4237   EXPECT_EQ(It, CS0->handler_end());
4238   // Check handlers().
4239   SmallVector<sandboxir::BasicBlock *, 2> Handlers;
4240   for (sandboxir::BasicBlock *Handler : CS0->handlers())
4241     Handlers.push_back(Handler);
4242   EXPECT_EQ(Handlers.size(), 2u);
4243   EXPECT_EQ(Handlers[0], Handler0);
4244   EXPECT_EQ(Handlers[1], Handler1);
4245   // Check addHandler().
4246   CS0->addHandler(BB0);
4247   EXPECT_EQ(CS0->getNumHandlers(), 3u);
4248   EXPECT_EQ(*std::next(CS0->handler_begin(), 2), BB0);
4249   // Check getNumSuccessors().
4250   EXPECT_EQ(CS0->getNumSuccessors(), LLVMCS0->getNumSuccessors());
4251   EXPECT_EQ(CS1->getNumSuccessors(), LLVMCS1->getNumSuccessors());
4252   // Check getSuccessor().
4253   for (auto SuccIdx : seq<unsigned>(0, CS0->getNumSuccessors()))
4254     EXPECT_EQ(CS0->getSuccessor(SuccIdx),
4255               Ctx.getValue(LLVMCS0->getSuccessor(SuccIdx)));
4256   // Check setSuccessor().
4257   auto *OrigSuccessor = CS0->getSuccessor(0);
4258   auto *NewSuccessor = BB0;
4259   EXPECT_NE(NewSuccessor, OrigSuccessor);
4260   CS0->setSuccessor(0, NewSuccessor);
4261   EXPECT_EQ(CS0->getSuccessor(0), NewSuccessor);
4262   CS0->setSuccessor(0, OrigSuccessor);
4263   EXPECT_EQ(CS0->getSuccessor(0), OrigSuccessor);
4264   // Check create().
4265   CS1->eraseFromParent();
4266   auto *NewCSI = sandboxir::CatchSwitchInst::create(
4267       CS0, Cleanup, 2, BB1->begin(), BB1, Ctx, "NewCSI");
4268   EXPECT_TRUE(isa<sandboxir::CatchSwitchInst>(NewCSI));
4269   EXPECT_EQ(NewCSI->getParentPad(), CS0);
4270 }
4271 
4272 TEST_F(SandboxIRTest, ResumeInst) {
4273   parseIR(C, R"IR(
4274 define void @foo() {
4275 entry:
4276   invoke void @foo()
4277       to label %bb unwind label %unwind
4278 bb:
4279   ret void
4280 unwind:
4281   %lpad = landingpad { ptr, i32 }
4282           cleanup
4283   resume { ptr, i32 } %lpad
4284 }
4285 )IR");
4286   Function &LLVMF = *M->getFunction("foo");
4287   auto *LLVMUnwindBB = getBasicBlockByName(LLVMF, "unwind");
4288   auto LLVMIt = LLVMUnwindBB->begin();
4289   [[maybe_unused]] auto *LLVMLPad = cast<llvm::LandingPadInst>(&*LLVMIt++);
4290   auto *LLVMResume = cast<llvm::ResumeInst>(&*LLVMIt++);
4291 
4292   sandboxir::Context Ctx(C);
4293   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
4294   auto *UnwindBB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMUnwindBB));
4295   auto It = UnwindBB->begin();
4296   auto *LPad = cast<sandboxir::LandingPadInst>(&*It++);
4297   auto *Resume = cast<sandboxir::ResumeInst>(&*It++);
4298   // Check getValue().
4299   EXPECT_EQ(Resume->getValue(), LPad);
4300   EXPECT_EQ(Resume->getValue(), Ctx.getValue(LLVMResume->getValue()));
4301   // Check getNumSuccessors().
4302   EXPECT_EQ(Resume->getNumSuccessors(), LLVMResume->getNumSuccessors());
4303   // Check create().
4304   auto *NewResume =
4305       sandboxir::ResumeInst::create(LPad, UnwindBB->end(), UnwindBB, Ctx);
4306   EXPECT_EQ(NewResume->getValue(), LPad);
4307   EXPECT_EQ(NewResume->getParent(), UnwindBB);
4308   EXPECT_EQ(NewResume->getNextNode(), nullptr);
4309 }
4310 
4311 TEST_F(SandboxIRTest, SwitchInst) {
4312   parseIR(C, R"IR(
4313 define void @foo(i32 %cond0, i32 %cond1) {
4314   entry:
4315     switch i32 %cond0, label %default [ i32 0, label %bb0
4316                                         i32 1, label %bb1 ]
4317   bb0:
4318     ret void
4319   bb1:
4320     ret void
4321   default:
4322     ret void
4323 }
4324 )IR");
4325   Function &LLVMF = *M->getFunction("foo");
4326   auto *LLVMEntry = getBasicBlockByName(LLVMF, "entry");
4327   auto *LLVMSwitch = cast<llvm::SwitchInst>(&*LLVMEntry->begin());
4328 
4329   sandboxir::Context Ctx(C);
4330   auto &F = *Ctx.createFunction(&LLVMF);
4331   auto *Cond1 = F.getArg(1);
4332   auto *Entry = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMEntry));
4333   auto *Switch = cast<sandboxir::SwitchInst>(&*Entry->begin());
4334   auto *BB0 = cast<sandboxir::BasicBlock>(
4335       Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
4336   auto *BB1 = cast<sandboxir::BasicBlock>(
4337       Ctx.getValue(getBasicBlockByName(LLVMF, "bb1")));
4338   auto *Default = cast<sandboxir::BasicBlock>(
4339       Ctx.getValue(getBasicBlockByName(LLVMF, "default")));
4340 
4341   // Check getCondition().
4342   EXPECT_EQ(Switch->getCondition(), Ctx.getValue(LLVMSwitch->getCondition()));
4343   // Check setCondition().
4344   auto *OrigCond = Switch->getCondition();
4345   auto *NewCond = Cond1;
4346   EXPECT_NE(NewCond, OrigCond);
4347   Switch->setCondition(NewCond);
4348   EXPECT_EQ(Switch->getCondition(), NewCond);
4349   Switch->setCondition(OrigCond);
4350   EXPECT_EQ(Switch->getCondition(), OrigCond);
4351   // Check getDefaultDest().
4352   EXPECT_EQ(Switch->getDefaultDest(),
4353             Ctx.getValue(LLVMSwitch->getDefaultDest()));
4354   EXPECT_EQ(Switch->getDefaultDest(), Default);
4355   // Check defaultDestUndefined().
4356   EXPECT_EQ(Switch->defaultDestUndefined(), LLVMSwitch->defaultDestUndefined());
4357   // Check setDefaultDest().
4358   auto *OrigDefaultDest = Switch->getDefaultDest();
4359   auto *NewDefaultDest = Entry;
4360   EXPECT_NE(NewDefaultDest, OrigDefaultDest);
4361   Switch->setDefaultDest(NewDefaultDest);
4362   EXPECT_EQ(Switch->getDefaultDest(), NewDefaultDest);
4363   Switch->setDefaultDest(OrigDefaultDest);
4364   EXPECT_EQ(Switch->getDefaultDest(), OrigDefaultDest);
4365   // Check getNumCases().
4366   EXPECT_EQ(Switch->getNumCases(), LLVMSwitch->getNumCases());
4367   // Check getNumSuccessors().
4368   EXPECT_EQ(Switch->getNumSuccessors(), LLVMSwitch->getNumSuccessors());
4369   // Check getSuccessor().
4370   for (auto SuccIdx : seq<unsigned>(0, Switch->getNumSuccessors()))
4371     EXPECT_EQ(Switch->getSuccessor(SuccIdx),
4372               Ctx.getValue(LLVMSwitch->getSuccessor(SuccIdx)));
4373   // Check setSuccessor().
4374   auto *OrigSucc = Switch->getSuccessor(0);
4375   auto *NewSucc = Entry;
4376   EXPECT_NE(NewSucc, OrigSucc);
4377   Switch->setSuccessor(0, NewSucc);
4378   EXPECT_EQ(Switch->getSuccessor(0), NewSucc);
4379   Switch->setSuccessor(0, OrigSucc);
4380   EXPECT_EQ(Switch->getSuccessor(0), OrigSucc);
4381   // Check case_begin(), case_end(), CaseIt.
4382   auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0);
4383   auto *One = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 1);
4384   auto CaseIt = Switch->case_begin();
4385   {
4386     sandboxir::SwitchInst::CaseHandle Case = *CaseIt++;
4387     EXPECT_EQ(Case.getCaseValue(), Zero);
4388     EXPECT_EQ(Case.getCaseSuccessor(), BB0);
4389     EXPECT_EQ(Case.getCaseIndex(), 0u);
4390     EXPECT_EQ(Case.getSuccessorIndex(), 1u);
4391   }
4392   {
4393     sandboxir::SwitchInst::CaseHandle Case = *CaseIt++;
4394     EXPECT_EQ(Case.getCaseValue(), One);
4395     EXPECT_EQ(Case.getCaseSuccessor(), BB1);
4396     EXPECT_EQ(Case.getCaseIndex(), 1u);
4397     EXPECT_EQ(Case.getSuccessorIndex(), 2u);
4398   }
4399   EXPECT_EQ(CaseIt, Switch->case_end());
4400   // Check cases().
4401   unsigned CntCase = 0;
4402   for (auto &Case : Switch->cases()) {
4403     EXPECT_EQ(Case.getCaseIndex(), CntCase);
4404     ++CntCase;
4405   }
4406   EXPECT_EQ(CntCase, 2u);
4407   // Check case_default().
4408   auto CaseDefault = *Switch->case_default();
4409   EXPECT_EQ(CaseDefault.getCaseSuccessor(), Default);
4410   EXPECT_EQ(CaseDefault.getCaseIndex(),
4411             sandboxir::SwitchInst::DefaultPseudoIndex);
4412   // Check findCaseValue().
4413   EXPECT_EQ(Switch->findCaseValue(Zero)->getCaseIndex(), 0u);
4414   EXPECT_EQ(Switch->findCaseValue(One)->getCaseIndex(), 1u);
4415   // Check findCaseDest().
4416   EXPECT_EQ(Switch->findCaseDest(BB0), Zero);
4417   EXPECT_EQ(Switch->findCaseDest(BB1), One);
4418   EXPECT_EQ(Switch->findCaseDest(Entry), nullptr);
4419   // Check addCase().
4420   auto *Two = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 2);
4421   Switch->addCase(Two, Entry);
4422   auto CaseTwoIt = Switch->findCaseValue(Two);
4423   auto CaseTwo = *CaseTwoIt;
4424   EXPECT_EQ(CaseTwo.getCaseValue(), Two);
4425   EXPECT_EQ(CaseTwo.getCaseSuccessor(), Entry);
4426   EXPECT_EQ(Switch->getNumCases(), 3u);
4427   // Check removeCase().
4428   auto RemovedIt = Switch->removeCase(CaseTwoIt);
4429   EXPECT_EQ(RemovedIt, Switch->case_end());
4430   EXPECT_EQ(Switch->getNumCases(), 2u);
4431   // Check create().
4432   auto NewSwitch = sandboxir::SwitchInst::create(
4433       Cond1, Default, 1, Default->begin(), Default, Ctx, "NewSwitch");
4434   EXPECT_TRUE(isa<sandboxir::SwitchInst>(NewSwitch));
4435   EXPECT_EQ(NewSwitch->getCondition(), Cond1);
4436   EXPECT_EQ(NewSwitch->getDefaultDest(), Default);
4437 }
4438 
4439 TEST_F(SandboxIRTest, UnaryOperator) {
4440   parseIR(C, R"IR(
4441 define void @foo(float %arg0) {
4442   %fneg = fneg float %arg0
4443   %copyfrom = fadd reassoc float %arg0, 42.0
4444   ret void
4445 }
4446 )IR");
4447   Function &LLVMF = *M->getFunction("foo");
4448   sandboxir::Context Ctx(C);
4449 
4450   auto &F = *Ctx.createFunction(&LLVMF);
4451   auto *Arg0 = F.getArg(0);
4452   auto *BB = &*F.begin();
4453   auto It = BB->begin();
4454   auto *I = cast<sandboxir::UnaryOperator>(&*It++);
4455   auto *CopyFrom = cast<sandboxir::BinaryOperator>(&*It++);
4456   auto *Ret = &*It++;
4457   EXPECT_EQ(I->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
4458   EXPECT_EQ(I->getOperand(0), Arg0);
4459 
4460   {
4461     // Check create() WhereIt, WhereBB.
4462     auto *NewI =
4463         cast<sandboxir::UnaryOperator>(sandboxir::UnaryOperator::create(
4464             sandboxir::Instruction::Opcode::FNeg, Arg0,
4465             /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx,
4466             "New1"));
4467     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
4468     EXPECT_EQ(NewI->getOperand(0), Arg0);
4469 #ifndef NDEBUG
4470     EXPECT_EQ(NewI->getName(), "New1");
4471 #endif // NDEBUG
4472     EXPECT_EQ(NewI->getNextNode(), Ret);
4473   }
4474   {
4475     // Check create() InsertBefore.
4476     auto *NewI =
4477         cast<sandboxir::UnaryOperator>(sandboxir::UnaryOperator::create(
4478             sandboxir::Instruction::Opcode::FNeg, Arg0,
4479             /*InsertBefore=*/Ret, Ctx, "New2"));
4480     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
4481     EXPECT_EQ(NewI->getOperand(0), Arg0);
4482 #ifndef NDEBUG
4483     EXPECT_EQ(NewI->getName(), "New2");
4484 #endif // NDEBUG
4485     EXPECT_EQ(NewI->getNextNode(), Ret);
4486   }
4487   {
4488     // Check create() InsertAtEnd.
4489     auto *NewI =
4490         cast<sandboxir::UnaryOperator>(sandboxir::UnaryOperator::create(
4491             sandboxir::Instruction::Opcode::FNeg, Arg0,
4492             /*InsertAtEnd=*/BB, Ctx, "New3"));
4493     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
4494     EXPECT_EQ(NewI->getOperand(0), Arg0);
4495 #ifndef NDEBUG
4496     EXPECT_EQ(NewI->getName(), "New3");
4497 #endif // NDEBUG
4498     EXPECT_EQ(NewI->getParent(), BB);
4499     EXPECT_EQ(NewI->getNextNode(), nullptr);
4500   }
4501   {
4502     // Check create() when it gets folded.
4503     auto *FortyTwo = CopyFrom->getOperand(1);
4504     auto *NewV = sandboxir::UnaryOperator::create(
4505         sandboxir::Instruction::Opcode::FNeg, FortyTwo,
4506         /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx,
4507         "Folded");
4508     EXPECT_TRUE(isa<sandboxir::Constant>(NewV));
4509   }
4510 
4511   {
4512     // Check createWithCopiedFlags() WhereIt, WhereBB.
4513     auto *NewI = cast<sandboxir::UnaryOperator>(
4514         sandboxir::UnaryOperator::createWithCopiedFlags(
4515             sandboxir::Instruction::Opcode::FNeg, Arg0, CopyFrom,
4516             /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx,
4517             "NewCopyFrom1"));
4518     EXPECT_EQ(NewI->hasAllowReassoc(), CopyFrom->hasAllowReassoc());
4519     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
4520     EXPECT_EQ(NewI->getOperand(0), Arg0);
4521 #ifndef NDEBUG
4522     EXPECT_EQ(NewI->getName(), "NewCopyFrom1");
4523 #endif // NDEBUG
4524     EXPECT_EQ(NewI->getNextNode(), Ret);
4525   }
4526   {
4527     // Check createWithCopiedFlags() InsertBefore,
4528     auto *NewI = cast<sandboxir::UnaryOperator>(
4529         sandboxir::UnaryOperator::createWithCopiedFlags(
4530             sandboxir::Instruction::Opcode::FNeg, Arg0, CopyFrom,
4531             /*InsertBefore=*/Ret, Ctx, "NewCopyFrom2"));
4532     EXPECT_EQ(NewI->hasAllowReassoc(), CopyFrom->hasAllowReassoc());
4533     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
4534     EXPECT_EQ(NewI->getOperand(0), Arg0);
4535 #ifndef NDEBUG
4536     EXPECT_EQ(NewI->getName(), "NewCopyFrom2");
4537 #endif // NDEBUG
4538     EXPECT_EQ(NewI->getNextNode(), Ret);
4539   }
4540   {
4541     // Check createWithCopiedFlags() InsertAtEnd,
4542     auto *NewI = cast<sandboxir::UnaryOperator>(
4543         sandboxir::UnaryOperator::createWithCopiedFlags(
4544             sandboxir::Instruction::Opcode::FNeg, Arg0, CopyFrom,
4545             /*InsertAtEnd=*/BB, Ctx, "NewCopyFrom3"));
4546     EXPECT_EQ(NewI->hasAllowReassoc(), CopyFrom->hasAllowReassoc());
4547     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
4548     EXPECT_EQ(NewI->getOperand(0), Arg0);
4549 #ifndef NDEBUG
4550     EXPECT_EQ(NewI->getName(), "NewCopyFrom3");
4551 #endif // NDEBUG
4552     EXPECT_EQ(NewI->getParent(), BB);
4553     EXPECT_EQ(NewI->getNextNode(), nullptr);
4554   }
4555   {
4556     // Check createWithCopiedFlags() when it gets folded.
4557     auto *FortyTwo = CopyFrom->getOperand(1);
4558     auto *NewV = sandboxir::UnaryOperator::createWithCopiedFlags(
4559         sandboxir::Instruction::Opcode::FNeg, FortyTwo, CopyFrom,
4560         /*InsertAtEnd=*/BB, Ctx, "Folded");
4561     EXPECT_TRUE(isa<sandboxir::Constant>(NewV));
4562   }
4563 }
4564 
4565 TEST_F(SandboxIRTest, BinaryOperator) {
4566   parseIR(C, R"IR(
4567 define void @foo(i8 %arg0, i8 %arg1, float %farg0, float %farg1) {
4568   %add = add i8 %arg0, %arg1
4569   %fadd = fadd float %farg0, %farg1
4570   %sub = sub i8 %arg0, %arg1
4571   %fsub = fsub float %farg0, %farg1
4572   %mul = mul i8 %arg0, %arg1
4573   %fmul = fmul float %farg0, %farg1
4574   %udiv = udiv i8 %arg0, %arg1
4575   %sdiv = sdiv i8 %arg0, %arg1
4576   %fdiv = fdiv float %farg0, %farg1
4577   %urem = urem i8 %arg0, %arg1
4578   %srem = srem i8 %arg0, %arg1
4579   %frem = frem float %farg0, %farg1
4580   %shl = shl i8 %arg0, %arg1
4581   %lshr = lshr i8 %arg0, %arg1
4582   %ashr = ashr i8 %arg0, %arg1
4583   %and = and i8 %arg0, %arg1
4584   %or = or i8 %arg0, %arg1
4585   %xor = xor i8 %arg0, %arg1
4586 
4587   %copyfrom = add nsw i8 %arg0, %arg1
4588   ret void
4589 }
4590 )IR");
4591   Function &LLVMF = *M->getFunction("foo");
4592   sandboxir::Context Ctx(C);
4593 
4594   auto &F = *Ctx.createFunction(&LLVMF);
4595   auto *Arg0 = F.getArg(0);
4596   auto *Arg1 = F.getArg(1);
4597   auto *FArg0 = F.getArg(2);
4598   auto *FArg1 = F.getArg(3);
4599   auto *BB = &*F.begin();
4600   auto It = BB->begin();
4601 
4602 #define CHECK_IBINOP(OPCODE)                                                   \
4603   {                                                                            \
4604     auto *I = cast<sandboxir::BinaryOperator>(&*It++);                         \
4605     EXPECT_EQ(I->getOpcode(), OPCODE);                                         \
4606     EXPECT_EQ(I->getOperand(0), Arg0);                                         \
4607     EXPECT_EQ(I->getOperand(1), Arg1);                                         \
4608   }
4609 #define CHECK_FBINOP(OPCODE)                                                   \
4610   {                                                                            \
4611     auto *I = cast<sandboxir::BinaryOperator>(&*It++);                         \
4612     EXPECT_EQ(I->getOpcode(), OPCODE);                                         \
4613     EXPECT_EQ(I->getOperand(0), FArg0);                                        \
4614     EXPECT_EQ(I->getOperand(1), FArg1);                                        \
4615   }
4616 
4617   CHECK_IBINOP(sandboxir::Instruction::Opcode::Add);
4618   CHECK_FBINOP(sandboxir::Instruction::Opcode::FAdd);
4619   CHECK_IBINOP(sandboxir::Instruction::Opcode::Sub);
4620   CHECK_FBINOP(sandboxir::Instruction::Opcode::FSub);
4621   CHECK_IBINOP(sandboxir::Instruction::Opcode::Mul);
4622   CHECK_FBINOP(sandboxir::Instruction::Opcode::FMul);
4623   CHECK_IBINOP(sandboxir::Instruction::Opcode::UDiv);
4624   CHECK_IBINOP(sandboxir::Instruction::Opcode::SDiv);
4625   CHECK_FBINOP(sandboxir::Instruction::Opcode::FDiv);
4626   CHECK_IBINOP(sandboxir::Instruction::Opcode::URem);
4627   CHECK_IBINOP(sandboxir::Instruction::Opcode::SRem);
4628   CHECK_FBINOP(sandboxir::Instruction::Opcode::FRem);
4629   CHECK_IBINOP(sandboxir::Instruction::Opcode::Shl);
4630   CHECK_IBINOP(sandboxir::Instruction::Opcode::LShr);
4631   CHECK_IBINOP(sandboxir::Instruction::Opcode::AShr);
4632   CHECK_IBINOP(sandboxir::Instruction::Opcode::And);
4633   CHECK_IBINOP(sandboxir::Instruction::Opcode::Or);
4634   CHECK_IBINOP(sandboxir::Instruction::Opcode::Xor);
4635 
4636   auto *CopyFrom = cast<sandboxir::BinaryOperator>(&*It++);
4637   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
4638 
4639   {
4640     // Check create() WhereIt, WhereBB.
4641     auto *NewI =
4642         cast<sandboxir::BinaryOperator>(sandboxir::BinaryOperator::create(
4643             sandboxir::Instruction::Opcode::Add, Arg0, Arg1,
4644             /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx,
4645             "New1"));
4646     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
4647     EXPECT_EQ(NewI->getOperand(0), Arg0);
4648     EXPECT_EQ(NewI->getOperand(1), Arg1);
4649 #ifndef NDEBUG
4650     EXPECT_EQ(NewI->getName(), "New1");
4651 #endif // NDEBUG
4652     EXPECT_EQ(NewI->getNextNode(), Ret);
4653   }
4654   {
4655     // Check create() InsertBefore.
4656     auto *NewI =
4657         cast<sandboxir::BinaryOperator>(sandboxir::BinaryOperator::create(
4658             sandboxir::Instruction::Opcode::Add, Arg0, Arg1,
4659             /*InsertBefore=*/Ret, Ctx, "New2"));
4660     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
4661     EXPECT_EQ(NewI->getOperand(0), Arg0);
4662     EXPECT_EQ(NewI->getOperand(1), Arg1);
4663 #ifndef NDEBUG
4664     EXPECT_EQ(NewI->getName(), "New2");
4665 #endif // NDEBUG
4666     EXPECT_EQ(NewI->getNextNode(), Ret);
4667   }
4668   {
4669     // Check create() InsertAtEnd.
4670     auto *NewI =
4671         cast<sandboxir::BinaryOperator>(sandboxir::BinaryOperator::create(
4672             sandboxir::Instruction::Opcode::Add, Arg0, Arg1,
4673             /*InsertAtEnd=*/BB, Ctx, "New3"));
4674     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
4675     EXPECT_EQ(NewI->getOperand(0), Arg0);
4676     EXPECT_EQ(NewI->getOperand(1), Arg1);
4677 #ifndef NDEBUG
4678     EXPECT_EQ(NewI->getName(), "New3");
4679 #endif // NDEBUG
4680     EXPECT_EQ(NewI->getNextNode(), nullptr);
4681     EXPECT_EQ(NewI->getParent(), BB);
4682   }
4683   {
4684     // Check create() when it gets folded.
4685     auto *FortyTwo =
4686         sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42);
4687     auto *NewV = sandboxir::BinaryOperator::create(
4688         sandboxir::Instruction::Opcode::Add, FortyTwo, FortyTwo,
4689         /*InsertBefore=*/Ret, Ctx, "Folded");
4690     EXPECT_TRUE(isa<sandboxir::Constant>(NewV));
4691   }
4692 
4693   {
4694     // Check createWithCopiedFlags() WhereIt, WhereBB.
4695     auto *NewI = cast<sandboxir::BinaryOperator>(
4696         sandboxir::BinaryOperator::createWithCopiedFlags(
4697             sandboxir::Instruction::Opcode::Add, Arg0, Arg1, CopyFrom,
4698             /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx,
4699             "NewNSW1"));
4700     EXPECT_EQ(NewI->hasNoSignedWrap(), CopyFrom->hasNoSignedWrap());
4701     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
4702     EXPECT_EQ(NewI->getOperand(0), Arg0);
4703     EXPECT_EQ(NewI->getOperand(1), Arg1);
4704 #ifndef NDEBUG
4705     EXPECT_EQ(NewI->getName(), "NewNSW1");
4706 #endif // NDEBUG
4707     EXPECT_EQ(NewI->getNextNode(), Ret);
4708   }
4709   {
4710     // Check createWithCopiedFlags() InsertBefore.
4711     auto *NewI = cast<sandboxir::BinaryOperator>(
4712         sandboxir::BinaryOperator::createWithCopiedFlags(
4713             sandboxir::Instruction::Opcode::Add, Arg0, Arg1, CopyFrom,
4714             /*InsertBefore=*/Ret, Ctx, "NewNSW2"));
4715     EXPECT_EQ(NewI->hasNoSignedWrap(), CopyFrom->hasNoSignedWrap());
4716     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
4717     EXPECT_EQ(NewI->getOperand(0), Arg0);
4718     EXPECT_EQ(NewI->getOperand(1), Arg1);
4719 #ifndef NDEBUG
4720     EXPECT_EQ(NewI->getName(), "NewNSW2");
4721 #endif // NDEBUG
4722     EXPECT_EQ(NewI->getNextNode(), Ret);
4723   }
4724   {
4725     // Check createWithCopiedFlags() InsertAtEnd.
4726     auto *NewI = cast<sandboxir::BinaryOperator>(
4727         sandboxir::BinaryOperator::createWithCopiedFlags(
4728             sandboxir::Instruction::Opcode::Add, Arg0, Arg1, CopyFrom,
4729             /*InsertAtEnd=*/BB, Ctx, "NewNSW3"));
4730     EXPECT_EQ(NewI->hasNoSignedWrap(), CopyFrom->hasNoSignedWrap());
4731     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
4732     EXPECT_EQ(NewI->getOperand(0), Arg0);
4733     EXPECT_EQ(NewI->getOperand(1), Arg1);
4734 #ifndef NDEBUG
4735     EXPECT_EQ(NewI->getName(), "NewNSW3");
4736 #endif // NDEBUG
4737     EXPECT_EQ(NewI->getParent(), BB);
4738     EXPECT_EQ(NewI->getNextNode(), nullptr);
4739   }
4740   {
4741     // Check createWithCopiedFlags() when it gets folded.
4742     auto *FortyTwo =
4743         sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42);
4744     auto *NewV = sandboxir::BinaryOperator::createWithCopiedFlags(
4745         sandboxir::Instruction::Opcode::Add, FortyTwo, FortyTwo, CopyFrom,
4746         /*InsertBefore=*/Ret, Ctx, "Folded");
4747     EXPECT_TRUE(isa<sandboxir::Constant>(NewV));
4748   }
4749 }
4750 
4751 TEST_F(SandboxIRTest, PossiblyDisjointInst) {
4752   parseIR(C, R"IR(
4753 define void @foo(i8 %arg0, i8 %arg1) {
4754   %or = or i8 %arg0, %arg1
4755   ret void
4756 }
4757 )IR");
4758   Function &LLVMF = *M->getFunction("foo");
4759   sandboxir::Context Ctx(C);
4760 
4761   auto &F = *Ctx.createFunction(&LLVMF);
4762   auto *BB = &*F.begin();
4763   auto It = BB->begin();
4764   auto *PDI = cast<sandboxir::PossiblyDisjointInst>(&*It++);
4765 
4766   // Check setIsDisjoint(), isDisjoint().
4767   auto OrigIsDisjoint = PDI->isDisjoint();
4768   auto NewIsDisjoint = true;
4769   EXPECT_NE(NewIsDisjoint, OrigIsDisjoint);
4770   PDI->setIsDisjoint(NewIsDisjoint);
4771   EXPECT_EQ(PDI->isDisjoint(), NewIsDisjoint);
4772   PDI->setIsDisjoint(OrigIsDisjoint);
4773   EXPECT_EQ(PDI->isDisjoint(), OrigIsDisjoint);
4774 }
4775 
4776 TEST_F(SandboxIRTest, AtomicRMWInst) {
4777   parseIR(C, R"IR(
4778 define void @foo(ptr %ptr, i8 %arg) {
4779   %atomicrmw = atomicrmw add ptr %ptr, i8 %arg acquire, align 128
4780   ret void
4781 }
4782 )IR");
4783   llvm::Function &LLVMF = *M->getFunction("foo");
4784   llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
4785   auto LLVMIt = LLVMBB->begin();
4786   auto *LLVMRMW = cast<llvm::AtomicRMWInst>(&*LLVMIt++);
4787 
4788   sandboxir::Context Ctx(C);
4789   sandboxir::Function *F = Ctx.createFunction(&LLVMF);
4790   auto *Ptr = F->getArg(0);
4791   auto *Arg = F->getArg(1);
4792   auto *BB = &*F->begin();
4793   auto It = BB->begin();
4794   auto *RMW = cast<sandboxir::AtomicRMWInst>(&*It++);
4795   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
4796 
4797   // Check getOperationName().
4798   EXPECT_EQ(
4799       sandboxir::AtomicRMWInst::getOperationName(
4800           sandboxir::AtomicRMWInst::BinOp::Add),
4801       llvm::AtomicRMWInst::getOperationName(llvm::AtomicRMWInst::BinOp::Add));
4802   // Check isFPOperation().
4803   EXPECT_EQ(
4804       sandboxir::AtomicRMWInst::isFPOperation(
4805           sandboxir::AtomicRMWInst::BinOp::Add),
4806       llvm::AtomicRMWInst::isFPOperation(llvm::AtomicRMWInst::BinOp::Add));
4807   EXPECT_FALSE(sandboxir::AtomicRMWInst::isFPOperation(
4808       sandboxir::AtomicRMWInst::BinOp::Add));
4809   EXPECT_TRUE(sandboxir::AtomicRMWInst::isFPOperation(
4810       sandboxir::AtomicRMWInst::BinOp::FAdd));
4811   // Check setOperation(), getOperation().
4812   EXPECT_EQ(RMW->getOperation(), LLVMRMW->getOperation());
4813   RMW->setOperation(sandboxir::AtomicRMWInst::BinOp::Sub);
4814   EXPECT_EQ(RMW->getOperation(), sandboxir::AtomicRMWInst::BinOp::Sub);
4815   RMW->setOperation(sandboxir::AtomicRMWInst::BinOp::Add);
4816   // Check getAlign().
4817   EXPECT_EQ(RMW->getAlign(), LLVMRMW->getAlign());
4818   auto OrigAlign = RMW->getAlign();
4819   Align NewAlign(256);
4820   EXPECT_NE(NewAlign, OrigAlign);
4821   RMW->setAlignment(NewAlign);
4822   EXPECT_EQ(RMW->getAlign(), NewAlign);
4823   RMW->setAlignment(OrigAlign);
4824   EXPECT_EQ(RMW->getAlign(), OrigAlign);
4825   // Check isVolatile(), setVolatile().
4826   EXPECT_EQ(RMW->isVolatile(), LLVMRMW->isVolatile());
4827   bool OrigV = RMW->isVolatile();
4828   bool NewV = true;
4829   EXPECT_NE(NewV, OrigV);
4830   RMW->setVolatile(NewV);
4831   EXPECT_EQ(RMW->isVolatile(), NewV);
4832   RMW->setVolatile(OrigV);
4833   EXPECT_EQ(RMW->isVolatile(), OrigV);
4834   // Check getOrdering(), setOrdering().
4835   EXPECT_EQ(RMW->getOrdering(), LLVMRMW->getOrdering());
4836   auto OldOrdering = RMW->getOrdering();
4837   auto NewOrdering = AtomicOrdering::Monotonic;
4838   EXPECT_NE(NewOrdering, OldOrdering);
4839   RMW->setOrdering(NewOrdering);
4840   EXPECT_EQ(RMW->getOrdering(), NewOrdering);
4841   RMW->setOrdering(OldOrdering);
4842   EXPECT_EQ(RMW->getOrdering(), OldOrdering);
4843   // Check getSyncScopeID(), setSyncScopeID().
4844   EXPECT_EQ(RMW->getSyncScopeID(), LLVMRMW->getSyncScopeID());
4845   auto OrigSSID = RMW->getSyncScopeID();
4846   SyncScope::ID NewSSID = SyncScope::SingleThread;
4847   EXPECT_NE(NewSSID, OrigSSID);
4848   RMW->setSyncScopeID(NewSSID);
4849   EXPECT_EQ(RMW->getSyncScopeID(), NewSSID);
4850   RMW->setSyncScopeID(OrigSSID);
4851   EXPECT_EQ(RMW->getSyncScopeID(), OrigSSID);
4852   // Check getPointerOperand().
4853   EXPECT_EQ(RMW->getPointerOperand(),
4854             Ctx.getValue(LLVMRMW->getPointerOperand()));
4855   // Check getValOperand().
4856   EXPECT_EQ(RMW->getValOperand(), Ctx.getValue(LLVMRMW->getValOperand()));
4857   // Check getPointerAddressSpace().
4858   EXPECT_EQ(RMW->getPointerAddressSpace(), LLVMRMW->getPointerAddressSpace());
4859   // Check isFloatingPointOperation().
4860   EXPECT_EQ(RMW->isFloatingPointOperation(),
4861             LLVMRMW->isFloatingPointOperation());
4862 
4863   Align Align(1024);
4864   auto Ordering = AtomicOrdering::Acquire;
4865   auto SSID = SyncScope::System;
4866   {
4867     // Check create() WhereIt, WhereBB.
4868     auto *NewI =
4869         cast<sandboxir::AtomicRMWInst>(sandboxir::AtomicRMWInst::create(
4870             sandboxir::AtomicRMWInst::BinOp::Sub, Ptr, Arg, Align, Ordering,
4871             /*WhereIt=*/Ret->getIterator(),
4872             /*WhereBB=*/Ret->getParent(), Ctx, SSID, "NewAtomicRMW1"));
4873     // Check getOpcode().
4874     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicRMW);
4875     // Check getAlign().
4876     EXPECT_EQ(NewI->getAlign(), Align);
4877     // Check getSuccessOrdering().
4878     EXPECT_EQ(NewI->getOrdering(), Ordering);
4879     // Check instr position.
4880     EXPECT_EQ(NewI->getNextNode(), Ret);
4881     // Check getPointerOperand().
4882     EXPECT_EQ(NewI->getPointerOperand(), Ptr);
4883     // Check getValOperand().
4884     EXPECT_EQ(NewI->getValOperand(), Arg);
4885 #ifndef NDEBUG
4886     // Check getName().
4887     EXPECT_EQ(NewI->getName(), "NewAtomicRMW1");
4888 #endif // NDEBUG
4889   }
4890   {
4891     // Check create() InsertBefore.
4892     auto *NewI =
4893         cast<sandboxir::AtomicRMWInst>(sandboxir::AtomicRMWInst::create(
4894             sandboxir::AtomicRMWInst::BinOp::Sub, Ptr, Arg, Align, Ordering,
4895             /*InsertBefore=*/Ret, Ctx, SSID, "NewAtomicRMW2"));
4896     // Check getOpcode().
4897     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicRMW);
4898     // Check getAlign().
4899     EXPECT_EQ(NewI->getAlign(), Align);
4900     // Check getSuccessOrdering().
4901     EXPECT_EQ(NewI->getOrdering(), Ordering);
4902     // Check instr position.
4903     EXPECT_EQ(NewI->getNextNode(), Ret);
4904     // Check getPointerOperand().
4905     EXPECT_EQ(NewI->getPointerOperand(), Ptr);
4906     // Check getValOperand().
4907     EXPECT_EQ(NewI->getValOperand(), Arg);
4908 #ifndef NDEBUG
4909     // Check getName().
4910     EXPECT_EQ(NewI->getName(), "NewAtomicRMW2");
4911 #endif // NDEBUG
4912   }
4913   {
4914     // Check create() InsertAtEnd.
4915     auto *NewI =
4916         cast<sandboxir::AtomicRMWInst>(sandboxir::AtomicRMWInst::create(
4917             sandboxir::AtomicRMWInst::BinOp::Sub, Ptr, Arg, Align, Ordering,
4918             /*InsertAtEnd=*/BB, Ctx, SSID, "NewAtomicRMW3"));
4919     // Check getOpcode().
4920     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicRMW);
4921     // Check getAlign().
4922     EXPECT_EQ(NewI->getAlign(), Align);
4923     // Check getSuccessOrdering().
4924     EXPECT_EQ(NewI->getOrdering(), Ordering);
4925     // Check instr position.
4926     EXPECT_EQ(NewI->getParent(), BB);
4927     EXPECT_EQ(NewI->getNextNode(), nullptr);
4928     // Check getPointerOperand().
4929     EXPECT_EQ(NewI->getPointerOperand(), Ptr);
4930     // Check getValOperand().
4931     EXPECT_EQ(NewI->getValOperand(), Arg);
4932 #ifndef NDEBUG
4933     // Check getName().
4934     EXPECT_EQ(NewI->getName(), "NewAtomicRMW3");
4935 #endif // NDEBUG
4936   }
4937 }
4938 
4939 TEST_F(SandboxIRTest, AtomicCmpXchgInst) {
4940   parseIR(C, R"IR(
4941 define void @foo(ptr %ptr, i8 %cmp, i8 %new) {
4942   %cmpxchg = cmpxchg ptr %ptr, i8 %cmp, i8 %new monotonic monotonic, align 128
4943   ret void
4944 }
4945 )IR");
4946   llvm::Function &LLVMF = *M->getFunction("foo");
4947   llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
4948   auto LLVMIt = LLVMBB->begin();
4949   auto *LLVMCmpXchg = cast<llvm::AtomicCmpXchgInst>(&*LLVMIt++);
4950 
4951   sandboxir::Context Ctx(C);
4952   sandboxir::Function *F = Ctx.createFunction(&LLVMF);
4953   auto *Ptr = F->getArg(0);
4954   auto *Cmp = F->getArg(1);
4955   auto *New = F->getArg(2);
4956   auto *BB = &*F->begin();
4957   auto It = BB->begin();
4958   auto *CmpXchg = cast<sandboxir::AtomicCmpXchgInst>(&*It++);
4959   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
4960 
4961   // Check getAlign(), setAlignment().
4962   EXPECT_EQ(CmpXchg->getAlign(), LLVMCmpXchg->getAlign());
4963   auto OrigAlign = CmpXchg->getAlign();
4964   Align NewAlign(256);
4965   EXPECT_NE(NewAlign, OrigAlign);
4966   CmpXchg->setAlignment(NewAlign);
4967   EXPECT_EQ(CmpXchg->getAlign(), NewAlign);
4968   CmpXchg->setAlignment(OrigAlign);
4969   EXPECT_EQ(CmpXchg->getAlign(), OrigAlign);
4970   // Check isVolatile(), setVolatile().
4971   EXPECT_EQ(CmpXchg->isVolatile(), LLVMCmpXchg->isVolatile());
4972   bool OrigV = CmpXchg->isVolatile();
4973   bool NewV = true;
4974   EXPECT_NE(NewV, OrigV);
4975   CmpXchg->setVolatile(NewV);
4976   EXPECT_EQ(CmpXchg->isVolatile(), NewV);
4977   CmpXchg->setVolatile(OrigV);
4978   EXPECT_EQ(CmpXchg->isVolatile(), OrigV);
4979   // Check isWeak(), setWeak().
4980   EXPECT_EQ(CmpXchg->isWeak(), LLVMCmpXchg->isWeak());
4981   bool OrigWeak = CmpXchg->isWeak();
4982   bool NewWeak = true;
4983   EXPECT_NE(NewWeak, OrigWeak);
4984   CmpXchg->setWeak(NewWeak);
4985   EXPECT_EQ(CmpXchg->isWeak(), NewWeak);
4986   CmpXchg->setWeak(OrigWeak);
4987   EXPECT_EQ(CmpXchg->isWeak(), OrigWeak);
4988   // Check isValidSuccessOrdering(), isValidFailureOrdering().
4989   SmallVector<AtomicOrdering> AllOrderings(
4990       {AtomicOrdering::NotAtomic, AtomicOrdering::Unordered,
4991        AtomicOrdering::Monotonic, AtomicOrdering::Acquire,
4992        AtomicOrdering::Release, AtomicOrdering::AcquireRelease,
4993        AtomicOrdering::SequentiallyConsistent});
4994   for (auto Ordering : AllOrderings) {
4995     EXPECT_EQ(sandboxir::AtomicCmpXchgInst::isValidSuccessOrdering(Ordering),
4996               llvm::AtomicCmpXchgInst::isValidSuccessOrdering(Ordering));
4997     EXPECT_EQ(sandboxir::AtomicCmpXchgInst::isValidFailureOrdering(Ordering),
4998               llvm::AtomicCmpXchgInst::isValidFailureOrdering(Ordering));
4999   }
5000   // Check getSuccessOrdering(), setSuccessOrdering().
5001   EXPECT_EQ(CmpXchg->getSuccessOrdering(), LLVMCmpXchg->getSuccessOrdering());
5002   auto OldSuccOrdering = CmpXchg->getSuccessOrdering();
5003   auto NewSuccOrdering = AtomicOrdering::Acquire;
5004   EXPECT_NE(NewSuccOrdering, OldSuccOrdering);
5005   CmpXchg->setSuccessOrdering(NewSuccOrdering);
5006   EXPECT_EQ(CmpXchg->getSuccessOrdering(), NewSuccOrdering);
5007   CmpXchg->setSuccessOrdering(OldSuccOrdering);
5008   EXPECT_EQ(CmpXchg->getSuccessOrdering(), OldSuccOrdering);
5009   // Check getFailureOrdering(), setFailureOrdering().
5010   EXPECT_EQ(CmpXchg->getFailureOrdering(), LLVMCmpXchg->getFailureOrdering());
5011   auto OldFailOrdering = CmpXchg->getFailureOrdering();
5012   auto NewFailOrdering = AtomicOrdering::Acquire;
5013   EXPECT_NE(NewFailOrdering, OldFailOrdering);
5014   CmpXchg->setFailureOrdering(NewFailOrdering);
5015   EXPECT_EQ(CmpXchg->getFailureOrdering(), NewFailOrdering);
5016   CmpXchg->setFailureOrdering(OldFailOrdering);
5017   EXPECT_EQ(CmpXchg->getFailureOrdering(), OldFailOrdering);
5018   // Check getMergedOrdering().
5019   EXPECT_EQ(CmpXchg->getMergedOrdering(), LLVMCmpXchg->getMergedOrdering());
5020   // Check getSyncScopeID(), setSyncScopeID().
5021   EXPECT_EQ(CmpXchg->getSyncScopeID(), LLVMCmpXchg->getSyncScopeID());
5022   auto OrigSSID = CmpXchg->getSyncScopeID();
5023   SyncScope::ID NewSSID = SyncScope::SingleThread;
5024   EXPECT_NE(NewSSID, OrigSSID);
5025   CmpXchg->setSyncScopeID(NewSSID);
5026   EXPECT_EQ(CmpXchg->getSyncScopeID(), NewSSID);
5027   CmpXchg->setSyncScopeID(OrigSSID);
5028   EXPECT_EQ(CmpXchg->getSyncScopeID(), OrigSSID);
5029   // Check getPointerOperand().
5030   EXPECT_EQ(CmpXchg->getPointerOperand(),
5031             Ctx.getValue(LLVMCmpXchg->getPointerOperand()));
5032   // Check getCompareOperand().
5033   EXPECT_EQ(CmpXchg->getCompareOperand(),
5034             Ctx.getValue(LLVMCmpXchg->getCompareOperand()));
5035   // Check getNewValOperand().
5036   EXPECT_EQ(CmpXchg->getNewValOperand(),
5037             Ctx.getValue(LLVMCmpXchg->getNewValOperand()));
5038   // Check getPointerAddressSpace().
5039   EXPECT_EQ(CmpXchg->getPointerAddressSpace(),
5040             LLVMCmpXchg->getPointerAddressSpace());
5041 
5042   Align Align(1024);
5043   auto SuccOrdering = AtomicOrdering::Acquire;
5044   auto FailOrdering = AtomicOrdering::Monotonic;
5045   auto SSID = SyncScope::System;
5046   {
5047     // Check create() WhereIt, WhereBB.
5048     auto *NewI =
5049         cast<sandboxir::AtomicCmpXchgInst>(sandboxir::AtomicCmpXchgInst::create(
5050             Ptr, Cmp, New, Align, SuccOrdering, FailOrdering,
5051             /*WhereIt=*/Ret->getIterator(),
5052             /*WhereBB=*/Ret->getParent(), Ctx, SSID, "NewAtomicCmpXchg1"));
5053     // Check getOpcode().
5054     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicCmpXchg);
5055     // Check getAlign().
5056     EXPECT_EQ(NewI->getAlign(), Align);
5057     // Check getSuccessOrdering().
5058     EXPECT_EQ(NewI->getSuccessOrdering(), SuccOrdering);
5059     // Check getFailureOrdering().
5060     EXPECT_EQ(NewI->getFailureOrdering(), FailOrdering);
5061     // Check instr position.
5062     EXPECT_EQ(NewI->getNextNode(), Ret);
5063     // Check getPointerOperand().
5064     EXPECT_EQ(NewI->getPointerOperand(), Ptr);
5065     // Check getCompareOperand().
5066     EXPECT_EQ(NewI->getCompareOperand(), Cmp);
5067     // Check getNewValOperand().
5068     EXPECT_EQ(NewI->getNewValOperand(), New);
5069 #ifndef NDEBUG
5070     // Check getName().
5071     EXPECT_EQ(NewI->getName(), "NewAtomicCmpXchg1");
5072 #endif // NDEBUG
5073   }
5074   {
5075     // Check create() InsertBefore.
5076     auto *NewI =
5077         cast<sandboxir::AtomicCmpXchgInst>(sandboxir::AtomicCmpXchgInst::create(
5078             Ptr, Cmp, New, Align, SuccOrdering, FailOrdering,
5079             /*InsertBefore=*/Ret, Ctx, SSID, "NewAtomicCmpXchg2"));
5080     // Check getOpcode().
5081     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicCmpXchg);
5082     // Check getAlign().
5083     EXPECT_EQ(NewI->getAlign(), Align);
5084     // Check getSuccessOrdering().
5085     EXPECT_EQ(NewI->getSuccessOrdering(), SuccOrdering);
5086     // Check getFailureOrdering().
5087     EXPECT_EQ(NewI->getFailureOrdering(), FailOrdering);
5088     // Check instr position.
5089     EXPECT_EQ(NewI->getNextNode(), Ret);
5090     // Check getPointerOperand().
5091     EXPECT_EQ(NewI->getPointerOperand(), Ptr);
5092     // Check getCompareOperand().
5093     EXPECT_EQ(NewI->getCompareOperand(), Cmp);
5094     // Check getNewValOperand().
5095     EXPECT_EQ(NewI->getNewValOperand(), New);
5096 #ifndef NDEBUG
5097     // Check getName().
5098     EXPECT_EQ(NewI->getName(), "NewAtomicCmpXchg2");
5099 #endif // NDEBUG
5100   }
5101   {
5102     // Check create() InsertAtEnd.
5103     auto *NewI =
5104         cast<sandboxir::AtomicCmpXchgInst>(sandboxir::AtomicCmpXchgInst::create(
5105             Ptr, Cmp, New, Align, SuccOrdering, FailOrdering,
5106             /*InsertAtEnd=*/BB, Ctx, SSID, "NewAtomicCmpXchg3"));
5107     // Check getOpcode().
5108     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicCmpXchg);
5109     // Check getAlign().
5110     EXPECT_EQ(NewI->getAlign(), Align);
5111     // Check getSuccessOrdering().
5112     EXPECT_EQ(NewI->getSuccessOrdering(), SuccOrdering);
5113     // Check getFailureOrdering().
5114     EXPECT_EQ(NewI->getFailureOrdering(), FailOrdering);
5115     // Check instr position.
5116     EXPECT_EQ(NewI->getParent(), BB);
5117     EXPECT_EQ(NewI->getNextNode(), nullptr);
5118     // Check getPointerOperand().
5119     EXPECT_EQ(NewI->getPointerOperand(), Ptr);
5120     // Check getCompareOperand().
5121     EXPECT_EQ(NewI->getCompareOperand(), Cmp);
5122     // Check getNewValOperand().
5123     EXPECT_EQ(NewI->getNewValOperand(), New);
5124 #ifndef NDEBUG
5125     // Check getName().
5126     EXPECT_EQ(NewI->getName(), "NewAtomicCmpXchg3");
5127 #endif // NDEBUG
5128   }
5129 }
5130 
5131 TEST_F(SandboxIRTest, AllocaInst) {
5132   parseIR(C, R"IR(
5133 define void @foo() {
5134   %allocaScalar = alloca i32, align 1024
5135   %allocaArray = alloca i32, i32 42
5136   ret void
5137 }
5138 )IR");
5139   const DataLayout &DL = M->getDataLayout();
5140   llvm::Function &LLVMF = *M->getFunction("foo");
5141   llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
5142   auto LLVMIt = LLVMBB->begin();
5143   auto *LLVMAllocaScalar = cast<llvm::AllocaInst>(&*LLVMIt++);
5144   auto *LLVMAllocaArray = cast<llvm::AllocaInst>(&*LLVMIt++);
5145 
5146   sandboxir::Context Ctx(C);
5147   sandboxir::Function *F = Ctx.createFunction(&LLVMF);
5148   auto *BB = &*F->begin();
5149   auto It = BB->begin();
5150   auto *AllocaScalar = cast<sandboxir::AllocaInst>(&*It++);
5151   auto *AllocaArray = cast<sandboxir::AllocaInst>(&*It++);
5152   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
5153 
5154   // Check isArrayAllocation().
5155   EXPECT_EQ(AllocaScalar->isArrayAllocation(),
5156             LLVMAllocaScalar->isArrayAllocation());
5157   EXPECT_EQ(AllocaArray->isArrayAllocation(),
5158             LLVMAllocaArray->isArrayAllocation());
5159   // Check getArraySize().
5160   EXPECT_EQ(AllocaScalar->getArraySize(),
5161             Ctx.getValue(LLVMAllocaScalar->getArraySize()));
5162   EXPECT_EQ(AllocaArray->getArraySize(),
5163             Ctx.getValue(LLVMAllocaArray->getArraySize()));
5164   // Check getType().
5165   EXPECT_EQ(AllocaScalar->getType(), Ctx.getType(LLVMAllocaScalar->getType()));
5166   EXPECT_EQ(AllocaArray->getType(), Ctx.getType(LLVMAllocaArray->getType()));
5167   // Check getAddressSpace().
5168   EXPECT_EQ(AllocaScalar->getAddressSpace(),
5169             LLVMAllocaScalar->getAddressSpace());
5170   EXPECT_EQ(AllocaArray->getAddressSpace(), LLVMAllocaArray->getAddressSpace());
5171   // Check getAllocationSize().
5172   EXPECT_EQ(AllocaScalar->getAllocationSize(DL),
5173             LLVMAllocaScalar->getAllocationSize(DL));
5174   EXPECT_EQ(AllocaArray->getAllocationSize(DL),
5175             LLVMAllocaArray->getAllocationSize(DL));
5176   // Check getAllocationSizeInBits().
5177   EXPECT_EQ(AllocaScalar->getAllocationSizeInBits(DL),
5178             LLVMAllocaScalar->getAllocationSizeInBits(DL));
5179   EXPECT_EQ(AllocaArray->getAllocationSizeInBits(DL),
5180             LLVMAllocaArray->getAllocationSizeInBits(DL));
5181   // Check getAllocatedType().
5182   EXPECT_EQ(AllocaScalar->getAllocatedType(),
5183             Ctx.getType(LLVMAllocaScalar->getAllocatedType()));
5184   EXPECT_EQ(AllocaArray->getAllocatedType(),
5185             Ctx.getType(LLVMAllocaArray->getAllocatedType()));
5186   // Check setAllocatedType().
5187   auto *OrigType = AllocaScalar->getAllocatedType();
5188   auto *NewType = sandboxir::PointerType::get(Ctx, 0);
5189   EXPECT_NE(NewType, OrigType);
5190   AllocaScalar->setAllocatedType(NewType);
5191   EXPECT_EQ(AllocaScalar->getAllocatedType(), NewType);
5192   AllocaScalar->setAllocatedType(OrigType);
5193   EXPECT_EQ(AllocaScalar->getAllocatedType(), OrigType);
5194   // Check getAlign().
5195   EXPECT_EQ(AllocaScalar->getAlign(), LLVMAllocaScalar->getAlign());
5196   EXPECT_EQ(AllocaArray->getAlign(), LLVMAllocaArray->getAlign());
5197   // Check setAlignment().
5198   Align OrigAlign = AllocaScalar->getAlign();
5199   Align NewAlign(16);
5200   EXPECT_NE(NewAlign, OrigAlign);
5201   AllocaScalar->setAlignment(NewAlign);
5202   EXPECT_EQ(AllocaScalar->getAlign(), NewAlign);
5203   AllocaScalar->setAlignment(OrigAlign);
5204   EXPECT_EQ(AllocaScalar->getAlign(), OrigAlign);
5205   // Check isStaticAlloca().
5206   EXPECT_EQ(AllocaScalar->isStaticAlloca(), LLVMAllocaScalar->isStaticAlloca());
5207   EXPECT_EQ(AllocaArray->isStaticAlloca(), LLVMAllocaArray->isStaticAlloca());
5208   // Check isUsedWithInAlloca(), setUsedWithInAlloca().
5209   EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(),
5210             LLVMAllocaScalar->isUsedWithInAlloca());
5211   bool OrigUsedWithInAlloca = AllocaScalar->isUsedWithInAlloca();
5212   bool NewUsedWithInAlloca = true;
5213   EXPECT_NE(NewUsedWithInAlloca, OrigUsedWithInAlloca);
5214   AllocaScalar->setUsedWithInAlloca(NewUsedWithInAlloca);
5215   EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(), NewUsedWithInAlloca);
5216   AllocaScalar->setUsedWithInAlloca(OrigUsedWithInAlloca);
5217   EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(), OrigUsedWithInAlloca);
5218 
5219   auto *Ty = sandboxir::Type::getInt32Ty(Ctx);
5220   unsigned AddrSpace = 42;
5221   auto *PtrTy = sandboxir::PointerType::get(Ctx, AddrSpace);
5222   auto *ArraySize = sandboxir::ConstantInt::get(Ty, 43);
5223   {
5224     // Check create() WhereIt, WhereBB.
5225     auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create(
5226         Ty, AddrSpace, /*WhereIt=*/Ret->getIterator(),
5227         /*WhereBB=*/Ret->getParent(), Ctx, ArraySize, "NewAlloca1"));
5228     // Check getOpcode().
5229     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca);
5230     // Check getType().
5231     EXPECT_EQ(NewI->getType(), PtrTy);
5232     // Check getArraySize().
5233     EXPECT_EQ(NewI->getArraySize(), ArraySize);
5234     // Check getAddrSpace().
5235     EXPECT_EQ(NewI->getAddressSpace(), AddrSpace);
5236     // Check instr position.
5237     EXPECT_EQ(NewI->getNextNode(), Ret);
5238   }
5239   {
5240     // Check create() InsertBefore.
5241     auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create(
5242         Ty, AddrSpace, /*InsertBefore=*/Ret, Ctx, ArraySize, "NewAlloca2"));
5243     // Check getOpcode().
5244     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca);
5245     // Check getType().
5246     EXPECT_EQ(NewI->getType(), PtrTy);
5247     // Check getArraySize().
5248     EXPECT_EQ(NewI->getArraySize(), ArraySize);
5249     // Check getAddrSpace().
5250     EXPECT_EQ(NewI->getAddressSpace(), AddrSpace);
5251     // Check instr position.
5252     EXPECT_EQ(NewI->getNextNode(), Ret);
5253   }
5254   {
5255     // Check create() InsertAtEnd.
5256     auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create(
5257         Ty, AddrSpace, /*InsertAtEnd=*/BB, Ctx, ArraySize, "NewAlloca3"));
5258     // Check getOpcode().
5259     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca);
5260     // Check getType().
5261     EXPECT_EQ(NewI->getType(), PtrTy);
5262     // Check getArraySize().
5263     EXPECT_EQ(NewI->getArraySize(), ArraySize);
5264     // Check getAddrSpace().
5265     EXPECT_EQ(NewI->getAddressSpace(), AddrSpace);
5266     // Check instr position.
5267     EXPECT_EQ(NewI->getParent(), BB);
5268     EXPECT_EQ(NewI->getNextNode(), nullptr);
5269   }
5270 }
5271 
5272 TEST_F(SandboxIRTest, CastInst) {
5273   parseIR(C, R"IR(
5274 define void @foo(i32 %arg, float %farg, double %darg, ptr %ptr) {
5275   %zext = zext i32 %arg to i64
5276   %sext = sext i32 %arg to i64
5277   %fptoui = fptoui float %farg to i32
5278   %fptosi = fptosi float %farg to i32
5279   %fpext = fpext float %farg to double
5280   %ptrtoint = ptrtoint ptr %ptr to i32
5281   %inttoptr = inttoptr i32 %arg to ptr
5282   %sitofp = sitofp i32 %arg to float
5283   %uitofp = uitofp i32 %arg to float
5284   %trunc = trunc i32 %arg to i16
5285   %fptrunc = fptrunc double %darg to float
5286   %bitcast = bitcast i32 %arg to float
5287   %addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1)
5288   ret void
5289 }
5290 )IR");
5291   Function &LLVMF = *M->getFunction("foo");
5292   sandboxir::Context Ctx(C);
5293   sandboxir::Function *F = Ctx.createFunction(&LLVMF);
5294   unsigned ArgIdx = 0;
5295   auto *Arg = F->getArg(ArgIdx++);
5296   auto *BB = &*F->begin();
5297   auto It = BB->begin();
5298 
5299   auto *Ti64 = sandboxir::Type::getInt64Ty(Ctx);
5300   auto *Ti32 = sandboxir::Type::getInt32Ty(Ctx);
5301   auto *Ti16 = sandboxir::Type::getInt16Ty(Ctx);
5302   auto *Tdouble = sandboxir::Type::getDoubleTy(Ctx);
5303   auto *Tfloat = sandboxir::Type::getFloatTy(Ctx);
5304   auto *Tptr = sandboxir::PointerType::get(Tfloat, 0);
5305   auto *Tptr1 = sandboxir::PointerType::get(Tfloat, 1);
5306 
5307   // Check classof(), getOpcode(), getSrcTy(), getDstTy()
5308   auto *ZExt = cast<sandboxir::CastInst>(&*It++);
5309   auto *ZExtI = cast<sandboxir::ZExtInst>(ZExt);
5310   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(ZExtI));
5311   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(ZExtI));
5312   EXPECT_EQ(ZExt->getOpcode(), sandboxir::Instruction::Opcode::ZExt);
5313   EXPECT_EQ(ZExt->getSrcTy(), Ti32);
5314   EXPECT_EQ(ZExt->getDestTy(), Ti64);
5315 
5316   auto *SExt = cast<sandboxir::CastInst>(&*It++);
5317   auto *SExtI = cast<sandboxir::SExtInst>(SExt);
5318   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SExt));
5319   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SExtI));
5320   EXPECT_EQ(SExt->getOpcode(), sandboxir::Instruction::Opcode::SExt);
5321   EXPECT_EQ(SExt->getSrcTy(), Ti32);
5322   EXPECT_EQ(SExt->getDestTy(), Ti64);
5323 
5324   auto *FPToUI = cast<sandboxir::CastInst>(&*It++);
5325   auto *FPToUII = cast<sandboxir::FPToUIInst>(FPToUI);
5326   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToUI));
5327   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToUII));
5328   EXPECT_EQ(FPToUI->getOpcode(), sandboxir::Instruction::Opcode::FPToUI);
5329   EXPECT_EQ(FPToUI->getSrcTy(), Tfloat);
5330   EXPECT_EQ(FPToUI->getDestTy(), Ti32);
5331 
5332   auto *FPToSI = cast<sandboxir::CastInst>(&*It++);
5333   auto *FPToSII = cast<sandboxir::FPToSIInst>(FPToSI);
5334   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToSI));
5335   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToSII));
5336   EXPECT_EQ(FPToSI->getOpcode(), sandboxir::Instruction::Opcode::FPToSI);
5337   EXPECT_EQ(FPToSI->getSrcTy(), Tfloat);
5338   EXPECT_EQ(FPToSI->getDestTy(), Ti32);
5339 
5340   auto *FPExt = cast<sandboxir::CastInst>(&*It++);
5341   auto *FPExtI = cast<sandboxir::FPExtInst>(FPExt);
5342   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPExt));
5343   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPExtI));
5344   EXPECT_EQ(FPExt->getOpcode(), sandboxir::Instruction::Opcode::FPExt);
5345   EXPECT_EQ(FPExt->getSrcTy(), Tfloat);
5346   EXPECT_EQ(FPExt->getDestTy(), Tdouble);
5347 
5348   auto *PtrToInt = cast<sandboxir::CastInst>(&*It++);
5349   auto *PtrToIntI = cast<sandboxir::PtrToIntInst>(PtrToInt);
5350   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(PtrToInt));
5351   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(PtrToIntI));
5352   EXPECT_EQ(PtrToInt->getOpcode(), sandboxir::Instruction::Opcode::PtrToInt);
5353   EXPECT_EQ(PtrToInt->getSrcTy(), Tptr);
5354   EXPECT_EQ(PtrToInt->getDestTy(), Ti32);
5355 
5356   auto *IntToPtr = cast<sandboxir::CastInst>(&*It++);
5357   auto *IntToPtrI = cast<sandboxir::IntToPtrInst>(IntToPtr);
5358   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(IntToPtr));
5359   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(IntToPtrI));
5360   EXPECT_EQ(IntToPtr->getOpcode(), sandboxir::Instruction::Opcode::IntToPtr);
5361   EXPECT_EQ(IntToPtr->getSrcTy(), Ti32);
5362   EXPECT_EQ(IntToPtr->getDestTy(), Tptr);
5363 
5364   auto *SIToFP = cast<sandboxir::CastInst>(&*It++);
5365   auto *SIToFPI = cast<sandboxir::SIToFPInst>(SIToFP);
5366   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SIToFP));
5367   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SIToFPI));
5368   EXPECT_EQ(SIToFP->getOpcode(), sandboxir::Instruction::Opcode::SIToFP);
5369   EXPECT_EQ(SIToFP->getSrcTy(), Ti32);
5370   EXPECT_EQ(SIToFP->getDestTy(), Tfloat);
5371 
5372   auto *UIToFP = cast<sandboxir::CastInst>(&*It++);
5373   auto *UIToFPI = cast<sandboxir::UIToFPInst>(UIToFP);
5374   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(UIToFP));
5375   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(UIToFPI));
5376   EXPECT_EQ(UIToFP->getOpcode(), sandboxir::Instruction::Opcode::UIToFP);
5377   EXPECT_EQ(UIToFP->getSrcTy(), Ti32);
5378   EXPECT_EQ(UIToFP->getDestTy(), Tfloat);
5379 
5380   auto *Trunc = cast<sandboxir::CastInst>(&*It++);
5381   auto *TruncI = cast<sandboxir::TruncInst>(Trunc);
5382   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Trunc));
5383   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(TruncI));
5384   EXPECT_EQ(Trunc->getOpcode(), sandboxir::Instruction::Opcode::Trunc);
5385   EXPECT_EQ(Trunc->getSrcTy(), Ti32);
5386   EXPECT_EQ(Trunc->getDestTy(), Ti16);
5387 
5388   auto *FPTrunc = cast<sandboxir::CastInst>(&*It++);
5389   auto *FPTruncI = cast<sandboxir::FPTruncInst>(FPTrunc);
5390   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPTrunc));
5391   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPTruncI));
5392   EXPECT_EQ(FPTrunc->getOpcode(), sandboxir::Instruction::Opcode::FPTrunc);
5393   EXPECT_EQ(FPTrunc->getSrcTy(), Tdouble);
5394   EXPECT_EQ(FPTrunc->getDestTy(), Tfloat);
5395 
5396   auto *BitCast = cast<sandboxir::CastInst>(&*It++);
5397   auto *BitCastI = cast<sandboxir::BitCastInst>(BitCast);
5398   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(BitCast));
5399   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(BitCastI));
5400   EXPECT_EQ(BitCast->getOpcode(), sandboxir::Instruction::Opcode::BitCast);
5401   EXPECT_EQ(BitCast->getSrcTy(), Ti32);
5402   EXPECT_EQ(BitCast->getDestTy(), Tfloat);
5403 
5404   auto *AddrSpaceCast = cast<sandboxir::CastInst>(&*It++);
5405   auto *AddrSpaceCastI = cast<sandboxir::AddrSpaceCastInst>(AddrSpaceCast);
5406   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(AddrSpaceCast));
5407   EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(AddrSpaceCastI));
5408   EXPECT_EQ(AddrSpaceCast->getOpcode(),
5409             sandboxir::Instruction::Opcode::AddrSpaceCast);
5410   EXPECT_EQ(AddrSpaceCast->getSrcTy(), Tptr);
5411   EXPECT_EQ(AddrSpaceCast->getDestTy(), Tptr1);
5412 
5413   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
5414 
5415   {
5416     // Check create() WhereIt, WhereBB
5417     auto *NewI = cast<sandboxir::CastInst>(sandboxir::CastInst::create(
5418         Ti64, sandboxir::Instruction::Opcode::SExt, Arg, /*WhereIt=*/BB->end(),
5419         /*WhereBB=*/BB, Ctx, "SExt"));
5420     // Check getOpcode().
5421     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::SExt);
5422     // Check getSrcTy().
5423     EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
5424     // Check getDestTy().
5425     EXPECT_EQ(NewI->getDestTy(), Ti64);
5426     // Check instr position.
5427     EXPECT_EQ(NewI->getNextNode(), nullptr);
5428     EXPECT_EQ(NewI->getPrevNode(), Ret);
5429   }
5430 
5431   {
5432     // Check create() InsertBefore.
5433     auto *NewI = cast<sandboxir::CastInst>(
5434         sandboxir::CastInst::create(Ti64, sandboxir::Instruction::Opcode::ZExt,
5435                                     Arg, /*InsertBefore=*/Ret, Ctx, "ZExt"));
5436     // Check getOpcode().
5437     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::ZExt);
5438     // Check getSrcTy().
5439     EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
5440     // Check getDestTy().
5441     EXPECT_EQ(NewI->getDestTy(), Ti64);
5442     // Check instr position.
5443     EXPECT_EQ(NewI->getNextNode(), Ret);
5444   }
5445   {
5446     // Check create() InsertAtEnd.
5447     auto *NewI = cast<sandboxir::CastInst>(
5448         sandboxir::CastInst::create(Ti64, sandboxir::Instruction::Opcode::ZExt,
5449                                     Arg, /*InsertAtEnd=*/BB, Ctx, "ZExt"));
5450     // Check getOpcode().
5451     EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::ZExt);
5452     // Check getSrcTy().
5453     EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
5454     // Check getDestTy().
5455     EXPECT_EQ(NewI->getDestTy(), Ti64);
5456     // Check instr position.
5457     EXPECT_EQ(NewI->getNextNode(), nullptr);
5458     EXPECT_EQ(NewI->getParent(), BB);
5459   }
5460 
5461   {
5462 #ifndef NDEBUG
5463     // Check that passing a non-cast opcode crashes.
5464     EXPECT_DEATH(
5465         sandboxir::CastInst::create(Ti64, sandboxir::Instruction::Opcode::Store,
5466                                     Arg, /*InsertBefore=*/Ret, Ctx, "Bad"),
5467         ".*Opcode.*");
5468 #endif // NDEBUG
5469   }
5470 }
5471 
5472 TEST_F(SandboxIRTest, PossiblyNonNegInst) {
5473   parseIR(C, R"IR(
5474 define void @foo(i32 %arg, float %farg, double %darg, ptr %ptr) {
5475   %zext = zext i32 %arg to i64
5476   %uitofp = uitofp i32 %arg to float
5477 
5478   %sext = sext i32 %arg to i64
5479   %fptoui = fptoui float %farg to i32
5480   %fptosi = fptosi float %farg to i32
5481   %fpext = fpext float %farg to double
5482   %ptrtoint = ptrtoint ptr %ptr to i32
5483   %inttoptr = inttoptr i32 %arg to ptr
5484   %sitofp = sitofp i32 %arg to float
5485   %trunc = trunc i32 %arg to i16
5486   %fptrunc = fptrunc double %darg to float
5487   %bitcast = bitcast i32 %arg to float
5488   %addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1)
5489   ret void
5490 }
5491 )IR");
5492   Function &LLVMF = *M->getFunction("foo");
5493   sandboxir::Context Ctx(C);
5494   sandboxir::Function *F = Ctx.createFunction(&LLVMF);
5495   auto *BB = &*F->begin();
5496   auto It = BB->begin();
5497   auto *PNNI0 = cast<sandboxir::PossiblyNonNegInst>(&*It++);
5498   auto *PNNI1 = cast<sandboxir::PossiblyNonNegInst>(&*It++);
5499   for (auto ItE = BB->end(); It != ItE; ++It)
5500     EXPECT_FALSE(isa<sandboxir::PossiblyNonNegInst>(&*It++));
5501 
5502   for (auto *PNNI : {PNNI0, PNNI1}) {
5503     // Check setNonNeg(), hasNonNeg().
5504     auto OrigNonNeg = PNNI->hasNonNeg();
5505     auto NewNonNeg = true;
5506     EXPECT_NE(NewNonNeg, OrigNonNeg);
5507     PNNI->setNonNeg(NewNonNeg);
5508     EXPECT_EQ(PNNI->hasNonNeg(), NewNonNeg);
5509     PNNI->setNonNeg(OrigNonNeg);
5510     EXPECT_EQ(PNNI->hasNonNeg(), OrigNonNeg);
5511   }
5512 }
5513 
5514 /// CastInst's subclasses are very similar so we can use a common test function
5515 /// for them.
5516 template <typename SubclassT, sandboxir::Instruction::Opcode OpcodeT>
5517 void testCastInst(llvm::Module &M, llvm::Type *LLVMSrcTy,
5518                   llvm::Type *LLVMDstTy) {
5519   Function &LLVMF = *M.getFunction("foo");
5520   sandboxir::Context Ctx(M.getContext());
5521   sandboxir::Function *F = Ctx.createFunction(&LLVMF);
5522   sandboxir::Type *SrcTy = Ctx.getType(LLVMSrcTy);
5523   sandboxir::Type *DstTy = Ctx.getType(LLVMDstTy);
5524   unsigned ArgIdx = 0;
5525   auto *Arg = F->getArg(ArgIdx++);
5526   auto *BB = &*F->begin();
5527   auto It = BB->begin();
5528 
5529   auto *CI = cast<SubclassT>(&*It++);
5530   EXPECT_EQ(CI->getOpcode(), OpcodeT);
5531   EXPECT_EQ(CI->getSrcTy(), SrcTy);
5532   EXPECT_EQ(CI->getDestTy(), DstTy);
5533   auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
5534 
5535   {
5536     // Check create() WhereIt, WhereBB
5537     auto *NewI =
5538         cast<SubclassT>(SubclassT::create(Arg, DstTy, /*WhereIt=*/BB->end(),
5539                                           /*WhereBB=*/BB, Ctx, "NewCI"));
5540     // Check getOpcode().
5541     EXPECT_EQ(NewI->getOpcode(), OpcodeT);
5542     // Check getSrcTy().
5543     EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
5544     // Check getDestTy().
5545     EXPECT_EQ(NewI->getDestTy(), DstTy);
5546     // Check instr position.
5547     EXPECT_EQ(NewI->getNextNode(), nullptr);
5548     EXPECT_EQ(NewI->getPrevNode(), Ret);
5549     // Check instr name.
5550     EXPECT_EQ(NewI->getName(), "NewCI");
5551   }
5552   {
5553     // Check create() InsertBefore.
5554     auto *NewI =
5555         cast<SubclassT>(SubclassT::create(Arg, DstTy,
5556                                           /*InsertBefore=*/Ret, Ctx, "NewCI"));
5557     // Check getOpcode().
5558     EXPECT_EQ(NewI->getOpcode(), OpcodeT);
5559     // Check getSrcTy().
5560     EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
5561     // Check getDestTy().
5562     EXPECT_EQ(NewI->getDestTy(), DstTy);
5563     // Check instr position.
5564     EXPECT_EQ(NewI->getNextNode(), Ret);
5565   }
5566   {
5567     // Check create() InsertAtEnd.
5568     auto *NewI =
5569         cast<SubclassT>(SubclassT::create(Arg, DstTy,
5570                                           /*InsertAtEnd=*/BB, Ctx, "NewCI"));
5571     // Check getOpcode().
5572     EXPECT_EQ(NewI->getOpcode(), OpcodeT);
5573     // Check getSrcTy().
5574     EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
5575     // Check getDestTy().
5576     EXPECT_EQ(NewI->getDestTy(), DstTy);
5577     // Check instr position.
5578     EXPECT_EQ(NewI->getNextNode(), nullptr);
5579     EXPECT_EQ(NewI->getParent(), BB);
5580   }
5581 }
5582 
5583 TEST_F(SandboxIRTest, TruncInst) {
5584   parseIR(C, R"IR(
5585 define void @foo(i64 %arg) {
5586   %trunc = trunc i64 %arg to i32
5587   ret void
5588 }
5589 )IR");
5590   testCastInst<sandboxir::TruncInst, sandboxir::Instruction::Opcode::Trunc>(
5591       *M,
5592       /*SrcTy=*/Type::getInt64Ty(C), /*DstTy=*/Type::getInt32Ty(C));
5593 }
5594 
5595 TEST_F(SandboxIRTest, ZExtInst) {
5596   parseIR(C, R"IR(
5597 define void @foo(i32 %arg) {
5598   %zext = zext i32 %arg to i64
5599   ret void
5600 }
5601 )IR");
5602   testCastInst<sandboxir::ZExtInst, sandboxir::Instruction::Opcode::ZExt>(
5603       *M,
5604       /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getInt64Ty(C));
5605 }
5606 
5607 TEST_F(SandboxIRTest, SExtInst) {
5608   parseIR(C, R"IR(
5609 define void @foo(i32 %arg) {
5610   %sext = sext i32 %arg to i64
5611   ret void
5612 }
5613 )IR");
5614   testCastInst<sandboxir::SExtInst, sandboxir::Instruction::Opcode::SExt>(
5615       *M,
5616       /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getInt64Ty(C));
5617 }
5618 
5619 TEST_F(SandboxIRTest, FPTruncInst) {
5620   parseIR(C, R"IR(
5621 define void @foo(double %arg) {
5622   %fptrunc = fptrunc double %arg to float
5623   ret void
5624 }
5625 )IR");
5626   testCastInst<sandboxir::FPTruncInst, sandboxir::Instruction::Opcode::FPTrunc>(
5627       *M,
5628       /*SrcTy=*/Type::getDoubleTy(C), /*DstTy=*/Type::getFloatTy(C));
5629 }
5630 
5631 TEST_F(SandboxIRTest, FPExtInst) {
5632   parseIR(C, R"IR(
5633 define void @foo(float %arg) {
5634   %fpext = fpext float %arg to double
5635   ret void
5636 }
5637 )IR");
5638   testCastInst<sandboxir::FPExtInst, sandboxir::Instruction::Opcode::FPExt>(
5639       *M,
5640       /*SrcTy=*/Type::getFloatTy(C), /*DstTy=*/Type::getDoubleTy(C));
5641 }
5642 
5643 TEST_F(SandboxIRTest, UIToFPInst) {
5644   parseIR(C, R"IR(
5645 define void @foo(i32 %arg) {
5646   %uitofp = uitofp i32 %arg to float
5647   ret void
5648 }
5649 )IR");
5650   testCastInst<sandboxir::UIToFPInst, sandboxir::Instruction::Opcode::UIToFP>(
5651       *M,
5652       /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getFloatTy(C));
5653 }
5654 
5655 TEST_F(SandboxIRTest, SIToFPInst) {
5656   parseIR(C, R"IR(
5657 define void @foo(i32 %arg) {
5658   %sitofp = sitofp i32 %arg to float
5659   ret void
5660 }
5661 )IR");
5662   testCastInst<sandboxir::SIToFPInst, sandboxir::Instruction::Opcode::SIToFP>(
5663       *M,
5664       /*SrcTy=*/Type::getInt32Ty(C),
5665       /*DstTy=*/Type::getFloatTy(C));
5666 }
5667 
5668 TEST_F(SandboxIRTest, FPToUIInst) {
5669   parseIR(C, R"IR(
5670 define void @foo(float %arg) {
5671   %fptoui = fptoui float %arg to i32
5672   ret void
5673 }
5674 )IR");
5675   testCastInst<sandboxir::FPToUIInst, sandboxir::Instruction::Opcode::FPToUI>(
5676 
5677       *M, /*SrcTy=*/Type::getFloatTy(C), /*DstTy=*/Type::getInt32Ty(C));
5678 }
5679 
5680 TEST_F(SandboxIRTest, FPToSIInst) {
5681   parseIR(C, R"IR(
5682 define void @foo(float %arg) {
5683   %fptosi = fptosi float %arg to i32
5684   ret void
5685 }
5686 )IR");
5687   testCastInst<sandboxir::FPToSIInst, sandboxir::Instruction::Opcode::FPToSI>(
5688       *M, /*SrcTy=*/Type::getFloatTy(C), /*DstTy=*/Type::getInt32Ty(C));
5689 }
5690 
5691 TEST_F(SandboxIRTest, IntToPtrInst) {
5692   parseIR(C, R"IR(
5693 define void @foo(i32 %arg) {
5694   %inttoptr = inttoptr i32 %arg to ptr
5695   ret void
5696 }
5697 )IR");
5698   testCastInst<sandboxir::IntToPtrInst,
5699                sandboxir::Instruction::Opcode::IntToPtr>(
5700       *M,
5701       /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/PointerType::get(C, 0));
5702 }
5703 
5704 TEST_F(SandboxIRTest, PtrToIntInst) {
5705   parseIR(C, R"IR(
5706 define void @foo(ptr %ptr) {
5707   %ptrtoint = ptrtoint ptr %ptr to i32
5708   ret void
5709 }
5710 )IR");
5711   testCastInst<sandboxir::PtrToIntInst,
5712                sandboxir::Instruction::Opcode::PtrToInt>(
5713       *M, /*SrcTy=*/PointerType::get(C, 0), /*DstTy=*/Type::getInt32Ty(C));
5714 }
5715 
5716 TEST_F(SandboxIRTest, BitCastInst) {
5717   parseIR(C, R"IR(
5718 define void @foo(i32 %arg) {
5719   %bitcast = bitcast i32 %arg to float
5720   ret void
5721 }
5722 )IR");
5723   testCastInst<sandboxir::BitCastInst, sandboxir::Instruction::Opcode::BitCast>(
5724       *M,
5725       /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getFloatTy(C));
5726 }
5727 
5728 TEST_F(SandboxIRTest, AddrSpaceCastInst) {
5729   parseIR(C, R"IR(
5730 define void @foo(ptr %ptr) {
5731   %addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1)
5732   ret void
5733 }
5734 )IR");
5735   Type *Tptr0 = PointerType::get(C, 0);
5736   Type *Tptr1 = PointerType::get(C, 1);
5737   testCastInst<sandboxir::AddrSpaceCastInst,
5738                sandboxir::Instruction::Opcode::AddrSpaceCast>(*M,
5739                                                               /*SrcTy=*/Tptr0,
5740                                                               /*DstTy=*/Tptr1);
5741   Function &LLVMF = *M->getFunction("foo");
5742   sandboxir::Context Ctx(C);
5743   sandboxir::Function *F = Ctx.createFunction(&LLVMF);
5744   unsigned ArgIdx = 0;
5745   auto *Arg = F->getArg(ArgIdx++);
5746   auto *BB = &*F->begin();
5747   auto It = BB->begin();
5748 
5749   auto *AddrSpaceCast = cast<sandboxir::AddrSpaceCastInst>(&*It++);
5750   EXPECT_EQ(AddrSpaceCast->getOpcode(),
5751             sandboxir::Instruction::Opcode::AddrSpaceCast);
5752   EXPECT_EQ(AddrSpaceCast->getPointerOperand(), Arg);
5753   EXPECT_EQ(sandboxir::AddrSpaceCastInst::getPointerOperandIndex(), 0u);
5754   EXPECT_EQ(AddrSpaceCast->getSrcAddressSpace(),
5755             cast<PointerType>(Tptr0)->getPointerAddressSpace());
5756   EXPECT_EQ(AddrSpaceCast->getDestAddressSpace(),
5757             cast<PointerType>(Tptr1)->getPointerAddressSpace());
5758 }
5759 
5760 TEST_F(SandboxIRTest, PHINode) {
5761   parseIR(C, R"IR(
5762 define void @foo(i32 %arg) {
5763 bb1:
5764   br label %bb2
5765 
5766 bb2:
5767   %phi = phi i32 [ %arg, %bb1 ], [ 0, %bb2 ], [ 1, %bb3 ], [ 2, %bb4 ], [ 3, %bb5 ]
5768   br label %bb2
5769 
5770 bb3:
5771   br label %bb2
5772 
5773 bb4:
5774   br label %bb2
5775 
5776 bb5:
5777   br label %bb2
5778   ret void
5779 }
5780 )IR");
5781   Function &LLVMF = *M->getFunction("foo");
5782   auto *LLVMBB1 = getBasicBlockByName(LLVMF, "bb1");
5783   auto *LLVMBB2 = getBasicBlockByName(LLVMF, "bb2");
5784   auto *LLVMBB3 = getBasicBlockByName(LLVMF, "bb3");
5785   auto LLVMIt = LLVMBB2->begin();
5786   auto *LLVMPHI = cast<llvm::PHINode>(&*LLVMIt++);
5787   sandboxir::Context Ctx(C);
5788   sandboxir::Function *F = Ctx.createFunction(&LLVMF);
5789   auto *Arg = F->getArg(0);
5790   auto *BB1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB1));
5791   auto *BB2 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB2));
5792   auto *BB3 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB3));
5793   auto It = BB2->begin();
5794   // Check classof().
5795   auto *PHI = cast<sandboxir::PHINode>(&*It++);
5796   auto *Br = cast<sandboxir::BranchInst>(&*It++);
5797   // Check blocks().
5798   EXPECT_EQ(range_size(PHI->blocks()), range_size(LLVMPHI->blocks()));
5799   auto BlockIt = PHI->block_begin();
5800   for (llvm::BasicBlock *LLVMBB : LLVMPHI->blocks()) {
5801     sandboxir::BasicBlock *BB = *BlockIt++;
5802     EXPECT_EQ(BB, Ctx.getValue(LLVMBB));
5803   }
5804   // Check incoming_values().
5805   EXPECT_EQ(range_size(PHI->incoming_values()),
5806             range_size(LLVMPHI->incoming_values()));
5807   auto IncIt = PHI->incoming_values().begin();
5808   for (llvm::Value *LLVMV : LLVMPHI->incoming_values()) {
5809     sandboxir::Value *IncV = *IncIt++;
5810     EXPECT_EQ(IncV, Ctx.getValue(LLVMV));
5811   }
5812   // Check getNumIncomingValues().
5813   EXPECT_EQ(PHI->getNumIncomingValues(), LLVMPHI->getNumIncomingValues());
5814   // Check getIncomingValue().
5815   EXPECT_EQ(PHI->getIncomingValue(0),
5816             Ctx.getValue(LLVMPHI->getIncomingValue(0)));
5817   EXPECT_EQ(PHI->getIncomingValue(1),
5818             Ctx.getValue(LLVMPHI->getIncomingValue(1)));
5819   // Check setIncomingValue().
5820   auto *OrigV = PHI->getIncomingValue(0);
5821   PHI->setIncomingValue(0, PHI);
5822   EXPECT_EQ(PHI->getIncomingValue(0), PHI);
5823   PHI->setIncomingValue(0, OrigV);
5824   // Check getOperandNumForIncomingValue().
5825   EXPECT_EQ(sandboxir::PHINode::getOperandNumForIncomingValue(0),
5826             llvm::PHINode::getOperandNumForIncomingValue(0));
5827   // Check getIncomingValueNumForOperand().
5828   EXPECT_EQ(sandboxir::PHINode::getIncomingValueNumForOperand(0),
5829             llvm::PHINode::getIncomingValueNumForOperand(0));
5830   // Check getIncomingBlock(unsigned).
5831   EXPECT_EQ(PHI->getIncomingBlock(0),
5832             Ctx.getValue(LLVMPHI->getIncomingBlock(0)));
5833   // Check getIncomingBlock(Use).
5834   llvm::Use &LLVMUse = LLVMPHI->getOperandUse(0);
5835   sandboxir::Use Use = PHI->getOperandUse(0);
5836   EXPECT_EQ(PHI->getIncomingBlock(Use),
5837             Ctx.getValue(LLVMPHI->getIncomingBlock(LLVMUse)));
5838   // Check setIncomingBlock().
5839   sandboxir::BasicBlock *OrigBB = PHI->getIncomingBlock(0);
5840   EXPECT_NE(OrigBB, BB2);
5841   PHI->setIncomingBlock(0, BB2);
5842   EXPECT_EQ(PHI->getIncomingBlock(0), BB2);
5843   PHI->setIncomingBlock(0, OrigBB);
5844   EXPECT_EQ(PHI->getIncomingBlock(0), OrigBB);
5845   // Check addIncoming().
5846   unsigned OrigNumIncoming = PHI->getNumIncomingValues();
5847   PHI->addIncoming(Arg, BB3);
5848   EXPECT_EQ(PHI->getNumIncomingValues(), LLVMPHI->getNumIncomingValues());
5849   EXPECT_EQ(PHI->getNumIncomingValues(), OrigNumIncoming + 1);
5850   EXPECT_EQ(PHI->getIncomingValue(OrigNumIncoming), Arg);
5851   EXPECT_EQ(PHI->getIncomingBlock(OrigNumIncoming), BB3);
5852   // Check removeIncomingValue(unsigned).
5853   PHI->removeIncomingValue(OrigNumIncoming);
5854   EXPECT_EQ(PHI->getNumIncomingValues(), OrigNumIncoming);
5855   // Check removeIncomingValue(BasicBlock *).
5856   PHI->addIncoming(Arg, BB3);
5857   PHI->removeIncomingValue(BB3);
5858   EXPECT_EQ(PHI->getNumIncomingValues(), OrigNumIncoming);
5859   // Check getBasicBlockIndex().
5860   EXPECT_EQ(PHI->getBasicBlockIndex(BB1), LLVMPHI->getBasicBlockIndex(LLVMBB1));
5861   // Check getIncomingValueForBlock().
5862   EXPECT_EQ(PHI->getIncomingValueForBlock(BB1),
5863             Ctx.getValue(LLVMPHI->getIncomingValueForBlock(LLVMBB1)));
5864   // Check hasConstantValue().
5865   llvm::Value *ConstV = LLVMPHI->hasConstantValue();
5866   EXPECT_EQ(PHI->hasConstantValue(),
5867             ConstV != nullptr ? Ctx.getValue(ConstV) : nullptr);
5868   // Check hasConstantOrUndefValue().
5869   EXPECT_EQ(PHI->hasConstantOrUndefValue(), LLVMPHI->hasConstantOrUndefValue());
5870   // Check isComplete().
5871   EXPECT_EQ(PHI->isComplete(), LLVMPHI->isComplete());
5872   // Check replaceIncomingValueIf
5873   EXPECT_EQ(PHI->getNumIncomingValues(), 5u);
5874   auto *RemainBB0 = PHI->getIncomingBlock(0);
5875   auto *RemoveBB0 = PHI->getIncomingBlock(1);
5876   auto *RemainBB1 = PHI->getIncomingBlock(2);
5877   auto *RemoveBB1 = PHI->getIncomingBlock(3);
5878   auto *RemainBB2 = PHI->getIncomingBlock(4);
5879   PHI->removeIncomingValueIf([&](unsigned Idx) {
5880     return PHI->getIncomingBlock(Idx) == RemoveBB0 ||
5881            PHI->getIncomingBlock(Idx) == RemoveBB1;
5882   });
5883   EXPECT_EQ(PHI->getNumIncomingValues(), 3u);
5884   EXPECT_EQ(PHI->getIncomingBlock(0), RemainBB0);
5885   EXPECT_EQ(PHI->getIncomingBlock(1), RemainBB1);
5886   EXPECT_EQ(PHI->getIncomingBlock(2), RemainBB2);
5887   // Check replaceIncomingBlockWith
5888   OrigBB = RemainBB0;
5889   auto *NewBB = RemainBB1;
5890   EXPECT_NE(NewBB, OrigBB);
5891   PHI->replaceIncomingBlockWith(OrigBB, NewBB);
5892   EXPECT_EQ(PHI->getIncomingBlock(0), NewBB);
5893   EXPECT_EQ(PHI->getIncomingBlock(1), RemainBB1);
5894   EXPECT_EQ(PHI->getIncomingBlock(2), RemainBB2);
5895   // Check create().
5896   auto *NewPHI = cast<sandboxir::PHINode>(
5897       sandboxir::PHINode::create(PHI->getType(), 0, Br, Ctx, "NewPHI"));
5898   EXPECT_EQ(NewPHI->getType(), PHI->getType());
5899   EXPECT_EQ(NewPHI->getNextNode(), Br);
5900   EXPECT_EQ(NewPHI->getName(), "NewPHI");
5901   EXPECT_EQ(NewPHI->getNumIncomingValues(), 0u);
5902   for (auto [Idx, V] : enumerate(PHI->incoming_values())) {
5903     sandboxir::BasicBlock *IncBB = PHI->getIncomingBlock(Idx);
5904     NewPHI->addIncoming(V, IncBB);
5905   }
5906   EXPECT_EQ(NewPHI->getNumIncomingValues(), PHI->getNumIncomingValues());
5907 }
5908 
5909 static void checkSwapOperands(sandboxir::Context &Ctx,
5910                               llvm::sandboxir::CmpInst *Cmp,
5911                               llvm::CmpInst *LLVMCmp) {
5912   auto OrigOp0 = Cmp->getOperand(0);
5913   auto OrigOp1 = Cmp->getOperand(1);
5914   EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(0)), OrigOp0);
5915   EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(1)), OrigOp1);
5916   // This checks the dispatch mechanism in CmpInst, as well as
5917   // the specific implementations.
5918   Cmp->swapOperands();
5919   EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(1)), OrigOp0);
5920   EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(0)), OrigOp1);
5921   EXPECT_EQ(Cmp->getOperand(0), OrigOp1);
5922   EXPECT_EQ(Cmp->getOperand(1), OrigOp0);
5923   // Undo it to keep the rest of the test consistent
5924   Cmp->swapOperands();
5925 }
5926 
5927 static void checkCommonPredicates(sandboxir::CmpInst *Cmp,
5928                                   llvm::CmpInst *LLVMCmp) {
5929   // Check proper creation
5930   auto Pred = Cmp->getPredicate();
5931   auto LLVMPred = LLVMCmp->getPredicate();
5932   EXPECT_EQ(Pred, LLVMPred);
5933   // Check setPredicate
5934   Cmp->setPredicate(llvm::CmpInst::FCMP_FALSE);
5935   EXPECT_EQ(Cmp->getPredicate(), llvm::CmpInst::FCMP_FALSE);
5936   EXPECT_EQ(LLVMCmp->getPredicate(), llvm::CmpInst::FCMP_FALSE);
5937   Cmp->setPredicate(Pred);
5938   EXPECT_EQ(LLVMCmp->getPredicate(), Pred);
5939   // Ensure the accessors properly forward to the underlying implementation
5940   EXPECT_STREQ(sandboxir::CmpInst::getPredicateName(Pred).data(),
5941                llvm::CmpInst::getPredicateName(LLVMPred).data());
5942   EXPECT_EQ(Cmp->isFPPredicate(), LLVMCmp->isFPPredicate());
5943   EXPECT_EQ(Cmp->isIntPredicate(), LLVMCmp->isIntPredicate());
5944   EXPECT_EQ(Cmp->getInversePredicate(), LLVMCmp->getInversePredicate());
5945   EXPECT_EQ(Cmp->getOrderedPredicate(), LLVMCmp->getOrderedPredicate());
5946   EXPECT_EQ(Cmp->getUnorderedPredicate(), LLVMCmp->getUnorderedPredicate());
5947   EXPECT_EQ(Cmp->getSwappedPredicate(), LLVMCmp->getSwappedPredicate());
5948   EXPECT_EQ(Cmp->isStrictPredicate(), LLVMCmp->isStrictPredicate());
5949   EXPECT_EQ(Cmp->isNonStrictPredicate(), LLVMCmp->isNonStrictPredicate());
5950   EXPECT_EQ(Cmp->isRelational(), LLVMCmp->isRelational());
5951   if (Cmp->isRelational()) {
5952     EXPECT_EQ(Cmp->getFlippedStrictnessPredicate(),
5953               LLVMCmp->getFlippedStrictnessPredicate());
5954   }
5955   EXPECT_EQ(Cmp->isCommutative(), LLVMCmp->isCommutative());
5956   EXPECT_EQ(Cmp->isTrueWhenEqual(), LLVMCmp->isTrueWhenEqual());
5957   EXPECT_EQ(Cmp->isFalseWhenEqual(), LLVMCmp->isFalseWhenEqual());
5958   EXPECT_EQ(sandboxir::CmpInst::isOrdered(Pred),
5959             llvm::CmpInst::isOrdered(LLVMPred));
5960   EXPECT_EQ(sandboxir::CmpInst::isUnordered(Pred),
5961             llvm::CmpInst::isUnordered(LLVMPred));
5962 }
5963 
5964 TEST_F(SandboxIRTest, ICmpInst) {
5965   SCOPED_TRACE("SandboxIRTest sandboxir::ICmpInst tests");
5966   parseIR(C, R"IR(
5967 define void @foo(i32 %i0, i32 %i1) {
5968  bb:
5969   %ine  = icmp ne i32 %i0, %i1
5970   %iugt = icmp ugt i32 %i0, %i1
5971   %iuge = icmp uge i32 %i0, %i1
5972   %iult = icmp ult i32 %i0, %i1
5973   %iule = icmp ule i32 %i0, %i1
5974   %isgt = icmp sgt i32 %i0, %i1
5975   %isle = icmp sle i32 %i0, %i1
5976   %ieg  = icmp eq i32 %i0, %i1
5977   ret void
5978 }
5979 )IR");
5980   Function &LLVMF = *M->getFunction("foo");
5981   sandboxir::Context Ctx(C);
5982   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
5983 
5984   auto *LLVMBB = getBasicBlockByName(LLVMF, "bb");
5985   auto LLVMIt = LLVMBB->begin();
5986   auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB));
5987   auto It = BB->begin();
5988   // Check classof()
5989   while (auto *ICmp = dyn_cast<sandboxir::ICmpInst>(&*It++)) {
5990     auto *LLVMICmp = cast<llvm::ICmpInst>(&*LLVMIt++);
5991     checkSwapOperands(Ctx, ICmp, LLVMICmp);
5992     checkCommonPredicates(ICmp, LLVMICmp);
5993     EXPECT_EQ(ICmp->isSigned(), LLVMICmp->isSigned());
5994     EXPECT_EQ(ICmp->isUnsigned(), LLVMICmp->isUnsigned());
5995     EXPECT_EQ(ICmp->getSignedPredicate(), LLVMICmp->getSignedPredicate());
5996     EXPECT_EQ(ICmp->getUnsignedPredicate(), LLVMICmp->getUnsignedPredicate());
5997   }
5998   auto *NewCmp =
5999       sandboxir::CmpInst::create(llvm::CmpInst::ICMP_ULE, F.getArg(0),
6000                                  F.getArg(1), &*BB->begin(), Ctx, "NewCmp");
6001   EXPECT_EQ(NewCmp, &*BB->begin());
6002   EXPECT_EQ(NewCmp->getPredicate(), llvm::CmpInst::ICMP_ULE);
6003   EXPECT_EQ(NewCmp->getOperand(0), F.getArg(0));
6004   EXPECT_EQ(NewCmp->getOperand(1), F.getArg(1));
6005 #ifndef NDEBUG
6006   EXPECT_EQ(NewCmp->getName(), "NewCmp");
6007 #endif // NDEBUG
6008   // TODO: Improve this test when sandboxir::VectorType is more completely
6009   // implemented.
6010   sandboxir::Type *RT =
6011       sandboxir::CmpInst::makeCmpResultType(F.getArg(0)->getType());
6012   EXPECT_TRUE(RT->isIntegerTy(1)); // Only one bit in a single comparison
6013 }
6014 
6015 TEST_F(SandboxIRTest, FCmpInst) {
6016   SCOPED_TRACE("SandboxIRTest sandboxir::FCmpInst tests");
6017   parseIR(C, R"IR(
6018 define void @foo(float %f0, float %f1) {
6019 bb:
6020   %ffalse = fcmp false float %f0, %f1
6021   %foeq = fcmp oeq float %f0, %f1
6022   %fogt = fcmp ogt float %f0, %f1
6023   %folt = fcmp olt float %f0, %f1
6024   %fole = fcmp ole float %f0, %f1
6025   %fone = fcmp one float %f0, %f1
6026   %ford = fcmp ord float %f0, %f1
6027   %funo = fcmp uno float %f0, %f1
6028   %fueq = fcmp ueq float %f0, %f1
6029   %fugt = fcmp ugt float %f0, %f1
6030   %fuge = fcmp uge float %f0, %f1
6031   %fult = fcmp ult float %f0, %f1
6032   %fule = fcmp ule float %f0, %f1
6033   %fune = fcmp une float %f0, %f1
6034   %ftrue = fcmp true float %f0, %f1
6035   ret void
6036 bb1:
6037   %copyfrom = fadd reassoc float %f0, 42.0
6038   ret void
6039 }
6040 )IR");
6041   Function &LLVMF = *M->getFunction("foo");
6042   sandboxir::Context Ctx(C);
6043   [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
6044 
6045   auto *LLVMBB = getBasicBlockByName(LLVMF, "bb");
6046   auto LLVMIt = LLVMBB->begin();
6047   auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB));
6048   auto It = BB->begin();
6049   // Check classof()
6050   while (auto *FCmp = dyn_cast<sandboxir::ICmpInst>(&*It++)) {
6051     auto *LLVMFCmp = cast<llvm::ICmpInst>(&*LLVMIt++);
6052     checkSwapOperands(Ctx, FCmp, LLVMFCmp);
6053     checkCommonPredicates(FCmp, LLVMFCmp);
6054   }
6055 
6056   auto *LLVMBB1 = getBasicBlockByName(LLVMF, "bb1");
6057   auto *BB1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB1));
6058   auto It1 = BB1->begin();
6059   auto *CopyFrom = &*It1++;
6060   CopyFrom->setFastMathFlags(FastMathFlags::getFast());
6061 
6062   // create with default flags
6063   auto *NewFCmp = sandboxir::CmpInst::create(
6064       llvm::CmpInst::FCMP_ONE, F.getArg(0), F.getArg(1), &*It1, Ctx, "NewFCmp");
6065   EXPECT_EQ(NewFCmp->getPredicate(), llvm::CmpInst::FCMP_ONE);
6066   EXPECT_EQ(NewFCmp->getOperand(0), F.getArg(0));
6067   EXPECT_EQ(NewFCmp->getOperand(1), F.getArg(1));
6068 #ifndef NDEBUG
6069   EXPECT_EQ(NewFCmp->getName(), "NewFCmp");
6070 #endif // NDEBUG
6071   FastMathFlags DefaultFMF = NewFCmp->getFastMathFlags();
6072   EXPECT_TRUE(CopyFrom->getFastMathFlags() != DefaultFMF);
6073   // create with copied flags
6074   auto *NewFCmpFlags = sandboxir::CmpInst::createWithCopiedFlags(
6075       llvm::CmpInst::FCMP_ONE, F.getArg(0), F.getArg(1), CopyFrom, &*It1, Ctx,
6076       "NewFCmpFlags");
6077   EXPECT_FALSE(NewFCmpFlags->getFastMathFlags() !=
6078                CopyFrom->getFastMathFlags());
6079   EXPECT_EQ(NewFCmpFlags->getPredicate(), llvm::CmpInst::FCMP_ONE);
6080   EXPECT_EQ(NewFCmpFlags->getOperand(0), F.getArg(0));
6081   EXPECT_EQ(NewFCmpFlags->getOperand(1), F.getArg(1));
6082 #ifndef NDEBUG
6083   EXPECT_EQ(NewFCmpFlags->getName(), "NewFCmpFlags");
6084 #endif // NDEBUG
6085 }
6086 
6087 TEST_F(SandboxIRTest, UnreachableInst) {
6088   parseIR(C, R"IR(
6089 define void @foo() {
6090   unreachable
6091 }
6092 )IR");
6093   llvm::Function *LLVMF = &*M->getFunction("foo");
6094   sandboxir::Context Ctx(C);
6095   sandboxir::Function *F = Ctx.createFunction(LLVMF);
6096   auto *BB = &*F->begin();
6097   auto It = BB->begin();
6098   auto *UI = cast<sandboxir::UnreachableInst>(&*It++);
6099 
6100   EXPECT_EQ(UI->getNumSuccessors(), 0u);
6101   EXPECT_EQ(UI->getNumOfIRInstrs(), 1u);
6102   // Check create(InsertBefore)
6103   sandboxir::UnreachableInst *NewUI =
6104       sandboxir::UnreachableInst::create(/*InsertBefore=*/UI, Ctx);
6105   EXPECT_EQ(NewUI->getNextNode(), UI);
6106   // Check create(InsertAtEnd)
6107   sandboxir::UnreachableInst *NewUIEnd =
6108       sandboxir::UnreachableInst::create(/*InsertAtEnd=*/BB, Ctx);
6109   EXPECT_EQ(NewUIEnd->getParent(), BB);
6110   EXPECT_EQ(NewUIEnd->getNextNode(), nullptr);
6111 }
6112 
6113 /// Makes sure that all Instruction sub-classes have a classof().
6114 TEST_F(SandboxIRTest, CheckClassof) {
6115 #define DEF_INSTR(ID, OPC, CLASS)                                              \
6116   EXPECT_NE(&sandboxir::CLASS::classof, &sandboxir::Instruction::classof);
6117 #include "llvm/SandboxIR/SandboxIRValues.def"
6118 }
6119