1 //===- llvm/unittest/IR/IRBuilderTest.cpp - IRBuilder tests ---------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/IR/IRBuilder.h"
11 #include "llvm/IR/BasicBlock.h"
12 #include "llvm/IR/DataLayout.h"
13 #include "llvm/IR/DIBuilder.h"
14 #include "llvm/IR/Function.h"
15 #include "llvm/IR/IntrinsicInst.h"
16 #include "llvm/IR/LLVMContext.h"
17 #include "llvm/IR/MDBuilder.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/IR/NoFolder.h"
20 #include "llvm/IR/Verifier.h"
21 #include "gtest/gtest.h"
22 
23 using namespace llvm;
24 
25 namespace {
26 
27 class IRBuilderTest : public testing::Test {
28 protected:
SetUp()29   void SetUp() override {
30     M.reset(new Module("MyModule", Ctx));
31     FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
32                                           /*isVarArg=*/false);
33     F = Function::Create(FTy, Function::ExternalLinkage, "", M.get());
34     BB = BasicBlock::Create(Ctx, "", F);
35     GV = new GlobalVariable(*M, Type::getFloatTy(Ctx), true,
36                             GlobalValue::ExternalLinkage, nullptr);
37   }
38 
TearDown()39   void TearDown() override {
40     BB = nullptr;
41     M.reset();
42   }
43 
44   LLVMContext Ctx;
45   std::unique_ptr<Module> M;
46   Function *F;
47   BasicBlock *BB;
48   GlobalVariable *GV;
49 };
50 
TEST_F(IRBuilderTest,Lifetime)51 TEST_F(IRBuilderTest, Lifetime) {
52   IRBuilder<> Builder(BB);
53   AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty());
54   AllocaInst *Var2 = Builder.CreateAlloca(Builder.getInt32Ty());
55   AllocaInst *Var3 = Builder.CreateAlloca(Builder.getInt8Ty(),
56                                           Builder.getInt32(123));
57 
58   CallInst *Start1 = Builder.CreateLifetimeStart(Var1);
59   CallInst *Start2 = Builder.CreateLifetimeStart(Var2);
60   CallInst *Start3 = Builder.CreateLifetimeStart(Var3, Builder.getInt64(100));
61 
62   EXPECT_EQ(Start1->getArgOperand(0), Builder.getInt64(-1));
63   EXPECT_EQ(Start2->getArgOperand(0), Builder.getInt64(-1));
64   EXPECT_EQ(Start3->getArgOperand(0), Builder.getInt64(100));
65 
66   EXPECT_EQ(Start1->getArgOperand(1), Var1);
67   EXPECT_NE(Start2->getArgOperand(1), Var2);
68   EXPECT_EQ(Start3->getArgOperand(1), Var3);
69 
70   Value *End1 = Builder.CreateLifetimeEnd(Var1);
71   Builder.CreateLifetimeEnd(Var2);
72   Builder.CreateLifetimeEnd(Var3);
73 
74   IntrinsicInst *II_Start1 = dyn_cast<IntrinsicInst>(Start1);
75   IntrinsicInst *II_End1 = dyn_cast<IntrinsicInst>(End1);
76   ASSERT_TRUE(II_Start1 != nullptr);
77   EXPECT_EQ(II_Start1->getIntrinsicID(), Intrinsic::lifetime_start);
78   ASSERT_TRUE(II_End1 != nullptr);
79   EXPECT_EQ(II_End1->getIntrinsicID(), Intrinsic::lifetime_end);
80 }
81 
TEST_F(IRBuilderTest,CreateCondBr)82 TEST_F(IRBuilderTest, CreateCondBr) {
83   IRBuilder<> Builder(BB);
84   BasicBlock *TBB = BasicBlock::Create(Ctx, "", F);
85   BasicBlock *FBB = BasicBlock::Create(Ctx, "", F);
86 
87   BranchInst *BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
88   TerminatorInst *TI = BB->getTerminator();
89   EXPECT_EQ(BI, TI);
90   EXPECT_EQ(2u, TI->getNumSuccessors());
91   EXPECT_EQ(TBB, TI->getSuccessor(0));
92   EXPECT_EQ(FBB, TI->getSuccessor(1));
93 
94   BI->eraseFromParent();
95   MDNode *Weights = MDBuilder(Ctx).createBranchWeights(42, 13);
96   BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB, Weights);
97   TI = BB->getTerminator();
98   EXPECT_EQ(BI, TI);
99   EXPECT_EQ(2u, TI->getNumSuccessors());
100   EXPECT_EQ(TBB, TI->getSuccessor(0));
101   EXPECT_EQ(FBB, TI->getSuccessor(1));
102   EXPECT_EQ(Weights, TI->getMetadata(LLVMContext::MD_prof));
103 }
104 
TEST_F(IRBuilderTest,LandingPadName)105 TEST_F(IRBuilderTest, LandingPadName) {
106   IRBuilder<> Builder(BB);
107   LandingPadInst *LP = Builder.CreateLandingPad(Builder.getInt32Ty(),
108                                                 Builder.getInt32(0), 0, "LP");
109   EXPECT_EQ(LP->getName(), "LP");
110 }
111 
TEST_F(IRBuilderTest,DataLayout)112 TEST_F(IRBuilderTest, DataLayout) {
113   std::unique_ptr<Module> M(new Module("test", Ctx));
114   M->setDataLayout("e-n32");
115   EXPECT_TRUE(M->getDataLayout().isLegalInteger(32));
116   M->setDataLayout("e");
117   EXPECT_FALSE(M->getDataLayout().isLegalInteger(32));
118 }
119 
TEST_F(IRBuilderTest,GetIntTy)120 TEST_F(IRBuilderTest, GetIntTy) {
121   IRBuilder<> Builder(BB);
122   IntegerType *Ty1 = Builder.getInt1Ty();
123   EXPECT_EQ(Ty1, IntegerType::get(Ctx, 1));
124 
125   DataLayout* DL = new DataLayout(M.get());
126   IntegerType *IntPtrTy = Builder.getIntPtrTy(*DL);
127   unsigned IntPtrBitSize =  DL->getPointerSizeInBits(0);
128   EXPECT_EQ(IntPtrTy, IntegerType::get(Ctx, IntPtrBitSize));
129   delete DL;
130 }
131 
TEST_F(IRBuilderTest,FastMathFlags)132 TEST_F(IRBuilderTest, FastMathFlags) {
133   IRBuilder<> Builder(BB);
134   Value *F;
135   Instruction *FDiv, *FAdd;
136 
137   F = Builder.CreateLoad(GV);
138   F = Builder.CreateFAdd(F, F);
139 
140   EXPECT_FALSE(Builder.getFastMathFlags().any());
141   ASSERT_TRUE(isa<Instruction>(F));
142   FAdd = cast<Instruction>(F);
143   EXPECT_FALSE(FAdd->hasNoNaNs());
144 
145   FastMathFlags FMF;
146   Builder.SetFastMathFlags(FMF);
147 
148   F = Builder.CreateFAdd(F, F);
149   EXPECT_FALSE(Builder.getFastMathFlags().any());
150 
151   FMF.setUnsafeAlgebra();
152   Builder.SetFastMathFlags(FMF);
153 
154   F = Builder.CreateFAdd(F, F);
155   EXPECT_TRUE(Builder.getFastMathFlags().any());
156   ASSERT_TRUE(isa<Instruction>(F));
157   FAdd = cast<Instruction>(F);
158   EXPECT_TRUE(FAdd->hasNoNaNs());
159 
160   // Now, try it with CreateBinOp
161   F = Builder.CreateBinOp(Instruction::FAdd, F, F);
162   EXPECT_TRUE(Builder.getFastMathFlags().any());
163   ASSERT_TRUE(isa<Instruction>(F));
164   FAdd = cast<Instruction>(F);
165   EXPECT_TRUE(FAdd->hasNoNaNs());
166 
167   F = Builder.CreateFDiv(F, F);
168   EXPECT_TRUE(Builder.getFastMathFlags().any());
169   EXPECT_TRUE(Builder.getFastMathFlags().UnsafeAlgebra);
170   ASSERT_TRUE(isa<Instruction>(F));
171   FDiv = cast<Instruction>(F);
172   EXPECT_TRUE(FDiv->hasAllowReciprocal());
173 
174   Builder.clearFastMathFlags();
175 
176   F = Builder.CreateFDiv(F, F);
177   ASSERT_TRUE(isa<Instruction>(F));
178   FDiv = cast<Instruction>(F);
179   EXPECT_FALSE(FDiv->hasAllowReciprocal());
180 
181   FMF.clear();
182   FMF.setAllowReciprocal();
183   Builder.SetFastMathFlags(FMF);
184 
185   F = Builder.CreateFDiv(F, F);
186   EXPECT_TRUE(Builder.getFastMathFlags().any());
187   EXPECT_TRUE(Builder.getFastMathFlags().AllowReciprocal);
188   ASSERT_TRUE(isa<Instruction>(F));
189   FDiv = cast<Instruction>(F);
190   EXPECT_TRUE(FDiv->hasAllowReciprocal());
191 
192   Builder.clearFastMathFlags();
193 
194   // To test a copy, make sure that a '0' and a '1' change state.
195   F = Builder.CreateFDiv(F, F);
196   ASSERT_TRUE(isa<Instruction>(F));
197   FDiv = cast<Instruction>(F);
198   EXPECT_FALSE(FDiv->getFastMathFlags().any());
199   FDiv->setHasAllowReciprocal(true);
200   FAdd->setHasAllowReciprocal(false);
201   FDiv->copyFastMathFlags(FAdd);
202   EXPECT_TRUE(FDiv->hasNoNaNs());
203   EXPECT_FALSE(FDiv->hasAllowReciprocal());
204 
205 }
206 
TEST_F(IRBuilderTest,WrapFlags)207 TEST_F(IRBuilderTest, WrapFlags) {
208   IRBuilder<true, NoFolder> Builder(BB);
209 
210   // Test instructions.
211   GlobalVariable *G = new GlobalVariable(*M, Builder.getInt32Ty(), true,
212                                          GlobalValue::ExternalLinkage, nullptr);
213   Value *V = Builder.CreateLoad(G);
214   EXPECT_TRUE(
215       cast<BinaryOperator>(Builder.CreateNSWAdd(V, V))->hasNoSignedWrap());
216   EXPECT_TRUE(
217       cast<BinaryOperator>(Builder.CreateNSWMul(V, V))->hasNoSignedWrap());
218   EXPECT_TRUE(
219       cast<BinaryOperator>(Builder.CreateNSWSub(V, V))->hasNoSignedWrap());
220   EXPECT_TRUE(cast<BinaryOperator>(
221                   Builder.CreateShl(V, V, "", /* NUW */ false, /* NSW */ true))
222                   ->hasNoSignedWrap());
223 
224   EXPECT_TRUE(
225       cast<BinaryOperator>(Builder.CreateNUWAdd(V, V))->hasNoUnsignedWrap());
226   EXPECT_TRUE(
227       cast<BinaryOperator>(Builder.CreateNUWMul(V, V))->hasNoUnsignedWrap());
228   EXPECT_TRUE(
229       cast<BinaryOperator>(Builder.CreateNUWSub(V, V))->hasNoUnsignedWrap());
230   EXPECT_TRUE(cast<BinaryOperator>(
231                   Builder.CreateShl(V, V, "", /* NUW */ true, /* NSW */ false))
232                   ->hasNoUnsignedWrap());
233 
234   // Test operators created with constants.
235   Constant *C = Builder.getInt32(42);
236   EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWAdd(C, C))
237                   ->hasNoSignedWrap());
238   EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWSub(C, C))
239                   ->hasNoSignedWrap());
240   EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWMul(C, C))
241                   ->hasNoSignedWrap());
242   EXPECT_TRUE(cast<OverflowingBinaryOperator>(
243                   Builder.CreateShl(C, C, "", /* NUW */ false, /* NSW */ true))
244                   ->hasNoSignedWrap());
245 
246   EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWAdd(C, C))
247                   ->hasNoUnsignedWrap());
248   EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWSub(C, C))
249                   ->hasNoUnsignedWrap());
250   EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWMul(C, C))
251                   ->hasNoUnsignedWrap());
252   EXPECT_TRUE(cast<OverflowingBinaryOperator>(
253                   Builder.CreateShl(C, C, "", /* NUW */ true, /* NSW */ false))
254                   ->hasNoUnsignedWrap());
255 }
256 
TEST_F(IRBuilderTest,RAIIHelpersTest)257 TEST_F(IRBuilderTest, RAIIHelpersTest) {
258   IRBuilder<> Builder(BB);
259   EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
260   MDBuilder MDB(M->getContext());
261 
262   MDNode *FPMathA = MDB.createFPMath(0.01f);
263   MDNode *FPMathB = MDB.createFPMath(0.1f);
264 
265   Builder.SetDefaultFPMathTag(FPMathA);
266 
267   {
268     IRBuilder<>::FastMathFlagGuard Guard(Builder);
269     FastMathFlags FMF;
270     FMF.setAllowReciprocal();
271     Builder.SetFastMathFlags(FMF);
272     Builder.SetDefaultFPMathTag(FPMathB);
273     EXPECT_TRUE(Builder.getFastMathFlags().allowReciprocal());
274     EXPECT_EQ(FPMathB, Builder.getDefaultFPMathTag());
275   }
276 
277   EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
278   EXPECT_EQ(FPMathA, Builder.getDefaultFPMathTag());
279 
280   Value *F = Builder.CreateLoad(GV);
281 
282   {
283     IRBuilder<>::InsertPointGuard Guard(Builder);
284     Builder.SetInsertPoint(cast<Instruction>(F));
285     EXPECT_EQ(F, Builder.GetInsertPoint());
286   }
287 
288   EXPECT_EQ(BB->end(), Builder.GetInsertPoint());
289   EXPECT_EQ(BB, Builder.GetInsertBlock());
290 }
291 
TEST_F(IRBuilderTest,DIBuilder)292 TEST_F(IRBuilderTest, DIBuilder) {
293   IRBuilder<> Builder(BB);
294   DIBuilder DIB(*M);
295   auto File = DIB.createFile("F.CBL", "/");
296   auto CU = DIB.createCompileUnit(dwarf::DW_LANG_Cobol74, "F.CBL", "/",
297                                   "llvm-cobol74", true, "", 0);
298   auto Type = DIB.createSubroutineType(File, DIB.getOrCreateTypeArray(None));
299   DIB.createFunction(CU, "foo", "", File, 1, Type, false, true, 1, 0, true, F);
300   AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty());
301   auto BarSP = DIB.createFunction(CU, "bar", "", File, 1, Type, false, true, 1,
302                                   0, true, nullptr);
303   auto BadScope = DIB.createLexicalBlockFile(BarSP, File, 0);
304   I->setDebugLoc(DebugLoc::get(2, 0, BadScope));
305   DIB.finalize();
306   EXPECT_TRUE(verifyModule(*M));
307 }
308 
309 
310 }
311