1c779e96158cbac4c62df8e2053ab6a933eba5868Chandler Carruth//===- llvm/unittest/IR/IRBuilderTest.cpp - IRBuilder tests ---------------===//
20cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky//
30cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky//                     The LLVM Compiler Infrastructure
40cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky//
50cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky// This file is distributed under the University of Illinois Open Source
60cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky// License. See LICENSE.TXT for details.
70cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky//
80cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky//===----------------------------------------------------------------------===//
90cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky
100b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IRBuilder.h"
110b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/BasicBlock.h"
120b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h"
13ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/DIBuilder.h"
140b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
150b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IntrinsicInst.h"
160b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h"
170b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/MDBuilder.h"
180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h"
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/NoFolder.h"
202c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar#include "llvm/IR/Verifier.h"
210cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky#include "gtest/gtest.h"
220cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky
230cf51561eddd659a7b427f40144e22363fd95a57Nick Lewyckyusing namespace llvm;
240cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky
252d24e2a396a1d211baaeedf32148a3b657240170David Blaikienamespace {
261880e2d34458f67a92e26953c257f2feb334ceefChandler Carruth
270cf51561eddd659a7b427f40144e22363fd95a57Nick Lewyckyclass IRBuilderTest : public testing::Test {
280cf51561eddd659a7b427f40144e22363fd95a57Nick Lewyckyprotected:
292c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  void SetUp() override {
304da02d43b1981f8be6f3b64ae42161fb3f918a8dBenjamin Kramer    M.reset(new Module("MyModule", Ctx));
314da02d43b1981f8be6f3b64ae42161fb3f918a8dBenjamin Kramer    FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
320cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky                                          /*isVarArg=*/false);
334b31c4d93ff23c4b9a5d9169ff5e6f51731fca17Chandler Carruth    F = Function::Create(FTy, Function::ExternalLinkage, "", M.get());
344da02d43b1981f8be6f3b64ae42161fb3f918a8dBenjamin Kramer    BB = BasicBlock::Create(Ctx, "", F);
354da02d43b1981f8be6f3b64ae42161fb3f918a8dBenjamin Kramer    GV = new GlobalVariable(*M, Type::getFloatTy(Ctx), true,
36c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                            GlobalValue::ExternalLinkage, nullptr);
370cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  }
380cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky
392c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  void TearDown() override {
40c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    BB = nullptr;
410cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky    M.reset();
420cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  }
430cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky
444da02d43b1981f8be6f3b64ae42161fb3f918a8dBenjamin Kramer  LLVMContext Ctx;
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<Module> M;
464b31c4d93ff23c4b9a5d9169ff5e6f51731fca17Chandler Carruth  Function *F;
470cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  BasicBlock *BB;
48f564e9ff2d3327dc122f55b8037da6d688a7deb4Michael Ilseman  GlobalVariable *GV;
490cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky};
500cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky
510cf51561eddd659a7b427f40144e22363fd95a57Nick LewyckyTEST_F(IRBuilderTest, Lifetime) {
520cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  IRBuilder<> Builder(BB);
530cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty());
540cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  AllocaInst *Var2 = Builder.CreateAlloca(Builder.getInt32Ty());
550cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  AllocaInst *Var3 = Builder.CreateAlloca(Builder.getInt8Ty(),
560cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky                                          Builder.getInt32(123));
570cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky
580cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  CallInst *Start1 = Builder.CreateLifetimeStart(Var1);
590cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  CallInst *Start2 = Builder.CreateLifetimeStart(Var2);
600cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  CallInst *Start3 = Builder.CreateLifetimeStart(Var3, Builder.getInt64(100));
610cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky
620cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  EXPECT_EQ(Start1->getArgOperand(0), Builder.getInt64(-1));
630cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  EXPECT_EQ(Start2->getArgOperand(0), Builder.getInt64(-1));
640cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  EXPECT_EQ(Start3->getArgOperand(0), Builder.getInt64(100));
650cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky
660cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  EXPECT_EQ(Start1->getArgOperand(1), Var1);
670cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  EXPECT_NE(Start2->getArgOperand(1), Var2);
680cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  EXPECT_EQ(Start3->getArgOperand(1), Var3);
690cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky
700cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  Value *End1 = Builder.CreateLifetimeEnd(Var1);
710cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  Builder.CreateLifetimeEnd(Var2);
720cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  Builder.CreateLifetimeEnd(Var3);
730cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky
740cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  IntrinsicInst *II_Start1 = dyn_cast<IntrinsicInst>(Start1);
750cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  IntrinsicInst *II_End1 = dyn_cast<IntrinsicInst>(End1);
76c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  ASSERT_TRUE(II_Start1 != nullptr);
770cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  EXPECT_EQ(II_Start1->getIntrinsicID(), Intrinsic::lifetime_start);
78c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  ASSERT_TRUE(II_End1 != nullptr);
790cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  EXPECT_EQ(II_End1->getIntrinsicID(), Intrinsic::lifetime_end);
800cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky}
811880e2d34458f67a92e26953c257f2feb334ceefChandler Carruth
824b31c4d93ff23c4b9a5d9169ff5e6f51731fca17Chandler CarruthTEST_F(IRBuilderTest, CreateCondBr) {
834b31c4d93ff23c4b9a5d9169ff5e6f51731fca17Chandler Carruth  IRBuilder<> Builder(BB);
844da02d43b1981f8be6f3b64ae42161fb3f918a8dBenjamin Kramer  BasicBlock *TBB = BasicBlock::Create(Ctx, "", F);
854da02d43b1981f8be6f3b64ae42161fb3f918a8dBenjamin Kramer  BasicBlock *FBB = BasicBlock::Create(Ctx, "", F);
864b31c4d93ff23c4b9a5d9169ff5e6f51731fca17Chandler Carruth
874b31c4d93ff23c4b9a5d9169ff5e6f51731fca17Chandler Carruth  BranchInst *BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
884b31c4d93ff23c4b9a5d9169ff5e6f51731fca17Chandler Carruth  TerminatorInst *TI = BB->getTerminator();
894b31c4d93ff23c4b9a5d9169ff5e6f51731fca17Chandler Carruth  EXPECT_EQ(BI, TI);
904b31c4d93ff23c4b9a5d9169ff5e6f51731fca17Chandler Carruth  EXPECT_EQ(2u, TI->getNumSuccessors());
914b31c4d93ff23c4b9a5d9169ff5e6f51731fca17Chandler Carruth  EXPECT_EQ(TBB, TI->getSuccessor(0));
924b31c4d93ff23c4b9a5d9169ff5e6f51731fca17Chandler Carruth  EXPECT_EQ(FBB, TI->getSuccessor(1));
93299493720382ab26e0842eca233fd240dce3b3d6Chandler Carruth
94299493720382ab26e0842eca233fd240dce3b3d6Chandler Carruth  BI->eraseFromParent();
954da02d43b1981f8be6f3b64ae42161fb3f918a8dBenjamin Kramer  MDNode *Weights = MDBuilder(Ctx).createBranchWeights(42, 13);
96299493720382ab26e0842eca233fd240dce3b3d6Chandler Carruth  BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB, Weights);
97299493720382ab26e0842eca233fd240dce3b3d6Chandler Carruth  TI = BB->getTerminator();
98299493720382ab26e0842eca233fd240dce3b3d6Chandler Carruth  EXPECT_EQ(BI, TI);
99299493720382ab26e0842eca233fd240dce3b3d6Chandler Carruth  EXPECT_EQ(2u, TI->getNumSuccessors());
100299493720382ab26e0842eca233fd240dce3b3d6Chandler Carruth  EXPECT_EQ(TBB, TI->getSuccessor(0));
101299493720382ab26e0842eca233fd240dce3b3d6Chandler Carruth  EXPECT_EQ(FBB, TI->getSuccessor(1));
102299493720382ab26e0842eca233fd240dce3b3d6Chandler Carruth  EXPECT_EQ(Weights, TI->getMetadata(LLVMContext::MD_prof));
1034b31c4d93ff23c4b9a5d9169ff5e6f51731fca17Chandler Carruth}
1044b31c4d93ff23c4b9a5d9169ff5e6f51731fca17Chandler Carruth
1056e591ea0b9759ffae3abafb2d55b8d30a20e98f2Duncan SandsTEST_F(IRBuilderTest, LandingPadName) {
1066e591ea0b9759ffae3abafb2d55b8d30a20e98f2Duncan Sands  IRBuilder<> Builder(BB);
1076e591ea0b9759ffae3abafb2d55b8d30a20e98f2Duncan Sands  LandingPadInst *LP = Builder.CreateLandingPad(Builder.getInt32Ty(),
1086e591ea0b9759ffae3abafb2d55b8d30a20e98f2Duncan Sands                                                Builder.getInt32(0), 0, "LP");
1096e591ea0b9759ffae3abafb2d55b8d30a20e98f2Duncan Sands  EXPECT_EQ(LP->getName(), "LP");
1106e591ea0b9759ffae3abafb2d55b8d30a20e98f2Duncan Sands}
1116e591ea0b9759ffae3abafb2d55b8d30a20e98f2Duncan Sands
11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesTEST_F(IRBuilderTest, DataLayout) {
11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<Module> M(new Module("test", Ctx));
11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  M->setDataLayout("e-n32");
1154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  EXPECT_TRUE(M->getDataLayout().isLegalInteger(32));
11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  M->setDataLayout("e");
1174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  EXPECT_FALSE(M->getDataLayout().isLegalInteger(32));
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1200ceb855d5251c67c3a129c172a520c1d2682c344Evgeniy StepanovTEST_F(IRBuilderTest, GetIntTy) {
1210ceb855d5251c67c3a129c172a520c1d2682c344Evgeniy Stepanov  IRBuilder<> Builder(BB);
1220ceb855d5251c67c3a129c172a520c1d2682c344Evgeniy Stepanov  IntegerType *Ty1 = Builder.getInt1Ty();
1234da02d43b1981f8be6f3b64ae42161fb3f918a8dBenjamin Kramer  EXPECT_EQ(Ty1, IntegerType::get(Ctx, 1));
1240ceb855d5251c67c3a129c172a520c1d2682c344Evgeniy Stepanov
1250ceb855d5251c67c3a129c172a520c1d2682c344Evgeniy Stepanov  DataLayout* DL = new DataLayout(M.get());
1264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  IntegerType *IntPtrTy = Builder.getIntPtrTy(*DL);
1270ceb855d5251c67c3a129c172a520c1d2682c344Evgeniy Stepanov  unsigned IntPtrBitSize =  DL->getPointerSizeInBits(0);
1284da02d43b1981f8be6f3b64ae42161fb3f918a8dBenjamin Kramer  EXPECT_EQ(IntPtrTy, IntegerType::get(Ctx, IntPtrBitSize));
129e82a5fae0309eee5a253e84b77f84525bdcbf111NAKAMURA Takumi  delete DL;
1300ceb855d5251c67c3a129c172a520c1d2682c344Evgeniy Stepanov}
1310ceb855d5251c67c3a129c172a520c1d2682c344Evgeniy Stepanov
132f564e9ff2d3327dc122f55b8037da6d688a7deb4Michael IlsemanTEST_F(IRBuilderTest, FastMathFlags) {
133f564e9ff2d3327dc122f55b8037da6d688a7deb4Michael Ilseman  IRBuilder<> Builder(BB);
134f564e9ff2d3327dc122f55b8037da6d688a7deb4Michael Ilseman  Value *F;
135f564e9ff2d3327dc122f55b8037da6d688a7deb4Michael Ilseman  Instruction *FDiv, *FAdd;
136f564e9ff2d3327dc122f55b8037da6d688a7deb4Michael Ilseman
137f564e9ff2d3327dc122f55b8037da6d688a7deb4Michael Ilseman  F = Builder.CreateLoad(GV);
138f564e9ff2d3327dc122f55b8037da6d688a7deb4Michael Ilseman  F = Builder.CreateFAdd(F, F);
139f564e9ff2d3327dc122f55b8037da6d688a7deb4Michael Ilseman
1409eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  EXPECT_FALSE(Builder.getFastMathFlags().any());
1419eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  ASSERT_TRUE(isa<Instruction>(F));
1429eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  FAdd = cast<Instruction>(F);
1439eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  EXPECT_FALSE(FAdd->hasNoNaNs());
1449eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman
1459eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  FastMathFlags FMF;
1469eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  Builder.SetFastMathFlags(FMF);
1479eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman
1489eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  F = Builder.CreateFAdd(F, F);
1499eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  EXPECT_FALSE(Builder.getFastMathFlags().any());
1509eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman
1511638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman  FMF.setUnsafeAlgebra();
1529eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  Builder.SetFastMathFlags(FMF);
1539eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman
1549eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  F = Builder.CreateFAdd(F, F);
1559eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  EXPECT_TRUE(Builder.getFastMathFlags().any());
1569eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  ASSERT_TRUE(isa<Instruction>(F));
1579eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  FAdd = cast<Instruction>(F);
1589eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  EXPECT_TRUE(FAdd->hasNoNaNs());
1599eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman
16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Now, try it with CreateBinOp
16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  F = Builder.CreateBinOp(Instruction::FAdd, F, F);
16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(Builder.getFastMathFlags().any());
16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_TRUE(isa<Instruction>(F));
16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  FAdd = cast<Instruction>(F);
16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(FAdd->hasNoNaNs());
16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1679eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  F = Builder.CreateFDiv(F, F);
1689eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  EXPECT_TRUE(Builder.getFastMathFlags().any());
1699eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  EXPECT_TRUE(Builder.getFastMathFlags().UnsafeAlgebra);
1709eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  ASSERT_TRUE(isa<Instruction>(F));
1719eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  FDiv = cast<Instruction>(F);
1729eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  EXPECT_TRUE(FDiv->hasAllowReciprocal());
1739eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman
1749eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  Builder.clearFastMathFlags();
1759eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman
1769eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  F = Builder.CreateFDiv(F, F);
1779eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  ASSERT_TRUE(isa<Instruction>(F));
1789eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  FDiv = cast<Instruction>(F);
1799eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  EXPECT_FALSE(FDiv->hasAllowReciprocal());
1809eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman
1819eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  FMF.clear();
1821638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman  FMF.setAllowReciprocal();
1839eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  Builder.SetFastMathFlags(FMF);
1849eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman
1859eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  F = Builder.CreateFDiv(F, F);
1869eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  EXPECT_TRUE(Builder.getFastMathFlags().any());
1879eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  EXPECT_TRUE(Builder.getFastMathFlags().AllowReciprocal);
1889eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  ASSERT_TRUE(isa<Instruction>(F));
1899eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  FDiv = cast<Instruction>(F);
1909eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman  EXPECT_TRUE(FDiv->hasAllowReciprocal());
1919eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman
1924b896dd613b1d85ee1b261ee470cb72fab24c282Michael Ilseman  Builder.clearFastMathFlags();
1934b896dd613b1d85ee1b261ee470cb72fab24c282Michael Ilseman
19437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // To test a copy, make sure that a '0' and a '1' change state.
1954b896dd613b1d85ee1b261ee470cb72fab24c282Michael Ilseman  F = Builder.CreateFDiv(F, F);
1964b896dd613b1d85ee1b261ee470cb72fab24c282Michael Ilseman  ASSERT_TRUE(isa<Instruction>(F));
1974b896dd613b1d85ee1b261ee470cb72fab24c282Michael Ilseman  FDiv = cast<Instruction>(F);
1984b896dd613b1d85ee1b261ee470cb72fab24c282Michael Ilseman  EXPECT_FALSE(FDiv->getFastMathFlags().any());
19937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  FDiv->setHasAllowReciprocal(true);
20037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  FAdd->setHasAllowReciprocal(false);
2014b896dd613b1d85ee1b261ee470cb72fab24c282Michael Ilseman  FDiv->copyFastMathFlags(FAdd);
2024b896dd613b1d85ee1b261ee470cb72fab24c282Michael Ilseman  EXPECT_TRUE(FDiv->hasNoNaNs());
20337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  EXPECT_FALSE(FDiv->hasAllowReciprocal());
2044b896dd613b1d85ee1b261ee470cb72fab24c282Michael Ilseman
2059eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman}
2069eec6599521ba64e59da4a5e5fdc79ba6964dbc6Michael Ilseman
20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesTEST_F(IRBuilderTest, WrapFlags) {
20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  IRBuilder<true, NoFolder> Builder(BB);
20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Test instructions.
21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  GlobalVariable *G = new GlobalVariable(*M, Builder.getInt32Ty(), true,
212c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                         GlobalValue::ExternalLinkage, nullptr);
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Value *V = Builder.CreateLoad(G);
21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(
21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      cast<BinaryOperator>(Builder.CreateNSWAdd(V, V))->hasNoSignedWrap());
21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(
21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      cast<BinaryOperator>(Builder.CreateNSWMul(V, V))->hasNoSignedWrap());
21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(
21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      cast<BinaryOperator>(Builder.CreateNSWSub(V, V))->hasNoSignedWrap());
22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(cast<BinaryOperator>(
22136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  Builder.CreateShl(V, V, "", /* NUW */ false, /* NSW */ true))
22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  ->hasNoSignedWrap());
22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(
22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      cast<BinaryOperator>(Builder.CreateNUWAdd(V, V))->hasNoUnsignedWrap());
22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(
22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      cast<BinaryOperator>(Builder.CreateNUWMul(V, V))->hasNoUnsignedWrap());
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(
22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      cast<BinaryOperator>(Builder.CreateNUWSub(V, V))->hasNoUnsignedWrap());
23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(cast<BinaryOperator>(
23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  Builder.CreateShl(V, V, "", /* NUW */ true, /* NSW */ false))
23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  ->hasNoUnsignedWrap());
23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Test operators created with constants.
23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Constant *C = Builder.getInt32(42);
23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWAdd(C, C))
23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  ->hasNoSignedWrap());
23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWSub(C, C))
23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  ->hasNoSignedWrap());
24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWMul(C, C))
24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  ->hasNoSignedWrap());
24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(cast<OverflowingBinaryOperator>(
24336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  Builder.CreateShl(C, C, "", /* NUW */ false, /* NSW */ true))
24436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  ->hasNoSignedWrap());
24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWAdd(C, C))
24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  ->hasNoUnsignedWrap());
24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWSub(C, C))
24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  ->hasNoUnsignedWrap());
25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWMul(C, C))
25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  ->hasNoUnsignedWrap());
25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(cast<OverflowingBinaryOperator>(
25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  Builder.CreateShl(C, C, "", /* NUW */ true, /* NSW */ false))
25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  ->hasNoUnsignedWrap());
25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
257adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin KramerTEST_F(IRBuilderTest, RAIIHelpersTest) {
258adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer  IRBuilder<> Builder(BB);
259adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer  EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
260adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer  MDBuilder MDB(M->getContext());
261adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer
262bd5b912dccbdd9708c8efe809af4bfbf31328288Aaron Ballman  MDNode *FPMathA = MDB.createFPMath(0.01f);
263bd5b912dccbdd9708c8efe809af4bfbf31328288Aaron Ballman  MDNode *FPMathB = MDB.createFPMath(0.1f);
264adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer
265adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer  Builder.SetDefaultFPMathTag(FPMathA);
266adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer
267adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer  {
268adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer    IRBuilder<>::FastMathFlagGuard Guard(Builder);
269adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer    FastMathFlags FMF;
270adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer    FMF.setAllowReciprocal();
271adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer    Builder.SetFastMathFlags(FMF);
272adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer    Builder.SetDefaultFPMathTag(FPMathB);
273adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer    EXPECT_TRUE(Builder.getFastMathFlags().allowReciprocal());
274adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer    EXPECT_EQ(FPMathB, Builder.getDefaultFPMathTag());
275adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer  }
276adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer
277adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer  EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
278adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer  EXPECT_EQ(FPMathA, Builder.getDefaultFPMathTag());
279adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer
280adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer  Value *F = Builder.CreateLoad(GV);
281adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer
282adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer  {
283adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer    IRBuilder<>::InsertPointGuard Guard(Builder);
284adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer    Builder.SetInsertPoint(cast<Instruction>(F));
285adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer    EXPECT_EQ(F, Builder.GetInsertPoint());
286adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer  }
287adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer
288adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer  EXPECT_EQ(BB->end(), Builder.GetInsertPoint());
289adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer  EXPECT_EQ(BB, Builder.GetInsertBlock());
290adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer}
291adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer
292ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesTEST_F(IRBuilderTest, DIBuilder) {
293ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  IRBuilder<> Builder(BB);
294ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  DIBuilder DIB(*M);
295ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  auto File = DIB.createFile("F.CBL", "/");
296ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  auto CU = DIB.createCompileUnit(dwarf::DW_LANG_Cobol74, "F.CBL", "/",
297ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                  "llvm-cobol74", true, "", 0);
298ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  auto Type = DIB.createSubroutineType(File, DIB.getOrCreateTypeArray(None));
2992c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  DIB.createFunction(CU, "foo", "", File, 1, Type, false, true, 1, 0, true, F);
300ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty());
3012c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  auto BarSP = DIB.createFunction(CU, "bar", "", File, 1, Type, false, true, 1,
3022c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar                                  0, true, nullptr);
3032c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  auto BadScope = DIB.createLexicalBlockFile(BarSP, File, 0);
304ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  I->setDebugLoc(DebugLoc::get(2, 0, BadScope));
305ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  DIB.finalize();
3062c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  EXPECT_TRUE(verifyModule(*M));
307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
309adb412daa41aef94a9f724dfd1ade9f579bb3a84Benjamin Kramer
3101880e2d34458f67a92e26953c257f2feb334ceefChandler Carruth}
311