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