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/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"
29 struct SandboxIRTest
: public testing::Test
{
31 std::unique_ptr
<Module
> M
;
33 void parseIR(LLVMContext
&C
, const char *IR
) {
35 M
= parseAssemblyString(IR
, Err
, C
);
37 Err
.print("SandboxIRTest", errs());
39 BasicBlock
*getBasicBlockByName(Function
&F
, StringRef Name
) {
40 for (BasicBlock
&BB
: F
)
41 if (BB
.getName() == Name
)
43 llvm_unreachable("Expected to find basic block!");
47 TEST_F(SandboxIRTest
, ClassID
) {
49 define void @foo(i32 %v1) {
50 %add = add i32 %v1, 42
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
));
104 raw_string_ostream
BS(Buff
);
113 TEST_F(SandboxIRTest
, ConstantInt
) {
115 define void @foo(i32 %v0) {
116 %add0 = add i32 %v0, 42
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.
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).
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).
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).
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
));
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().
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().
266 sandboxir::ConstantInt::isValueValidForType(Int32Ty
, (uint64_t)42));
268 sandboxir::ConstantInt::isValueValidForType(Int32Ty
, (int64_t)42));
269 // Check isNegative().
270 EXPECT_FALSE(FortyTwo
->isNegative());
271 EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty
, -42));
273 EXPECT_FALSE(FortyTwo
->isZero());
274 EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty
, 0)->isZero());
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));
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));
289 sandboxir::ConstantInt::get(Int32Ty
, std::numeric_limits
<int32_t>::min())
290 ->isMinValue(/*Signed=*/true));
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
) {
301 define void @foo(float %v0, double %v1) {
302 %fadd0 = fadd float %v0, 42.0
303 %fadd1 = fadd double %v1, 43.0
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).
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))));
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,
358 EXPECT_EQ(NaN
, Ctx
.getValue(llvm::ConstantFP::getNaN(
359 LLVMFloatTy
, /*Negative=*/true, /*Payload=*/1)));
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)));
374 sandboxir::ConstantFP::getQNaN(FloatTy
, /*Negative=*/true, &Payload
);
375 EXPECT_EQ(QNaN
, Ctx
.getValue(llvm::ConstantFP::getQNaN(
376 LLVMFloatTy
, /*Negative=*/true, &Payload
)));
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)));
391 sandboxir::ConstantFP::getSNaN(FloatTy
, /*Negative=*/true, &Payload
);
392 EXPECT_EQ(SNaN
, Ctx
.getValue(llvm::ConstantFP::getSNaN(
393 LLVMFloatTy
, /*Negative=*/true, &Payload
)));
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
));
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().
426 EXPECT_EQ(sandboxir::ConstantFP::isValueValidForType(FloatTy
, V
),
427 llvm::ConstantFP::isValueValidForType(LLVMFloatTy
, V
));
428 // Check getValueAPF().
429 EXPECT_EQ(FortyFour
->getValueAPF(), LLVMFortyFour
->getValueAPF());
431 EXPECT_EQ(FortyFour
->getValue(), LLVMFortyFour
->getValue());
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))
440 // Check isInfinity().
442 cast
<sandboxir::ConstantFP
>(sandboxir::ConstantFP::getInfinity(FloatTy
))
446 cast
<sandboxir::ConstantFP
>(sandboxir::ConstantFP::getNaN(FloatTy
))
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.
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
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();
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().
487 sandboxir::ConstantArray::get(Array
->getType(), {ZeroI42
, OneI42
});
488 EXPECT_EQ(NewCA
, Array
);
490 // Check ConstantStruct::get(), getType().
492 sandboxir::ConstantStruct::get(Struct
->getType(), {ZeroI42
, OneI42
});
493 EXPECT_EQ(NewCS
, Struct
);
494 // Check ConstantStruct::get(...).
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());
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).
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).
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
) {
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
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
++);
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
});
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
);
562 cast
<sandboxir::ConstantAggregateZero
>(Extr1
->getOperand(0));
563 EXPECT_EQ(StructCAZ
->getType(), StructTy
);
565 cast
<sandboxir::ConstantAggregateZero
>(Extr2
->getOperand(0));
566 EXPECT_EQ(VectorCAZ
->getType(), VectorTy
);
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.
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();
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
) {
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());
615 sandboxir::ConstantPointerNull::get(sandboxir::PointerType::get(Ctx
, 0u));
616 EXPECT_EQ(NewCPNull
, CPNull
);
618 sandboxir::ConstantPointerNull::get(sandboxir::PointerType::get(Ctx
, 1u));
619 EXPECT_NE(NewCPNull2
, CPNull
);
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
) {
628 %i0 = add i32 poison, poison
629 %i1 = add <2 x i32> poison, poison
630 %i2 = extractvalue {i32, i8} poison, 0
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();
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
653 auto *NewPoison
= sandboxir::PoisonValue::get(Int32Ty
);
654 EXPECT_EQ(NewPoison
, Poison
);
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
) {
683 %i0 = add i32 undef, undef
684 %i1 = add <2 x i32> undef, undef
685 %i2 = extractvalue {i32, i8} undef, 0
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();
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
708 auto *NewUndef
= sandboxir::UndefValue::get(Int32Ty
);
709 EXPECT_EQ(NewUndef
, Undef
);
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
) {
740 declare external void @bar()
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().
780 sandboxir::GlobalValue::getMinUnnamedAddr(OrigUnnamedAddr
,
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();
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
) {
806 declare external void @bar()
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());
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();
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
) {
870 declare external void @bar()
871 @ifunc0 = ifunc void(), ptr @foo
872 @ifunc1 = ifunc void(), ptr @foo
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().
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
) {
948 @glob0 = global i32 42
949 @glob1 = global i32 43
951 %ld0 = load i32, ptr @glob0
952 %ld1 = load i32, ptr @glob1
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
) {
1062 @alias0 = dso_local alias void(), ptr @foo
1063 @alias1 = dso_local alias void(), ptr @foo
1064 declare void @bar();
1065 define void @foo() {
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
) {
1128 define void @foo() {
1129 call void no_cfi @foo()
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());
1143 auto *NewNoCFI
= sandboxir::NoCFIValue::get(&F
);
1144 EXPECT_EQ(NewNoCFI
, NoCFI
);
1145 // Check getGlobalValue().
1146 EXPECT_EQ(NoCFI
->getGlobalValue(), &F
);
1148 EXPECT_EQ(NoCFI
->getType(), F
.getType());
1151 TEST_F(SandboxIRTest
, ConstantPtrAuth
) {
1154 ret ptr ptrauth (ptr @foo, i32 2, i64 1234)
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
) {
1191 ret i32 ptrtoint (ptr @foo to i32)
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
) {
1208 define void @foo(ptr %ptr) {
1210 store ptr blockaddress(@foo, %bb0), ptr %ptr
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
);
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
);
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
) {
1257 define void @foo() {
1258 call void dso_local_equivalent @bar()
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
++);
1270 auto *DSOLE
= cast
<sandboxir::DSOLocalEquivalent
>(CI
->getCalledOperand());
1271 // Check getGlobalValue().
1272 auto *GV
= DSOLE
->getGlobalValue();
1274 auto *NewDSOLE
= sandboxir::DSOLocalEquivalent::get(GV
);
1275 EXPECT_EQ(NewDSOLE
, DSOLE
);
1278 TEST_F(SandboxIRTest
, ConstantTokenNone
) {
1280 define void @foo(ptr %ptr) {
1282 %cs = catchswitch within none [label %handler] unwind to caller
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());
1298 auto *NewCTN
= sandboxir::ConstantTokenNone::get(Ctx
);
1299 EXPECT_EQ(NewCTN
, CTN
);
1302 TEST_F(SandboxIRTest
, Use
) {
1304 define i32 @foo(i32 %v0, i32 %v1) {
1305 %add0 = add i32 %v0, %v1
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();
1325 auto *Ret
= cast
<sandboxir::ReturnInst
>(&*It
++);
1327 SmallVector
<sandboxir::Argument
*> Args
{Arg0
, Arg1
};
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
);
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
));
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
);
1367 // Check Use.dump(()
1369 raw_string_ostream
BS(Buff
);
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)
1379 // Check Value.user_begin().
1380 sandboxir::Value::user_iterator UIt
= I0
->user_begin();
1381 sandboxir::User
*U
= *UIt
;
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
) {
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
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();
1440 auto *Ret
= cast
<sandboxir::ReturnInst
>(&*It
++);
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
) {
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
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
);
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.
1527 TEST_F(SandboxIRTest
, DuplicateUses
) {
1529 define void @foo(i8 %v) {
1531 %I2 = add i8 %I1, %I1
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();
1542 EXPECT_EQ(range_size(I1
->users()), 2u);
1543 EXPECT_EQ(range_size(I2
->operands()), 2u);
1546 TEST_F(SandboxIRTest
, Function
) {
1548 define void @foo0(i32 %arg0, i32 %arg1) {
1554 define void @foo1() {
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();
1606 // Check F.dumpNameAndArgs()
1608 raw_string_ostream
BS(Buff
);
1609 F0
->dumpNameAndArgs(BS
);
1610 EXPECT_EQ(Buff
, "void @foo0(i32 %arg0, i32 %arg1)");
1615 raw_string_ostream
BS(Buff
);
1618 EXPECT_EQ(Buff
, R
"IR(
1619 void @foo0(i32 %arg0, i32 %arg1) {
1621 br label %bb1 ; SB4. (Br)
1624 ret void ; SB6. (Ret)
1631 TEST_F(SandboxIRTest
, Module
) {
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() {
1642 define void @bar() {
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
) {
1691 define void @foo(i32 %v1) {
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());
1746 raw_string_ostream
BS(Buff
);
1749 EXPECT_EQ(Buff
, R
"IR(
1751 br label %bb1 ; SB3. (Br)
1757 TEST_F(SandboxIRTest
, Instruction
) {
1759 define void @foo(i8 %v1, ptr %ptr) {
1761 %add0 = add i8 %v1, %v1
1762 %sub1 = sub i8 %add0, %v1
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
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();
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
),
1822 // Check moveBefore(I).
1824 EXPECT_EQ(I0
->getPrevNode(), I1
);
1825 EXPECT_EQ(I1
->getNextNode(), I0
);
1827 // Check moveAfter(I).
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();
1850 EXPECT_DEATH(I0
->getPrevNode(), ".*Detached.*");
1851 EXPECT_DEATH(I0
->getNextNode(), ".*Detached.*");
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
);
1866 EXPECT_EQ(I0
->getNextNode(), I1
);
1868 // Check eraseFromParent().
1870 EXPECT_DEATH(I0
->eraseFromParent(), "Still connected to users.*");
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());
1887 EXPECT_EQ(LLVMI
.isShift(), I
.isShift());
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());
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
) {
1940 define void @foo(ptr %va) {
1941 %va_arg = va_arg ptr %va, i32
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());
1961 auto *NewVATy
= sandboxir::Type::getInt8Ty(Ctx
);
1962 auto *NewVA
= sandboxir::VAArgInst::create(Arg
, NewVATy
, Ret
->getIterator(),
1964 EXPECT_EQ(NewVA
->getNextNode(), Ret
);
1965 EXPECT_EQ(NewVA
->getType(), NewVATy
);
1967 EXPECT_EQ(NewVA
->getName(), "NewVA");
1971 TEST_F(SandboxIRTest
, FreezeInst
) {
1973 define void @foo(i8 %arg) {
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
);
1993 sandboxir::FreezeInst::create(Arg
, Ret
->getIterator(), Ctx
, "NewFreeze");
1994 EXPECT_EQ(NewFreeze
->getNextNode(), Ret
);
1996 EXPECT_EQ(NewFreeze
->getName(), "NewFreeze");
2000 TEST_F(SandboxIRTest
, FenceInst
) {
2002 define void @foo() {
2003 fence syncscope("singlethread
") seq_cst
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
);
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
) {
2048 define void @foo(i1 %c0, i8 %v0, i8 %v1, i1 %c1) {
2049 %sel = select i1 %c0, i8 %v0, i8 %v1
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.
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);
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
) {
2126 define void @foo(<2 x i8> %vec, i32 %idx) {
2127 %ins0 = extractelement <2 x i8> %vec, i32 %idx
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
++);
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());
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
);
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
) {
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
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
++);
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);
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
);
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);
2210 sandboxir::InsertElementInst::isValidOperands(ArgVec
, Arg0
, Zero
),
2211 llvm::InsertElementInst::isValidOperands(LLVMArgVec
, LLVMArg0
, LLVMZero
));
2213 sandboxir::InsertElementInst::isValidOperands(Arg0
, ArgVec
, Zero
),
2214 llvm::InsertElementInst::isValidOperands(LLVMArg0
, LLVMArgVec
, LLVMZero
));
2217 TEST_F(SandboxIRTest
, ShuffleVectorInst
) {
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
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
++);
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)
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
);
2259 EXPECT_EQ(NewI1
->getName(), "NewShuffleBeforeRet");
2262 // create (InsertAtEnd)
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
));
2277 auto *LLVMArgV1
= LLVMF
.getArg(0);
2278 auto *LLVMArgV2
= LLVMF
.getArg(1);
2279 SmallVector
<int, 2> Mask({1, 2});
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
,
2289 auto *I
= CreateShuffleWithMask(0, 2);
2291 EXPECT_EQ(I
->getOperand(0), ArgV2
);
2292 EXPECT_EQ(I
->getOperand(1), ArgV1
);
2293 EXPECT_THAT(I
->getShuffleMask(), testing::ElementsAre(2, 0));
2297 EXPECT_EQ(SVI
->getType(), ArgV1
->getType());
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));
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));
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));
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));
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());
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));
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));
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));
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));
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));
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));
2475 sandboxir::ShuffleVectorInst::isTransposeMask(I
->getShuffleMask(), 2));
2478 // isSplice / isSpliceMask
2480 auto *I
= CreateShuffleWithMask(1, 2);
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(),
2490 auto *I
= CreateShuffleWithMask(2, 1);
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(),
2499 // isExtractSubvectorMask
2501 auto *I
= CreateShuffleWithMask(1);
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);
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);
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));
2611 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isDeInterleaveMaskOfFactor(
2612 ArrayRef
<int>({1, 3}), 2, Index
));
2613 EXPECT_EQ(Index
, 1u);
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
,
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
,
2631 TEST_F(SandboxIRTest
, ExtractValueInst
) {
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
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
++);
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
);
2666 EXPECT_EQ(NewExtBeforeRet
->getName(), "NewExtBeforeRet");
2669 // create at end of BB
2671 cast
<sandboxir::ExtractValueInst
>(sandboxir::ExtractValueInst::create(
2672 ArgAgg
, ArrayRef
<unsigned>({0}), BB
->end(), Ctx
, "NewExtAtEnd"));
2673 EXPECT_EQ(NewExtAtEnd
->getPrevNode(), Ret
);
2675 EXPECT_EQ(NewExtAtEnd
->getName(), "NewExtAtEnd");
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
);
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})),
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));
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());
2728 EXPECT_EQ(ExtSimple
->getIndices().size(), 1u);
2729 EXPECT_EQ(ExtSimple
->getIndices()[0], 0u);
2732 EXPECT_EQ(ExtSimple
->getNumIndices(), 1u);
2735 EXPECT_EQ(ExtSimple
->hasIndices(), true);
2738 TEST_F(SandboxIRTest
, InsertValueInst
) {
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
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
++);
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
);
2773 EXPECT_EQ(NewInsBeforeRet
->getName(), "NewInsBeforeRet");
2776 // create at end of BB
2778 cast
<sandboxir::InsertValueInst
>(sandboxir::InsertValueInst::create(
2779 ArgAgg
, ArgInt
, ArrayRef
<unsigned>({0}), BB
, Ctx
, "NewInsAtEnd"));
2780 EXPECT_EQ(NewInsAtEnd
->getPrevNode(), Ret
);
2782 EXPECT_EQ(NewInsAtEnd
->getName(), "NewInsAtEnd");
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));
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());
2831 EXPECT_EQ(InsSimple
->getIndices().size(), 1u);
2832 EXPECT_EQ(InsSimple
->getIndices()[0], 0u);
2835 EXPECT_EQ(InsSimple
->getNumIndices(), 1u);
2838 EXPECT_EQ(InsSimple
->hasIndices(), true);
2841 TEST_F(SandboxIRTest
, BranchInst
) {
2843 define void @foo(i1 %cond0, i1 %cond2) {
2845 br i1 %cond0, label %bb1, label %bb2
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());
2898 EXPECT_DEATH(Br
->getCondition(), ".*condition.*");
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());
2912 EXPECT_DEATH(Br
->getCondition(), ".*condition.*");
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
) {
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
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
);
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),
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
) {
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
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
);
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),
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
) {
3109 define i8 @foo(i8 %val) {
3110 %add = add i8 %val, 42
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();
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
) {
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)
3157 call void %indirectFoo()
3158 call void @bar2() noreturn
3159 tail call fastcc void @bar2()
3160 call void (ptr, ...) @variadic(ptr %indirectFoo, i32 1)
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());
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);
3250 auto *LLVMCF
= cast
<llvm::Function
>(LLVMCall
->getCalledFunction());
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
) {
3299 define i8 @foo(i8 %arg) {
3300 %call = call i8 @foo(i8 %arg)
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
) {
3349 define void @foo(i8 %arg) {
3351 invoke i8 @foo(i8 %arg) to label %normal_bb
3352 unwind label %exception_bb
3356 %lpad = landingpad { ptr, i32}
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
) {
3439 define void @foo(i8 %arg) {
3441 callbr void asm "", ""()
3442 to label %bb1 [label %bb2]
3450 callbr void @foo(i8 %arg)
3451 to label %bb1 [label %bb2]
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
++);
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
;
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
) {
3552 define void @foo() {
3555 to label %bb unwind label %unwind
3557 %lpad = landingpad { ptr, i32 }
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
)));
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
));
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());
3606 EXPECT_EQ(NewLPad
->getName(), "NewLPad");
3610 TEST_F(SandboxIRTest
, FuncletPadInst_CatchPadInst_CleanupPadInst
) {
3612 define void @foo() {
3614 %cs = catchswitch within none [label %handler0] unwind to caller
3616 %catchpad = catchpad within %cs [ptr @foo]
3619 %cleanuppad = cleanuppad within %cs [ptr @foo]
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
);
3686 EXPECT_EQ(NewCPI
->getName(), "NewCPI");
3688 // Check CleanupPadInst::create().
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
);
3696 EXPECT_EQ(NewCLPI
->getName(), "NewCLPI");
3700 TEST_F(SandboxIRTest
, CatchReturnInst
) {
3702 define void @foo() {
3704 %cs = catchswitch within none [label %catch] unwind to caller
3706 %catchpad = catchpad within %cs [ptr @foo]
3707 catchret from %catchpad to label %continue
3711 %catchpad2 = catchpad within %cs [ptr @foo]
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();
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()));
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
) {
3766 define void @foo() {
3769 to label %throw unwind label %cleanup
3773 %cleanuppad = cleanuppad within none []
3774 cleanupret from %cleanuppad unwind label %cleanup2
3776 %cleanuppad2 = cleanuppad within none []
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
);
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
) {
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>
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
) {
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());
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();
3899 APInt::getZero(DL
.getIndexSizeInBits(GEP
->getPointerAddressSpace()));
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.
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.
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.
3950 cast
<sandboxir::GetElementPtrInst
>(sandboxir::GetElementPtrInst::create(
3951 GEP0
->getType(), GEP0
->getPointerOperand(), Indices
, BB
, Ctx
,
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
) {
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
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();
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
) {
4029 define void @foo(i32 %cond0, i32 %cond1) {
4031 %cs0 = catchswitch within none [label %handler0, label %handler1] unwind to caller
4033 %cs1 = catchswitch within %cs0 [label %handler0, label %handler1] unwind label %cleanup
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();
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
);
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
) {
4133 define void @foo() {
4136 to label %bb unwind label %unwind
4140 %lpad = landingpad { ptr, i32 }
4142 resume { ptr, i32 } %lpad
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());
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
) {
4171 define void @foo(i32 %cond0, i32 %cond1) {
4173 switch i32 %cond0, label %default [ i32 0, label %bb0
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());
4259 unsigned CntCase
= 0;
4260 for (auto &Case
: Switch
->cases()) {
4261 EXPECT_EQ(Case
.getCaseIndex(), 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);
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);
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
) {
4299 define void @foo(float %arg0) {
4300 %fneg = fneg float %arg0
4301 %copyfrom = fadd reassoc float %arg0, 42.0
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
++);
4315 EXPECT_EQ(I
->getOpcode(), sandboxir::Instruction::Opcode::FNeg
);
4316 EXPECT_EQ(I
->getOperand(0), Arg0
);
4319 // Check create() WhereIt, WhereBB.
4321 cast
<sandboxir::UnaryOperator
>(sandboxir::UnaryOperator::create(
4322 sandboxir::Instruction::Opcode::FNeg
, Arg0
, Ret
->getIterator(), Ctx
,
4324 EXPECT_EQ(NewI
->getOpcode(), sandboxir::Instruction::Opcode::FNeg
);
4325 EXPECT_EQ(NewI
->getOperand(0), Arg0
);
4327 EXPECT_EQ(NewI
->getName(), "New1");
4329 EXPECT_EQ(NewI
->getNextNode(), Ret
);
4332 // Check create() InsertBefore.
4334 cast
<sandboxir::UnaryOperator
>(sandboxir::UnaryOperator::create(
4335 sandboxir::Instruction::Opcode::FNeg
, Arg0
, Ret
->getIterator(), Ctx
,
4337 EXPECT_EQ(NewI
->getOpcode(), sandboxir::Instruction::Opcode::FNeg
);
4338 EXPECT_EQ(NewI
->getOperand(0), Arg0
);
4340 EXPECT_EQ(NewI
->getName(), "New2");
4342 EXPECT_EQ(NewI
->getNextNode(), Ret
);
4345 // Check create() InsertAtEnd.
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
);
4352 EXPECT_EQ(NewI
->getName(), "New3");
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
,
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
);
4376 EXPECT_EQ(NewI
->getName(), "NewCopyFrom1");
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
);
4390 EXPECT_EQ(NewI
->getName(), "NewCopyFrom2");
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
,
4400 EXPECT_EQ(NewI
->hasAllowReassoc(), CopyFrom
->hasAllowReassoc());
4401 EXPECT_EQ(NewI
->getOpcode(), sandboxir::Instruction::Opcode::FNeg
);
4402 EXPECT_EQ(NewI
->getOperand(0), Arg0
);
4404 EXPECT_EQ(NewI
->getName(), "NewCopyFrom3");
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
,
4415 EXPECT_TRUE(isa
<sandboxir::Constant
>(NewV
));
4419 TEST_F(SandboxIRTest
, BinaryOperator
) {
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
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.
4496 cast
<sandboxir::BinaryOperator
>(sandboxir::BinaryOperator::create(
4497 sandboxir::Instruction::Opcode::Add
, Arg0
, Arg1
, Ret
->getIterator(),
4499 EXPECT_EQ(NewI
->getOpcode(), sandboxir::Instruction::Opcode::Add
);
4500 EXPECT_EQ(NewI
->getOperand(0), Arg0
);
4501 EXPECT_EQ(NewI
->getOperand(1), Arg1
);
4503 EXPECT_EQ(NewI
->getName(), "New1");
4505 EXPECT_EQ(NewI
->getNextNode(), Ret
);
4508 // Check create() InsertBefore.
4510 cast
<sandboxir::BinaryOperator
>(sandboxir::BinaryOperator::create(
4511 sandboxir::Instruction::Opcode::Add
, Arg0
, Arg1
, Ret
->getIterator(),
4513 EXPECT_EQ(NewI
->getOpcode(), sandboxir::Instruction::Opcode::Add
);
4514 EXPECT_EQ(NewI
->getOperand(0), Arg0
);
4515 EXPECT_EQ(NewI
->getOperand(1), Arg1
);
4517 EXPECT_EQ(NewI
->getName(), "New2");
4519 EXPECT_EQ(NewI
->getNextNode(), Ret
);
4522 // Check create() InsertAtEnd.
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
);
4531 EXPECT_EQ(NewI
->getName(), "New3");
4533 EXPECT_EQ(NewI
->getNextNode(), nullptr);
4534 EXPECT_EQ(NewI
->getParent(), BB
);
4537 // Check create() when it gets folded.
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
);
4557 EXPECT_EQ(NewI
->getName(), "NewNSW1");
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
);
4572 EXPECT_EQ(NewI
->getName(), "NewNSW2");
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
,
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
);
4587 EXPECT_EQ(NewI
->getName(), "NewNSW3");
4589 EXPECT_EQ(NewI
->getParent(), BB
);
4590 EXPECT_EQ(NewI
->getNextNode(), nullptr);
4593 // Check createWithCopiedFlags() when it gets folded.
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
) {
4605 define void @foo(i8 %arg0, i8 %arg1) {
4606 %or = or i8 %arg0, %arg1
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
) {
4630 define void @foo(ptr %ptr, i8 %arg) {
4631 %atomicrmw = atomicrmw add ptr %ptr, i8 %arg acquire, align 128
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().
4651 sandboxir::AtomicRMWInst::getOperationName(
4652 sandboxir::AtomicRMWInst::BinOp::Add
),
4653 llvm::AtomicRMWInst::getOperationName(llvm::AtomicRMWInst::BinOp::Add
));
4654 // Check isFPOperation().
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();
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());
4716 auto Ordering
= AtomicOrdering::Acquire
;
4717 auto SSID
= SyncScope::System
;
4719 // Check create() WhereIt, WhereBB.
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
);
4738 EXPECT_EQ(NewI
->getName(), "NewAtomicRMW1");
4742 // Check create() InsertBefore.
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
);
4761 EXPECT_EQ(NewI
->getName(), "NewAtomicRMW2");
4765 // Check create() InsertAtEnd.
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
);
4785 EXPECT_EQ(NewI
->getName(), "NewAtomicRMW3");
4790 TEST_F(SandboxIRTest
, AtomicCmpXchgInst
) {
4792 define void @foo(ptr %ptr, i8 %cmp, i8 %new) {
4793 %cmpxchg = cmpxchg ptr %ptr, i8 %cmp, i8 %new monotonic monotonic, align 128
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();
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());
4894 auto SuccOrdering
= AtomicOrdering::Acquire
;
4895 auto FailOrdering
= AtomicOrdering::Monotonic
;
4896 auto SSID
= SyncScope::System
;
4898 // Check create() WhereIt, WhereBB.
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
);
4921 EXPECT_EQ(NewI
->getName(), "NewAtomicCmpXchg1");
4925 // Check create() InsertBefore.
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
);
4948 EXPECT_EQ(NewI
->getName(), "NewAtomicCmpXchg2");
4952 // Check create() InsertAtEnd.
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
);
4976 EXPECT_EQ(NewI
->getName(), "NewAtomicCmpXchg3");
4981 TEST_F(SandboxIRTest
, AllocaInst
) {
4983 define void @foo() {
4984 %allocaScalar = alloca i32, align 1024
4985 %allocaArray = alloca i32, i32 42
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()));
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();
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
);
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
);
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
);
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
) {
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)
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
);
5311 // Check that passing a non-cast opcode crashes.
5313 sandboxir::CastInst::create(Ti64
, sandboxir::Instruction::Opcode::Store
,
5314 Arg
, Ret
->getIterator(), Ctx
, "Bad"),
5320 TEST_F(SandboxIRTest
, PossiblyNonNegInst
) {
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)
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
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
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.
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
) {
5431 define void @foo(i64 %arg) {
5432 %trunc = trunc i64 %arg to i32
5436 testCastInst
<sandboxir::TruncInst
, sandboxir::Instruction::Opcode::Trunc
>(
5438 /*SrcTy=*/Type::getInt64Ty(C
), /*DstTy=*/Type::getInt32Ty(C
));
5441 TEST_F(SandboxIRTest
, ZExtInst
) {
5443 define void @foo(i32 %arg) {
5444 %zext = zext i32 %arg to i64
5448 testCastInst
<sandboxir::ZExtInst
, sandboxir::Instruction::Opcode::ZExt
>(
5450 /*SrcTy=*/Type::getInt32Ty(C
), /*DstTy=*/Type::getInt64Ty(C
));
5453 TEST_F(SandboxIRTest
, SExtInst
) {
5455 define void @foo(i32 %arg) {
5456 %sext = sext i32 %arg to i64
5460 testCastInst
<sandboxir::SExtInst
, sandboxir::Instruction::Opcode::SExt
>(
5462 /*SrcTy=*/Type::getInt32Ty(C
), /*DstTy=*/Type::getInt64Ty(C
));
5465 TEST_F(SandboxIRTest
, FPTruncInst
) {
5467 define void @foo(double %arg) {
5468 %fptrunc = fptrunc double %arg to float
5472 testCastInst
<sandboxir::FPTruncInst
, sandboxir::Instruction::Opcode::FPTrunc
>(
5474 /*SrcTy=*/Type::getDoubleTy(C
), /*DstTy=*/Type::getFloatTy(C
));
5477 TEST_F(SandboxIRTest
, FPExtInst
) {
5479 define void @foo(float %arg) {
5480 %fpext = fpext float %arg to double
5484 testCastInst
<sandboxir::FPExtInst
, sandboxir::Instruction::Opcode::FPExt
>(
5486 /*SrcTy=*/Type::getFloatTy(C
), /*DstTy=*/Type::getDoubleTy(C
));
5489 TEST_F(SandboxIRTest
, UIToFPInst
) {
5491 define void @foo(i32 %arg) {
5492 %uitofp = uitofp i32 %arg to float
5496 testCastInst
<sandboxir::UIToFPInst
, sandboxir::Instruction::Opcode::UIToFP
>(
5498 /*SrcTy=*/Type::getInt32Ty(C
), /*DstTy=*/Type::getFloatTy(C
));
5501 TEST_F(SandboxIRTest
, SIToFPInst
) {
5503 define void @foo(i32 %arg) {
5504 %sitofp = sitofp i32 %arg to float
5508 testCastInst
<sandboxir::SIToFPInst
, sandboxir::Instruction::Opcode::SIToFP
>(
5510 /*SrcTy=*/Type::getInt32Ty(C
),
5511 /*DstTy=*/Type::getFloatTy(C
));
5514 TEST_F(SandboxIRTest
, FPToUIInst
) {
5516 define void @foo(float %arg) {
5517 %fptoui = fptoui float %arg to i32
5521 testCastInst
<sandboxir::FPToUIInst
, sandboxir::Instruction::Opcode::FPToUI
>(
5523 *M
, /*SrcTy=*/Type::getFloatTy(C
), /*DstTy=*/Type::getInt32Ty(C
));
5526 TEST_F(SandboxIRTest
, FPToSIInst
) {
5528 define void @foo(float %arg) {
5529 %fptosi = fptosi float %arg to i32
5533 testCastInst
<sandboxir::FPToSIInst
, sandboxir::Instruction::Opcode::FPToSI
>(
5534 *M
, /*SrcTy=*/Type::getFloatTy(C
), /*DstTy=*/Type::getInt32Ty(C
));
5537 TEST_F(SandboxIRTest
, IntToPtrInst
) {
5539 define void @foo(i32 %arg) {
5540 %inttoptr = inttoptr i32 %arg to ptr
5544 testCastInst
<sandboxir::IntToPtrInst
,
5545 sandboxir::Instruction::Opcode::IntToPtr
>(
5547 /*SrcTy=*/Type::getInt32Ty(C
), /*DstTy=*/PointerType::get(C
, 0));
5550 TEST_F(SandboxIRTest
, PtrToIntInst
) {
5552 define void @foo(ptr %ptr) {
5553 %ptrtoint = ptrtoint ptr %ptr to i32
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
) {
5564 define void @foo(i32 %arg) {
5565 %bitcast = bitcast i32 %arg to float
5569 testCastInst
<sandboxir::BitCastInst
, sandboxir::Instruction::Opcode::BitCast
>(
5571 /*SrcTy=*/Type::getInt32Ty(C
), /*DstTy=*/Type::getFloatTy(C
));
5574 TEST_F(SandboxIRTest
, AddrSpaceCastInst
) {
5576 define void @foo(ptr %ptr) {
5577 %addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1)
5581 Type
*Tptr0
= PointerType::get(C
, 0);
5582 Type
*Tptr1
= PointerType::get(C
, 1);
5583 testCastInst
<sandboxir::AddrSpaceCastInst
,
5584 sandboxir::Instruction::Opcode::AddrSpaceCast
>(*M
,
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
) {
5608 define void @foo(i32 %arg) {
5613 %phi = phi i32 [ %arg, %bb1 ], [ 0, %bb2 ], [ 1, %bb3 ], [ 2, %bb4 ], [ 3, %bb5 ]
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();
5641 auto *PHI
= cast
<sandboxir::PHINode
>(&*It
++);
5642 auto *Br
= cast
<sandboxir::BranchInst
>(&*It
++);
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
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
);
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");
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
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();
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());
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));
5852 EXPECT_EQ(NewCmp
->getName(), "NewCmp");
5854 // TODO: Improve this test when sandboxir::VectorType is more completely
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");
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
5883 %copyfrom = fadd reassoc float %f0, 42.0
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();
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));
5915 EXPECT_EQ(NewFCmp
->getName(), "NewFCmp");
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
,
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));
5929 EXPECT_EQ(NewFCmpFlags
->getName(), "NewFCmpFlags");
5933 TEST_F(SandboxIRTest
, UnreachableInst
) {
5935 define void @foo() {
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
) {
5968 define void @foo(ptr %ptr, i8 %val) {
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
*>>
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));
6000 Moved
.push_back(std::make_pair(I
, &*Where
));
6003 // Two more insertion callbacks, to check that they're called in registration
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); });
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.
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.
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());