1 //===- SandboxIRTest.cpp --------------------------------------------------===//
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
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"
20 struct SandboxIRTest
: public testing::Test
{
22 std::unique_ptr
<Module
> M
;
24 void parseIR(LLVMContext
&C
, const char *IR
) {
26 M
= parseAssemblyString(IR
, Err
, C
);
28 Err
.print("SandboxIRTest", errs());
30 BasicBlock
*getBasicBlockByName(Function
&F
, StringRef Name
) {
31 for (BasicBlock
&BB
: F
)
32 if (BB
.getName() == Name
)
34 llvm_unreachable("Expected to find basic block!");
38 TEST_F(SandboxIRTest
, ClassID
) {
40 define void @foo(i32 %v1) {
41 %add = add i32 %v1, 42
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
));
102 raw_string_ostream
BS(Buff
);
112 TEST_F(SandboxIRTest
, Use
) {
114 define i32 @foo(i32 %v0, i32 %v1) {
115 %add0 = add i32 %v0, %v1
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();
135 auto *Ret
= cast
<sandboxir::ReturnInst
>(&*It
++);
137 SmallVector
<sandboxir::Argument
*> Args
{Arg0
, Arg1
};
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
);
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
;
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
));
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
);
179 raw_string_ostream
BS(Buff
);
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)
189 // Check Value.user_begin().
190 sandboxir::Value::user_iterator UIt
= I0
->user_begin();
191 sandboxir::User
*U
= *UIt
;
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
) {
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
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();
248 auto *Ret
= cast
<sandboxir::ReturnInst
>(&*It
++);
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
) {
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
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
);
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.
336 TEST_F(SandboxIRTest
, DuplicateUses
) {
338 define void @foo(i8 %v) {
340 %I2 = add i8 %I1, %I1
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();
351 EXPECT_EQ(range_size(I1
->users()), 2u);
352 EXPECT_EQ(range_size(I2
->operands()), 2u);
355 TEST_F(SandboxIRTest
, Function
) {
357 define void @foo(i32 %arg0, i32 %arg1) {
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
);
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();
386 // Check F.dumpNameAndArgs()
388 raw_string_ostream
BS(Buff
);
389 F
->dumpNameAndArgs(BS
);
390 EXPECT_EQ(Buff
, "void @foo(i32 %arg0, i32 %arg1)");
395 raw_string_ostream
BS(Buff
);
398 EXPECT_EQ(Buff
, R
"IR(
399 void @foo(i32 %arg0, i32 %arg1) {
401 br label %bb1 ; SB3. (Opaque)
404 ret void ; SB5. (Ret)
411 TEST_F(SandboxIRTest
, BasicBlock
) {
413 define void @foo(i32 %v1) {
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());
464 raw_string_ostream
BS(Buff
);
467 EXPECT_EQ(Buff
, R
"IR(
469 br label %bb1 ; SB2. (Opaque)
475 TEST_F(SandboxIRTest
, Instruction
) {
477 define void @foo(i8 %v1) {
478 %add0 = add i8 %v1, %v1
479 %sub1 = sub i8 %add0, %v1
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();
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).
515 EXPECT_EQ(I0
->getPrevNode(), I1
);
516 EXPECT_EQ(I1
->getNextNode(), I0
);
518 // Check moveAfter(I).
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();
537 EXPECT_DEATH(I0
->getPrevNode(), ".*Detached.*");
538 EXPECT_DEATH(I0
->getNextNode(), ".*Detached.*");
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
);
553 EXPECT_EQ(I0
->getNextNode(), I1
);
555 // Check eraseFromParent().
557 EXPECT_DEATH(I0
->eraseFromParent(), "Still connected to users.*");
559 I1
->eraseFromParent();
560 EXPECT_EQ(I0
->getNumUses(), 0u);
561 EXPECT_EQ(I0
->getNextNode(), Ret
);
564 TEST_F(SandboxIRTest
, SelectInst
) {
566 define void @foo(i1 %c0, i8 %v0, i8 %v1, i1 %c1) {
567 %sel = select i1 %c0, i8 %v0, i8 %v1
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
++);
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.
620 sandboxir::Constant::createInt(llvm::Type::getInt1Ty(C
), 0, Ctx
,
623 sandboxir::Constant::createInt(llvm::Type::getInt1Ty(C
), 42, Ctx
,
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
) {
634 define void @foo(ptr %arg0, ptr %arg1) {
635 %ld = load i8, ptr %arg0, align 64
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
);
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
) {
665 define void @foo(i8 %val, ptr %ptr) {
666 store i8 %val, ptr %ptr, align 64
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
);
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
) {
698 define i8 @foo(i8 %val) {
699 %add = add i8 %val, 42
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();
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
);