Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / unittests / SandboxIR / SandboxIRTest.cpp
blobba90b4f811f8e1a694201dfccac89dfaaeb206a6
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/SandboxIR/SandboxIR.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/IR/BasicBlock.h"
12 #include "llvm/IR/Function.h"
13 #include "llvm/IR/Instruction.h"
14 #include "llvm/IR/Module.h"
15 #include "llvm/Support/SourceMgr.h"
16 #include "gtest/gtest.h"
18 using namespace llvm;
20 struct SandboxIRTest : public testing::Test {
21 LLVMContext C;
22 std::unique_ptr<Module> M;
24 void parseIR(LLVMContext &C, const char *IR) {
25 SMDiagnostic Err;
26 M = parseAssemblyString(IR, Err, C);
27 if (!M)
28 Err.print("SandboxIRTest", errs());
30 BasicBlock *getBasicBlockByName(Function &F, StringRef Name) {
31 for (BasicBlock &BB : F)
32 if (BB.getName() == Name)
33 return &BB;
34 llvm_unreachable("Expected to find basic block!");
38 TEST_F(SandboxIRTest, ClassID) {
39 parseIR(C, R"IR(
40 define void @foo(i32 %v1) {
41 %add = add i32 %v1, 42
42 ret void
44 )IR");
45 llvm::Function *LLVMF = &*M->getFunction("foo");
46 llvm::BasicBlock *LLVMBB = &*LLVMF->begin();
47 llvm::Instruction *LLVMAdd = &*LLVMBB->begin();
48 auto *LLVMC = cast<llvm::Constant>(LLVMAdd->getOperand(1));
50 sandboxir::Context Ctx(C);
51 sandboxir::Function *F = Ctx.createFunction(LLVMF);
52 sandboxir::Argument *Arg0 = F->getArg(0);
53 sandboxir::BasicBlock *BB = &*F->begin();
54 sandboxir::Instruction *AddI = &*BB->begin();
55 sandboxir::OpaqueInst *OpaqueI = cast<sandboxir::OpaqueInst>(AddI);
56 sandboxir::Constant *Const0 = cast<sandboxir::Constant>(Ctx.getValue(LLVMC));
58 EXPECT_TRUE(isa<sandboxir::Function>(F));
59 EXPECT_FALSE(isa<sandboxir::Function>(Arg0));
60 EXPECT_FALSE(isa<sandboxir::Function>(BB));
61 EXPECT_FALSE(isa<sandboxir::Function>(AddI));
62 EXPECT_FALSE(isa<sandboxir::Function>(Const0));
63 EXPECT_FALSE(isa<sandboxir::Function>(OpaqueI));
65 EXPECT_FALSE(isa<sandboxir::Argument>(F));
66 EXPECT_TRUE(isa<sandboxir::Argument>(Arg0));
67 EXPECT_FALSE(isa<sandboxir::Argument>(BB));
68 EXPECT_FALSE(isa<sandboxir::Argument>(AddI));
69 EXPECT_FALSE(isa<sandboxir::Argument>(Const0));
70 EXPECT_FALSE(isa<sandboxir::Argument>(OpaqueI));
72 EXPECT_TRUE(isa<sandboxir::Constant>(F));
73 EXPECT_FALSE(isa<sandboxir::Constant>(Arg0));
74 EXPECT_FALSE(isa<sandboxir::Constant>(BB));
75 EXPECT_FALSE(isa<sandboxir::Constant>(AddI));
76 EXPECT_TRUE(isa<sandboxir::Constant>(Const0));
77 EXPECT_FALSE(isa<sandboxir::Constant>(OpaqueI));
79 EXPECT_FALSE(isa<sandboxir::OpaqueInst>(F));
80 EXPECT_FALSE(isa<sandboxir::OpaqueInst>(Arg0));
81 EXPECT_FALSE(isa<sandboxir::OpaqueInst>(BB));
82 EXPECT_TRUE(isa<sandboxir::OpaqueInst>(AddI));
83 EXPECT_FALSE(isa<sandboxir::OpaqueInst>(Const0));
84 EXPECT_TRUE(isa<sandboxir::OpaqueInst>(OpaqueI));
86 EXPECT_FALSE(isa<sandboxir::Instruction>(F));
87 EXPECT_FALSE(isa<sandboxir::Instruction>(Arg0));
88 EXPECT_FALSE(isa<sandboxir::Instruction>(BB));
89 EXPECT_TRUE(isa<sandboxir::Instruction>(AddI));
90 EXPECT_FALSE(isa<sandboxir::Instruction>(Const0));
91 EXPECT_TRUE(isa<sandboxir::Instruction>(OpaqueI));
93 EXPECT_FALSE(isa<sandboxir::User>(F));
94 EXPECT_FALSE(isa<sandboxir::User>(Arg0));
95 EXPECT_FALSE(isa<sandboxir::User>(BB));
96 EXPECT_TRUE(isa<sandboxir::User>(AddI));
97 EXPECT_TRUE(isa<sandboxir::User>(Const0));
98 EXPECT_TRUE(isa<sandboxir::User>(OpaqueI));
100 #ifndef NDEBUG
101 std::string Buff;
102 raw_string_ostream BS(Buff);
103 F->dump(BS);
104 Arg0->dump(BS);
105 BB->dump(BS);
106 AddI->dump(BS);
107 Const0->dump(BS);
108 OpaqueI->dump(BS);
109 #endif
112 TEST_F(SandboxIRTest, Use) {
113 parseIR(C, R"IR(
114 define i32 @foo(i32 %v0, i32 %v1) {
115 %add0 = add i32 %v0, %v1
116 ret i32 %add0
118 )IR");
119 Function &LLVMF = *M->getFunction("foo");
120 sandboxir::Context Ctx(C);
122 BasicBlock *LLVMBB = &*LLVMF.begin();
123 auto LLVMBBIt = LLVMBB->begin();
124 Instruction *LLVMI0 = &*LLVMBBIt++;
125 Instruction *LLVMRet = &*LLVMBBIt++;
126 Argument *LLVMArg0 = LLVMF.getArg(0);
127 Argument *LLVMArg1 = LLVMF.getArg(1);
129 auto &F = *Ctx.createFunction(&LLVMF);
130 auto &BB = *F.begin();
131 auto *Arg0 = F.getArg(0);
132 auto *Arg1 = F.getArg(1);
133 auto It = BB.begin();
134 auto *I0 = &*It++;
135 auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
137 SmallVector<sandboxir::Argument *> Args{Arg0, Arg1};
138 unsigned OpIdx = 0;
139 for (sandboxir::Use Use : I0->operands()) {
140 // Check Use.getOperandNo().
141 EXPECT_EQ(Use.getOperandNo(), OpIdx);
142 // Check Use.getUser().
143 EXPECT_EQ(Use.getUser(), I0);
144 // Check Use.getContext().
145 EXPECT_EQ(Use.getContext(), &Ctx);
146 // Check Use.get().
147 sandboxir::Value *Op = Use.get();
148 EXPECT_EQ(Op, Ctx.getValue(LLVMI0->getOperand(OpIdx)));
149 // Check Use.getUser().
150 EXPECT_EQ(Use.getUser(), I0);
151 // Check implicit cast to Value.
152 sandboxir::Value *Cast = Use;
153 EXPECT_EQ(Cast, Op);
154 // Check that Use points to the correct operand.
155 EXPECT_EQ(Op, Args[OpIdx]);
156 // Check getOperand().
157 EXPECT_EQ(Op, I0->getOperand(OpIdx));
158 // Check getOperandUse().
159 EXPECT_EQ(Use, I0->getOperandUse(OpIdx));
160 ++OpIdx;
162 EXPECT_EQ(OpIdx, 2u);
164 // Check Use.operator==() and Use.operator!=().
165 sandboxir::Use UseA = I0->getOperandUse(0);
166 sandboxir::Use UseB = I0->getOperandUse(0);
167 EXPECT_TRUE(UseA == UseB);
168 EXPECT_FALSE(UseA != UseB);
170 // Check getNumOperands().
171 EXPECT_EQ(I0->getNumOperands(), 2u);
172 EXPECT_EQ(Ret->getNumOperands(), 1u);
174 EXPECT_EQ(Ret->getOperand(0), I0);
176 #ifndef NDEBUG
177 // Check Use.dump()
178 std::string Buff;
179 raw_string_ostream BS(Buff);
180 BS << "\n";
181 I0->getOperandUse(0).dump(BS);
182 EXPECT_EQ(Buff, R"IR(
183 Def: i32 %v0 ; SB1. (Argument)
184 User: %add0 = add i32 %v0, %v1 ; SB4. (Opaque)
185 OperandNo: 0
186 )IR");
187 #endif // NDEBUG
189 // Check Value.user_begin().
190 sandboxir::Value::user_iterator UIt = I0->user_begin();
191 sandboxir::User *U = *UIt;
192 EXPECT_EQ(U, Ret);
193 // Check Value.uses().
194 EXPECT_EQ(range_size(I0->uses()), 1u);
195 EXPECT_EQ((*I0->uses().begin()).getUser(), Ret);
196 // Check Value.users().
197 EXPECT_EQ(range_size(I0->users()), 1u);
198 EXPECT_EQ(*I0->users().begin(), Ret);
199 // Check Value.getNumUses().
200 EXPECT_EQ(I0->getNumUses(), 1u);
201 // Check Value.hasNUsesOrMore().
202 EXPECT_TRUE(I0->hasNUsesOrMore(0u));
203 EXPECT_TRUE(I0->hasNUsesOrMore(1u));
204 EXPECT_FALSE(I0->hasNUsesOrMore(2u));
205 // Check Value.hasNUses().
206 EXPECT_FALSE(I0->hasNUses(0u));
207 EXPECT_TRUE(I0->hasNUses(1u));
208 EXPECT_FALSE(I0->hasNUses(2u));
210 // Check User.setOperand().
211 Ret->setOperand(0, Arg0);
212 EXPECT_EQ(Ret->getOperand(0), Arg0);
213 EXPECT_EQ(Ret->getOperandUse(0).get(), Arg0);
214 EXPECT_EQ(LLVMRet->getOperand(0), LLVMArg0);
216 Ret->setOperand(0, Arg1);
217 EXPECT_EQ(Ret->getOperand(0), Arg1);
218 EXPECT_EQ(Ret->getOperandUse(0).get(), Arg1);
219 EXPECT_EQ(LLVMRet->getOperand(0), LLVMArg1);
222 TEST_F(SandboxIRTest, RUOW) {
223 parseIR(C, R"IR(
224 declare void @bar0()
225 declare void @bar1()
227 @glob0 = global ptr @bar0
228 @glob1 = global ptr @bar1
230 define i32 @foo(i32 %arg0, i32 %arg1) {
231 %add0 = add i32 %arg0, %arg1
232 %gep1 = getelementptr i8, ptr @glob0, i32 1
233 %gep2 = getelementptr i8, ptr @glob1, i32 1
234 ret i32 %add0
236 )IR");
237 llvm::Function &LLVMF = *M->getFunction("foo");
238 sandboxir::Context Ctx(C);
240 auto &F = *Ctx.createFunction(&LLVMF);
241 auto &BB = *F.begin();
242 auto *Arg0 = F.getArg(0);
243 auto *Arg1 = F.getArg(1);
244 auto It = BB.begin();
245 auto *I0 = &*It++;
246 auto *I1 = &*It++;
247 auto *I2 = &*It++;
248 auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
250 bool Replaced;
251 // Try to replace an operand that doesn't match.
252 Replaced = I0->replaceUsesOfWith(Ret, Arg1);
253 EXPECT_FALSE(Replaced);
254 EXPECT_EQ(I0->getOperand(0), Arg0);
255 EXPECT_EQ(I0->getOperand(1), Arg1);
257 // Replace I0 operands when operands differ.
258 Replaced = I0->replaceUsesOfWith(Arg0, Arg1);
259 EXPECT_TRUE(Replaced);
260 EXPECT_EQ(I0->getOperand(0), Arg1);
261 EXPECT_EQ(I0->getOperand(1), Arg1);
263 // Replace I0 operands when operands are the same.
264 Replaced = I0->replaceUsesOfWith(Arg1, Arg0);
265 EXPECT_TRUE(Replaced);
266 EXPECT_EQ(I0->getOperand(0), Arg0);
267 EXPECT_EQ(I0->getOperand(1), Arg0);
269 // Replace Ret operand.
270 Replaced = Ret->replaceUsesOfWith(I0, Arg0);
271 EXPECT_TRUE(Replaced);
272 EXPECT_EQ(Ret->getOperand(0), Arg0);
274 // Check RAUW on constant.
275 auto *Glob0 = cast<sandboxir::Constant>(I1->getOperand(0));
276 auto *Glob1 = cast<sandboxir::Constant>(I2->getOperand(0));
277 auto *Glob0Op = Glob0->getOperand(0);
278 Glob0->replaceUsesOfWith(Glob0Op, Glob1);
279 EXPECT_EQ(Glob0->getOperand(0), Glob1);
282 TEST_F(SandboxIRTest, RAUW_RUWIf) {
283 parseIR(C, R"IR(
284 define void @foo(ptr %ptr) {
285 %ld0 = load float, ptr %ptr
286 %ld1 = load float, ptr %ptr
287 store float %ld0, ptr %ptr
288 store float %ld0, ptr %ptr
289 ret void
291 )IR");
292 llvm::Function &LLVMF = *M->getFunction("foo");
293 sandboxir::Context Ctx(C);
294 llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
296 Ctx.createFunction(&LLVMF);
297 auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB));
298 auto It = BB->begin();
299 sandboxir::Instruction *Ld0 = &*It++;
300 sandboxir::Instruction *Ld1 = &*It++;
301 sandboxir::Instruction *St0 = &*It++;
302 sandboxir::Instruction *St1 = &*It++;
303 // Check RUWIf when the lambda returns false.
304 Ld0->replaceUsesWithIf(Ld1, [](const sandboxir::Use &Use) { return false; });
305 EXPECT_EQ(St0->getOperand(0), Ld0);
306 EXPECT_EQ(St1->getOperand(0), Ld0);
307 // Check RUWIf when the lambda returns true.
308 Ld0->replaceUsesWithIf(Ld1, [](const sandboxir::Use &Use) { return true; });
309 EXPECT_EQ(St0->getOperand(0), Ld1);
310 EXPECT_EQ(St1->getOperand(0), Ld1);
311 St0->setOperand(0, Ld0);
312 St1->setOperand(0, Ld0);
313 // Check RUWIf user == St0.
314 Ld0->replaceUsesWithIf(
315 Ld1, [St0](const sandboxir::Use &Use) { return Use.getUser() == St0; });
316 EXPECT_EQ(St0->getOperand(0), Ld1);
317 EXPECT_EQ(St1->getOperand(0), Ld0);
318 St0->setOperand(0, Ld0);
319 // Check RUWIf user == St1.
320 Ld0->replaceUsesWithIf(
321 Ld1, [St1](const sandboxir::Use &Use) { return Use.getUser() == St1; });
322 EXPECT_EQ(St0->getOperand(0), Ld0);
323 EXPECT_EQ(St1->getOperand(0), Ld1);
324 St1->setOperand(0, Ld0);
325 // Check RAUW.
326 Ld1->replaceAllUsesWith(Ld0);
327 EXPECT_EQ(St0->getOperand(0), Ld0);
328 EXPECT_EQ(St1->getOperand(0), Ld0);
331 // Check that the operands/users are counted correctly.
332 // I1
333 // / \
334 // \ /
335 // I2
336 TEST_F(SandboxIRTest, DuplicateUses) {
337 parseIR(C, R"IR(
338 define void @foo(i8 %v) {
339 %I1 = add i8 %v, %v
340 %I2 = add i8 %I1, %I1
341 ret void
343 )IR");
344 Function &LLVMF = *M->getFunction("foo");
345 sandboxir::Context Ctx(C);
346 auto *F = Ctx.createFunction(&LLVMF);
347 auto *BB = &*F->begin();
348 auto It = BB->begin();
349 auto *I1 = &*It++;
350 auto *I2 = &*It++;
351 EXPECT_EQ(range_size(I1->users()), 2u);
352 EXPECT_EQ(range_size(I2->operands()), 2u);
355 TEST_F(SandboxIRTest, Function) {
356 parseIR(C, R"IR(
357 define void @foo(i32 %arg0, i32 %arg1) {
358 bb0:
359 br label %bb1
360 bb1:
361 ret void
363 )IR");
364 llvm::Function *LLVMF = &*M->getFunction("foo");
365 llvm::Argument *LLVMArg0 = LLVMF->getArg(0);
366 llvm::Argument *LLVMArg1 = LLVMF->getArg(1);
368 sandboxir::Context Ctx(C);
369 sandboxir::Function *F = Ctx.createFunction(LLVMF);
371 // Check F arguments
372 EXPECT_EQ(F->arg_size(), 2u);
373 EXPECT_FALSE(F->arg_empty());
374 EXPECT_EQ(F->getArg(0), Ctx.getValue(LLVMArg0));
375 EXPECT_EQ(F->getArg(1), Ctx.getValue(LLVMArg1));
377 // Check F.begin(), F.end(), Function::iterator
378 llvm::BasicBlock *LLVMBB = &*LLVMF->begin();
379 for (sandboxir::BasicBlock &BB : *F) {
380 EXPECT_EQ(&BB, Ctx.getValue(LLVMBB));
381 LLVMBB = LLVMBB->getNextNode();
384 #ifndef NDEBUG
386 // Check F.dumpNameAndArgs()
387 std::string Buff;
388 raw_string_ostream BS(Buff);
389 F->dumpNameAndArgs(BS);
390 EXPECT_EQ(Buff, "void @foo(i32 %arg0, i32 %arg1)");
393 // Check F.dump()
394 std::string Buff;
395 raw_string_ostream BS(Buff);
396 BS << "\n";
397 F->dump(BS);
398 EXPECT_EQ(Buff, R"IR(
399 void @foo(i32 %arg0, i32 %arg1) {
400 bb0:
401 br label %bb1 ; SB3. (Opaque)
403 bb1:
404 ret void ; SB5. (Ret)
406 )IR");
408 #endif // NDEBUG
411 TEST_F(SandboxIRTest, BasicBlock) {
412 parseIR(C, R"IR(
413 define void @foo(i32 %v1) {
414 bb0:
415 br label %bb1
416 bb1:
417 ret void
419 )IR");
420 llvm::Function *LLVMF = &*M->getFunction("foo");
421 llvm::BasicBlock *LLVMBB0 = getBasicBlockByName(*LLVMF, "bb0");
422 llvm::BasicBlock *LLVMBB1 = getBasicBlockByName(*LLVMF, "bb1");
424 sandboxir::Context Ctx(C);
425 sandboxir::Function *F = Ctx.createFunction(LLVMF);
426 auto &BB0 = cast<sandboxir::BasicBlock>(*Ctx.getValue(LLVMBB0));
427 auto &BB1 = cast<sandboxir::BasicBlock>(*Ctx.getValue(LLVMBB1));
429 // Check BB::classof()
430 EXPECT_TRUE(isa<sandboxir::Value>(BB0));
431 EXPECT_FALSE(isa<sandboxir::User>(BB0));
432 EXPECT_FALSE(isa<sandboxir::Instruction>(BB0));
433 EXPECT_FALSE(isa<sandboxir::Constant>(BB0));
434 EXPECT_FALSE(isa<sandboxir::Argument>(BB0));
436 // Check BB.getParent()
437 EXPECT_EQ(BB0.getParent(), F);
438 EXPECT_EQ(BB1.getParent(), F);
440 // Check BBIterator, BB.begin(), BB.end().
441 llvm::Instruction *LLVMI = &*LLVMBB0->begin();
442 for (sandboxir::Instruction &I : BB0) {
443 EXPECT_EQ(&I, Ctx.getValue(LLVMI));
444 LLVMI = LLVMI->getNextNode();
446 LLVMI = &*LLVMBB1->begin();
447 for (sandboxir::Instruction &I : BB1) {
448 EXPECT_EQ(&I, Ctx.getValue(LLVMI));
449 LLVMI = LLVMI->getNextNode();
452 // Check BB.getTerminator()
453 EXPECT_EQ(BB0.getTerminator(), Ctx.getValue(LLVMBB0->getTerminator()));
454 EXPECT_EQ(BB1.getTerminator(), Ctx.getValue(LLVMBB1->getTerminator()));
456 // Check BB.rbegin(), BB.rend()
457 EXPECT_EQ(&*BB0.rbegin(), BB0.getTerminator());
458 EXPECT_EQ(&*std::prev(BB0.rend()), &*BB0.begin());
460 #ifndef NDEBUG
462 // Check BB.dump()
463 std::string Buff;
464 raw_string_ostream BS(Buff);
465 BS << "\n";
466 BB0.dump(BS);
467 EXPECT_EQ(Buff, R"IR(
468 bb0:
469 br label %bb1 ; SB2. (Opaque)
470 )IR");
472 #endif // NDEBUG
475 TEST_F(SandboxIRTest, Instruction) {
476 parseIR(C, R"IR(
477 define void @foo(i8 %v1) {
478 %add0 = add i8 %v1, %v1
479 %sub1 = sub i8 %add0, %v1
480 ret void
482 )IR");
483 llvm::Function *LLVMF = &*M->getFunction("foo");
484 sandboxir::Context Ctx(C);
485 sandboxir::Function *F = Ctx.createFunction(LLVMF);
486 auto *Arg = F->getArg(0);
487 auto *BB = &*F->begin();
488 auto It = BB->begin();
489 auto *I0 = &*It++;
490 auto *I1 = &*It++;
491 auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
493 // Check getPrevNode().
494 EXPECT_EQ(Ret->getPrevNode(), I1);
495 EXPECT_EQ(I1->getPrevNode(), I0);
496 EXPECT_EQ(I0->getPrevNode(), nullptr);
498 // Check getNextNode().
499 EXPECT_EQ(I0->getNextNode(), I1);
500 EXPECT_EQ(I1->getNextNode(), Ret);
501 EXPECT_EQ(Ret->getNextNode(), nullptr);
503 // Check getIterator().
504 EXPECT_EQ(I0->getIterator(), std::next(BB->begin(), 0));
505 EXPECT_EQ(I1->getIterator(), std::next(BB->begin(), 1));
506 EXPECT_EQ(Ret->getIterator(), std::next(BB->begin(), 2));
508 // Check getOpcode().
509 EXPECT_EQ(I0->getOpcode(), sandboxir::Instruction::Opcode::Opaque);
510 EXPECT_EQ(I1->getOpcode(), sandboxir::Instruction::Opcode::Opaque);
511 EXPECT_EQ(Ret->getOpcode(), sandboxir::Instruction::Opcode::Ret);
513 // Check moveBefore(I).
514 I1->moveBefore(I0);
515 EXPECT_EQ(I0->getPrevNode(), I1);
516 EXPECT_EQ(I1->getNextNode(), I0);
518 // Check moveAfter(I).
519 I1->moveAfter(I0);
520 EXPECT_EQ(I0->getNextNode(), I1);
521 EXPECT_EQ(I1->getPrevNode(), I0);
523 // Check moveBefore(BB, It).
524 I1->moveBefore(*BB, BB->begin());
525 EXPECT_EQ(I1->getPrevNode(), nullptr);
526 EXPECT_EQ(I1->getNextNode(), I0);
527 I1->moveBefore(*BB, BB->end());
528 EXPECT_EQ(I1->getNextNode(), nullptr);
529 EXPECT_EQ(Ret->getNextNode(), I1);
530 I1->moveBefore(*BB, std::next(BB->begin()));
531 EXPECT_EQ(I0->getNextNode(), I1);
532 EXPECT_EQ(I1->getNextNode(), Ret);
534 // Check removeFromParent().
535 I0->removeFromParent();
536 #ifndef NDEBUG
537 EXPECT_DEATH(I0->getPrevNode(), ".*Detached.*");
538 EXPECT_DEATH(I0->getNextNode(), ".*Detached.*");
539 #endif // NDEBUG
540 EXPECT_EQ(I0->getParent(), nullptr);
541 EXPECT_EQ(I1->getPrevNode(), nullptr);
542 EXPECT_EQ(I0->getOperand(0), Arg);
544 // Check insertBefore().
545 I0->insertBefore(I1);
546 EXPECT_EQ(I1->getPrevNode(), I0);
548 // Check insertInto().
549 I0->removeFromParent();
550 I0->insertInto(BB, BB->end());
551 EXPECT_EQ(Ret->getNextNode(), I0);
552 I0->moveBefore(I1);
553 EXPECT_EQ(I0->getNextNode(), I1);
555 // Check eraseFromParent().
556 #ifndef NDEBUG
557 EXPECT_DEATH(I0->eraseFromParent(), "Still connected to users.*");
558 #endif
559 I1->eraseFromParent();
560 EXPECT_EQ(I0->getNumUses(), 0u);
561 EXPECT_EQ(I0->getNextNode(), Ret);
564 TEST_F(SandboxIRTest, SelectInst) {
565 parseIR(C, R"IR(
566 define void @foo(i1 %c0, i8 %v0, i8 %v1, i1 %c1) {
567 %sel = select i1 %c0, i8 %v0, i8 %v1
568 ret void
570 )IR");
571 llvm::Function *LLVMF = &*M->getFunction("foo");
572 sandboxir::Context Ctx(C);
573 sandboxir::Function *F = Ctx.createFunction(LLVMF);
574 auto *Cond0 = F->getArg(0);
575 auto *V0 = F->getArg(1);
576 auto *V1 = F->getArg(2);
577 auto *Cond1 = F->getArg(3);
578 auto *BB = &*F->begin();
579 auto It = BB->begin();
580 auto *Select = cast<sandboxir::SelectInst>(&*It++);
581 auto *Ret = &*It++;
583 // Check getCondition().
584 EXPECT_EQ(Select->getCondition(), Cond0);
585 // Check getTrueValue().
586 EXPECT_EQ(Select->getTrueValue(), V0);
587 // Check getFalseValue().
588 EXPECT_EQ(Select->getFalseValue(), V1);
589 // Check setCondition().
590 Select->setCondition(Cond1);
591 EXPECT_EQ(Select->getCondition(), Cond1);
592 // Check setTrueValue().
593 Select->setTrueValue(V1);
594 EXPECT_EQ(Select->getTrueValue(), V1);
595 // Check setFalseValue().
596 Select->setFalseValue(V0);
597 EXPECT_EQ(Select->getFalseValue(), V0);
600 // Check SelectInst::create() InsertBefore.
601 auto *NewSel = cast<sandboxir::SelectInst>(sandboxir::SelectInst::create(
602 Cond0, V0, V1, /*InsertBefore=*/Ret, Ctx));
603 EXPECT_EQ(NewSel->getCondition(), Cond0);
604 EXPECT_EQ(NewSel->getTrueValue(), V0);
605 EXPECT_EQ(NewSel->getFalseValue(), V1);
606 EXPECT_EQ(NewSel->getNextNode(), Ret);
609 // Check SelectInst::create() InsertAtEnd.
610 auto *NewSel = cast<sandboxir::SelectInst>(
611 sandboxir::SelectInst::create(Cond0, V0, V1, /*InsertAtEnd=*/BB, Ctx));
612 EXPECT_EQ(NewSel->getCondition(), Cond0);
613 EXPECT_EQ(NewSel->getTrueValue(), V0);
614 EXPECT_EQ(NewSel->getFalseValue(), V1);
615 EXPECT_EQ(NewSel->getPrevNode(), Ret);
618 // Check SelectInst::create() Folded.
619 auto *False =
620 sandboxir::Constant::createInt(llvm::Type::getInt1Ty(C), 0, Ctx,
621 /*IsSigned=*/false);
622 auto *FortyTwo =
623 sandboxir::Constant::createInt(llvm::Type::getInt1Ty(C), 42, Ctx,
624 /*IsSigned=*/false);
625 auto *NewSel =
626 sandboxir::SelectInst::create(False, FortyTwo, FortyTwo, Ret, Ctx);
627 EXPECT_TRUE(isa<sandboxir::Constant>(NewSel));
628 EXPECT_EQ(NewSel, FortyTwo);
632 TEST_F(SandboxIRTest, LoadInst) {
633 parseIR(C, R"IR(
634 define void @foo(ptr %arg0, ptr %arg1) {
635 %ld = load i8, ptr %arg0, align 64
636 ret void
638 )IR");
639 llvm::Function *LLVMF = &*M->getFunction("foo");
640 sandboxir::Context Ctx(C);
641 sandboxir::Function *F = Ctx.createFunction(LLVMF);
642 auto *Arg0 = F->getArg(0);
643 auto *Arg1 = F->getArg(1);
644 auto *BB = &*F->begin();
645 auto It = BB->begin();
646 auto *Ld = cast<sandboxir::LoadInst>(&*It++);
647 auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
649 // Check getPointerOperand()
650 EXPECT_EQ(Ld->getPointerOperand(), Arg0);
651 // Check getAlign()
652 EXPECT_EQ(Ld->getAlign(), 64);
653 // Check create(InsertBefore)
654 sandboxir::LoadInst *NewLd =
655 sandboxir::LoadInst::create(Ld->getType(), Arg1, Align(8),
656 /*InsertBefore=*/Ret, Ctx, "NewLd");
657 EXPECT_EQ(NewLd->getType(), Ld->getType());
658 EXPECT_EQ(NewLd->getPointerOperand(), Arg1);
659 EXPECT_EQ(NewLd->getAlign(), 8);
660 EXPECT_EQ(NewLd->getName(), "NewLd");
663 TEST_F(SandboxIRTest, StoreInst) {
664 parseIR(C, R"IR(
665 define void @foo(i8 %val, ptr %ptr) {
666 store i8 %val, ptr %ptr, align 64
667 ret void
669 )IR");
670 llvm::Function *LLVMF = &*M->getFunction("foo");
671 sandboxir::Context Ctx(C);
672 sandboxir::Function *F = Ctx.createFunction(LLVMF);
673 auto *Val = F->getArg(0);
674 auto *Ptr = F->getArg(1);
675 auto *BB = &*F->begin();
676 auto It = BB->begin();
677 auto *St = cast<sandboxir::StoreInst>(&*It++);
678 auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
680 // Check that the StoreInst has been created correctly.
681 // Check getPointerOperand()
682 EXPECT_EQ(St->getValueOperand(), Val);
683 EXPECT_EQ(St->getPointerOperand(), Ptr);
684 // Check getAlign()
685 EXPECT_EQ(St->getAlign(), 64);
686 // Check create(InsertBefore)
687 sandboxir::StoreInst *NewSt =
688 sandboxir::StoreInst::create(Val, Ptr, Align(8),
689 /*InsertBefore=*/Ret, Ctx);
690 EXPECT_EQ(NewSt->getType(), St->getType());
691 EXPECT_EQ(NewSt->getValueOperand(), Val);
692 EXPECT_EQ(NewSt->getPointerOperand(), Ptr);
693 EXPECT_EQ(NewSt->getAlign(), 8);
696 TEST_F(SandboxIRTest, ReturnInst) {
697 parseIR(C, R"IR(
698 define i8 @foo(i8 %val) {
699 %add = add i8 %val, 42
700 ret i8 %val
702 )IR");
703 llvm::Function *LLVMF = &*M->getFunction("foo");
704 sandboxir::Context Ctx(C);
705 sandboxir::Function *F = Ctx.createFunction(LLVMF);
706 auto *Val = F->getArg(0);
707 auto *BB = &*F->begin();
708 auto It = BB->begin();
709 It++;
710 auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
712 // Check that the ReturnInst has been created correctly.
713 // Check getReturnValue().
714 EXPECT_EQ(Ret->getReturnValue(), Val);
716 // Check create(InsertBefore) a void ReturnInst.
717 auto *NewRet1 = cast<sandboxir::ReturnInst>(
718 sandboxir::ReturnInst::create(nullptr, /*InsertBefore=*/Ret, Ctx));
719 EXPECT_EQ(NewRet1->getReturnValue(), nullptr);
720 // Check create(InsertBefore) a non-void ReturnInst.
721 auto *NewRet2 = cast<sandboxir::ReturnInst>(
722 sandboxir::ReturnInst::create(Val, /*InsertBefore=*/Ret, Ctx));
723 EXPECT_EQ(NewRet2->getReturnValue(), Val);
725 // Check create(InsertAtEnd) a void ReturnInst.
726 auto *NewRet3 = cast<sandboxir::ReturnInst>(
727 sandboxir::ReturnInst::create(nullptr, /*InsertAtEnd=*/BB, Ctx));
728 EXPECT_EQ(NewRet3->getReturnValue(), nullptr);
729 // Check create(InsertAtEnd) a non-void ReturnInst.
730 auto *NewRet4 = cast<sandboxir::ReturnInst>(
731 sandboxir::ReturnInst::create(Val, /*InsertAtEnd=*/BB, Ctx));
732 EXPECT_EQ(NewRet4->getReturnValue(), Val);