1 //===- llvm/unittest/IR/IRBuilderTest.cpp - IRBuilder tests ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/IR/IRBuilder.h"
11 #include "llvm/IR/BasicBlock.h"
12 #include "llvm/IR/DataLayout.h"
13 #include "llvm/IR/Function.h"
14 #include "llvm/IR/IntrinsicInst.h"
15 #include "llvm/IR/LLVMContext.h"
16 #include "llvm/IR/MDBuilder.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/IR/NoFolder.h"
19 #include "gtest/gtest.h"
25 class IRBuilderTest
: public testing::Test
{
27 virtual void SetUp() {
28 M
.reset(new Module("MyModule", Ctx
));
29 FunctionType
*FTy
= FunctionType::get(Type::getVoidTy(Ctx
),
31 F
= Function::Create(FTy
, Function::ExternalLinkage
, "", M
.get());
32 BB
= BasicBlock::Create(Ctx
, "", F
);
33 GV
= new GlobalVariable(*M
, Type::getFloatTy(Ctx
), true,
34 GlobalValue::ExternalLinkage
, nullptr);
37 virtual void TearDown() {
43 std::unique_ptr
<Module
> M
;
49 TEST_F(IRBuilderTest
, Lifetime
) {
50 IRBuilder
<> Builder(BB
);
51 AllocaInst
*Var1
= Builder
.CreateAlloca(Builder
.getInt8Ty());
52 AllocaInst
*Var2
= Builder
.CreateAlloca(Builder
.getInt32Ty());
53 AllocaInst
*Var3
= Builder
.CreateAlloca(Builder
.getInt8Ty(),
54 Builder
.getInt32(123));
56 CallInst
*Start1
= Builder
.CreateLifetimeStart(Var1
);
57 CallInst
*Start2
= Builder
.CreateLifetimeStart(Var2
);
58 CallInst
*Start3
= Builder
.CreateLifetimeStart(Var3
, Builder
.getInt64(100));
60 EXPECT_EQ(Start1
->getArgOperand(0), Builder
.getInt64(-1));
61 EXPECT_EQ(Start2
->getArgOperand(0), Builder
.getInt64(-1));
62 EXPECT_EQ(Start3
->getArgOperand(0), Builder
.getInt64(100));
64 EXPECT_EQ(Start1
->getArgOperand(1), Var1
);
65 EXPECT_NE(Start2
->getArgOperand(1), Var2
);
66 EXPECT_EQ(Start3
->getArgOperand(1), Var3
);
68 Value
*End1
= Builder
.CreateLifetimeEnd(Var1
);
69 Builder
.CreateLifetimeEnd(Var2
);
70 Builder
.CreateLifetimeEnd(Var3
);
72 IntrinsicInst
*II_Start1
= dyn_cast
<IntrinsicInst
>(Start1
);
73 IntrinsicInst
*II_End1
= dyn_cast
<IntrinsicInst
>(End1
);
74 ASSERT_TRUE(II_Start1
!= nullptr);
75 EXPECT_EQ(II_Start1
->getIntrinsicID(), Intrinsic::lifetime_start
);
76 ASSERT_TRUE(II_End1
!= nullptr);
77 EXPECT_EQ(II_End1
->getIntrinsicID(), Intrinsic::lifetime_end
);
80 TEST_F(IRBuilderTest
, CreateCondBr
) {
81 IRBuilder
<> Builder(BB
);
82 BasicBlock
*TBB
= BasicBlock::Create(Ctx
, "", F
);
83 BasicBlock
*FBB
= BasicBlock::Create(Ctx
, "", F
);
85 BranchInst
*BI
= Builder
.CreateCondBr(Builder
.getTrue(), TBB
, FBB
);
86 TerminatorInst
*TI
= BB
->getTerminator();
88 EXPECT_EQ(2u, TI
->getNumSuccessors());
89 EXPECT_EQ(TBB
, TI
->getSuccessor(0));
90 EXPECT_EQ(FBB
, TI
->getSuccessor(1));
92 BI
->eraseFromParent();
93 MDNode
*Weights
= MDBuilder(Ctx
).createBranchWeights(42, 13);
94 BI
= Builder
.CreateCondBr(Builder
.getTrue(), TBB
, FBB
, Weights
);
95 TI
= BB
->getTerminator();
97 EXPECT_EQ(2u, TI
->getNumSuccessors());
98 EXPECT_EQ(TBB
, TI
->getSuccessor(0));
99 EXPECT_EQ(FBB
, TI
->getSuccessor(1));
100 EXPECT_EQ(Weights
, TI
->getMetadata(LLVMContext::MD_prof
));
103 TEST_F(IRBuilderTest
, LandingPadName
) {
104 IRBuilder
<> Builder(BB
);
105 LandingPadInst
*LP
= Builder
.CreateLandingPad(Builder
.getInt32Ty(),
106 Builder
.getInt32(0), 0, "LP");
107 EXPECT_EQ(LP
->getName(), "LP");
110 TEST_F(IRBuilderTest
, DataLayout
) {
111 std::unique_ptr
<Module
> M(new Module("test", Ctx
));
112 M
->setDataLayout("e-n32");
113 EXPECT_TRUE(M
->getDataLayout()->isLegalInteger(32));
114 M
->setDataLayout("e");
115 EXPECT_FALSE(M
->getDataLayout()->isLegalInteger(32));
118 TEST_F(IRBuilderTest
, GetIntTy
) {
119 IRBuilder
<> Builder(BB
);
120 IntegerType
*Ty1
= Builder
.getInt1Ty();
121 EXPECT_EQ(Ty1
, IntegerType::get(Ctx
, 1));
123 DataLayout
* DL
= new DataLayout(M
.get());
124 IntegerType
*IntPtrTy
= Builder
.getIntPtrTy(DL
);
125 unsigned IntPtrBitSize
= DL
->getPointerSizeInBits(0);
126 EXPECT_EQ(IntPtrTy
, IntegerType::get(Ctx
, IntPtrBitSize
));
130 TEST_F(IRBuilderTest
, FastMathFlags
) {
131 IRBuilder
<> Builder(BB
);
133 Instruction
*FDiv
, *FAdd
;
135 F
= Builder
.CreateLoad(GV
);
136 F
= Builder
.CreateFAdd(F
, F
);
138 EXPECT_FALSE(Builder
.getFastMathFlags().any());
139 ASSERT_TRUE(isa
<Instruction
>(F
));
140 FAdd
= cast
<Instruction
>(F
);
141 EXPECT_FALSE(FAdd
->hasNoNaNs());
144 Builder
.SetFastMathFlags(FMF
);
146 F
= Builder
.CreateFAdd(F
, F
);
147 EXPECT_FALSE(Builder
.getFastMathFlags().any());
149 FMF
.setUnsafeAlgebra();
150 Builder
.SetFastMathFlags(FMF
);
152 F
= Builder
.CreateFAdd(F
, F
);
153 EXPECT_TRUE(Builder
.getFastMathFlags().any());
154 ASSERT_TRUE(isa
<Instruction
>(F
));
155 FAdd
= cast
<Instruction
>(F
);
156 EXPECT_TRUE(FAdd
->hasNoNaNs());
158 // Now, try it with CreateBinOp
159 F
= Builder
.CreateBinOp(Instruction::FAdd
, F
, F
);
160 EXPECT_TRUE(Builder
.getFastMathFlags().any());
161 ASSERT_TRUE(isa
<Instruction
>(F
));
162 FAdd
= cast
<Instruction
>(F
);
163 EXPECT_TRUE(FAdd
->hasNoNaNs());
165 F
= Builder
.CreateFDiv(F
, F
);
166 EXPECT_TRUE(Builder
.getFastMathFlags().any());
167 EXPECT_TRUE(Builder
.getFastMathFlags().UnsafeAlgebra
);
168 ASSERT_TRUE(isa
<Instruction
>(F
));
169 FDiv
= cast
<Instruction
>(F
);
170 EXPECT_TRUE(FDiv
->hasAllowReciprocal());
172 Builder
.clearFastMathFlags();
174 F
= Builder
.CreateFDiv(F
, F
);
175 ASSERT_TRUE(isa
<Instruction
>(F
));
176 FDiv
= cast
<Instruction
>(F
);
177 EXPECT_FALSE(FDiv
->hasAllowReciprocal());
180 FMF
.setAllowReciprocal();
181 Builder
.SetFastMathFlags(FMF
);
183 F
= Builder
.CreateFDiv(F
, F
);
184 EXPECT_TRUE(Builder
.getFastMathFlags().any());
185 EXPECT_TRUE(Builder
.getFastMathFlags().AllowReciprocal
);
186 ASSERT_TRUE(isa
<Instruction
>(F
));
187 FDiv
= cast
<Instruction
>(F
);
188 EXPECT_TRUE(FDiv
->hasAllowReciprocal());
190 Builder
.clearFastMathFlags();
192 // To test a copy, make sure that a '0' and a '1' change state.
193 F
= Builder
.CreateFDiv(F
, F
);
194 ASSERT_TRUE(isa
<Instruction
>(F
));
195 FDiv
= cast
<Instruction
>(F
);
196 EXPECT_FALSE(FDiv
->getFastMathFlags().any());
197 FDiv
->setHasAllowReciprocal(true);
198 FAdd
->setHasAllowReciprocal(false);
199 FDiv
->copyFastMathFlags(FAdd
);
200 EXPECT_TRUE(FDiv
->hasNoNaNs());
201 EXPECT_FALSE(FDiv
->hasAllowReciprocal());
205 TEST_F(IRBuilderTest
, WrapFlags
) {
206 IRBuilder
<true, NoFolder
> Builder(BB
);
208 // Test instructions.
209 GlobalVariable
*G
= new GlobalVariable(*M
, Builder
.getInt32Ty(), true,
210 GlobalValue::ExternalLinkage
, nullptr);
211 Value
*V
= Builder
.CreateLoad(G
);
213 cast
<BinaryOperator
>(Builder
.CreateNSWAdd(V
, V
))->hasNoSignedWrap());
215 cast
<BinaryOperator
>(Builder
.CreateNSWMul(V
, V
))->hasNoSignedWrap());
217 cast
<BinaryOperator
>(Builder
.CreateNSWSub(V
, V
))->hasNoSignedWrap());
218 EXPECT_TRUE(cast
<BinaryOperator
>(
219 Builder
.CreateShl(V
, V
, "", /* NUW */ false, /* NSW */ true))
220 ->hasNoSignedWrap());
223 cast
<BinaryOperator
>(Builder
.CreateNUWAdd(V
, V
))->hasNoUnsignedWrap());
225 cast
<BinaryOperator
>(Builder
.CreateNUWMul(V
, V
))->hasNoUnsignedWrap());
227 cast
<BinaryOperator
>(Builder
.CreateNUWSub(V
, V
))->hasNoUnsignedWrap());
228 EXPECT_TRUE(cast
<BinaryOperator
>(
229 Builder
.CreateShl(V
, V
, "", /* NUW */ true, /* NSW */ false))
230 ->hasNoUnsignedWrap());
232 // Test operators created with constants.
233 Constant
*C
= Builder
.getInt32(42);
234 EXPECT_TRUE(cast
<OverflowingBinaryOperator
>(Builder
.CreateNSWAdd(C
, C
))
235 ->hasNoSignedWrap());
236 EXPECT_TRUE(cast
<OverflowingBinaryOperator
>(Builder
.CreateNSWSub(C
, C
))
237 ->hasNoSignedWrap());
238 EXPECT_TRUE(cast
<OverflowingBinaryOperator
>(Builder
.CreateNSWMul(C
, C
))
239 ->hasNoSignedWrap());
240 EXPECT_TRUE(cast
<OverflowingBinaryOperator
>(
241 Builder
.CreateShl(C
, C
, "", /* NUW */ false, /* NSW */ true))
242 ->hasNoSignedWrap());
244 EXPECT_TRUE(cast
<OverflowingBinaryOperator
>(Builder
.CreateNUWAdd(C
, C
))
245 ->hasNoUnsignedWrap());
246 EXPECT_TRUE(cast
<OverflowingBinaryOperator
>(Builder
.CreateNUWSub(C
, C
))
247 ->hasNoUnsignedWrap());
248 EXPECT_TRUE(cast
<OverflowingBinaryOperator
>(Builder
.CreateNUWMul(C
, C
))
249 ->hasNoUnsignedWrap());
250 EXPECT_TRUE(cast
<OverflowingBinaryOperator
>(
251 Builder
.CreateShl(C
, C
, "", /* NUW */ true, /* NSW */ false))
252 ->hasNoUnsignedWrap());
255 TEST_F(IRBuilderTest
, RAIIHelpersTest
) {
256 IRBuilder
<> Builder(BB
);
257 EXPECT_FALSE(Builder
.getFastMathFlags().allowReciprocal());
258 MDBuilder
MDB(M
->getContext());
260 MDNode
*FPMathA
= MDB
.createFPMath(0.01f
);
261 MDNode
*FPMathB
= MDB
.createFPMath(0.1f
);
263 Builder
.SetDefaultFPMathTag(FPMathA
);
266 IRBuilder
<>::FastMathFlagGuard
Guard(Builder
);
268 FMF
.setAllowReciprocal();
269 Builder
.SetFastMathFlags(FMF
);
270 Builder
.SetDefaultFPMathTag(FPMathB
);
271 EXPECT_TRUE(Builder
.getFastMathFlags().allowReciprocal());
272 EXPECT_EQ(FPMathB
, Builder
.getDefaultFPMathTag());
275 EXPECT_FALSE(Builder
.getFastMathFlags().allowReciprocal());
276 EXPECT_EQ(FPMathA
, Builder
.getDefaultFPMathTag());
278 Value
*F
= Builder
.CreateLoad(GV
);
281 IRBuilder
<>::InsertPointGuard
Guard(Builder
);
282 Builder
.SetInsertPoint(cast
<Instruction
>(F
));
283 EXPECT_EQ(F
, Builder
.GetInsertPoint());
286 EXPECT_EQ(BB
->end(), Builder
.GetInsertPoint());
287 EXPECT_EQ(BB
, Builder
.GetInsertBlock());