X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=unittests%2FIR%2FIRBuilderTest.cpp;h=0c602ed2b789e6f47e2c651e5160a4457fef2bd5;hb=8893466777ecbe91ff69206072bc95a3e38e1a0d;hp=fcb567790734e5a570fbbc221043b09dbbb2d9a7;hpb=faf4d59137e85f917f868e784c8d83ccc29c4b7f;p=oota-llvm.git diff --git a/unittests/IR/IRBuilderTest.cpp b/unittests/IR/IRBuilderTest.cpp index fcb56779073..0c602ed2b78 100644 --- a/unittests/IR/IRBuilderTest.cpp +++ b/unittests/IR/IRBuilderTest.cpp @@ -8,14 +8,16 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/IRBuilder.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DIBuilder.h" #include "llvm/IR/Function.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Module.h" +#include "llvm/IR/NoFolder.h" +#include "llvm/IR/Verifier.h" #include "gtest/gtest.h" using namespace llvm; @@ -24,23 +26,23 @@ namespace { class IRBuilderTest : public testing::Test { protected: - virtual void SetUp() { + void SetUp() override { M.reset(new Module("MyModule", Ctx)); FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx), /*isVarArg=*/false); F = Function::Create(FTy, Function::ExternalLinkage, "", M.get()); BB = BasicBlock::Create(Ctx, "", F); GV = new GlobalVariable(*M, Type::getFloatTy(Ctx), true, - GlobalValue::ExternalLinkage, 0); + GlobalValue::ExternalLinkage, nullptr); } - virtual void TearDown() { - BB = 0; + void TearDown() override { + BB = nullptr; M.reset(); } LLVMContext Ctx; - OwningPtr M; + std::unique_ptr M; Function *F; BasicBlock *BB; GlobalVariable *GV; @@ -71,9 +73,9 @@ TEST_F(IRBuilderTest, Lifetime) { IntrinsicInst *II_Start1 = dyn_cast(Start1); IntrinsicInst *II_End1 = dyn_cast(End1); - ASSERT_TRUE(II_Start1 != NULL); + ASSERT_TRUE(II_Start1 != nullptr); EXPECT_EQ(II_Start1->getIntrinsicID(), Intrinsic::lifetime_start); - ASSERT_TRUE(II_End1 != NULL); + ASSERT_TRUE(II_End1 != nullptr); EXPECT_EQ(II_End1->getIntrinsicID(), Intrinsic::lifetime_end); } @@ -102,18 +104,25 @@ TEST_F(IRBuilderTest, CreateCondBr) { TEST_F(IRBuilderTest, LandingPadName) { IRBuilder<> Builder(BB); - LandingPadInst *LP = Builder.CreateLandingPad(Builder.getInt32Ty(), - Builder.getInt32(0), 0, "LP"); + LandingPadInst *LP = Builder.CreateLandingPad(Builder.getInt32Ty(), 0, "LP"); EXPECT_EQ(LP->getName(), "LP"); } +TEST_F(IRBuilderTest, DataLayout) { + std::unique_ptr M(new Module("test", Ctx)); + M->setDataLayout("e-n32"); + EXPECT_TRUE(M->getDataLayout().isLegalInteger(32)); + M->setDataLayout("e"); + EXPECT_FALSE(M->getDataLayout().isLegalInteger(32)); +} + TEST_F(IRBuilderTest, GetIntTy) { IRBuilder<> Builder(BB); IntegerType *Ty1 = Builder.getInt1Ty(); EXPECT_EQ(Ty1, IntegerType::get(Ctx, 1)); DataLayout* DL = new DataLayout(M.get()); - IntegerType *IntPtrTy = Builder.getIntPtrTy(DL); + IntegerType *IntPtrTy = Builder.getIntPtrTy(*DL); unsigned IntPtrBitSize = DL->getPointerSizeInBits(0); EXPECT_EQ(IntPtrTy, IntegerType::get(Ctx, IntPtrBitSize)); delete DL; @@ -121,8 +130,8 @@ TEST_F(IRBuilderTest, GetIntTy) { TEST_F(IRBuilderTest, FastMathFlags) { IRBuilder<> Builder(BB); - Value *F; - Instruction *FDiv, *FAdd; + Value *F, *FC; + Instruction *FDiv, *FAdd, *FCmp; F = Builder.CreateLoad(GV); F = Builder.CreateFAdd(F, F); @@ -181,15 +190,87 @@ TEST_F(IRBuilderTest, FastMathFlags) { Builder.clearFastMathFlags(); + FC = Builder.CreateFCmpOEQ(F, F); + ASSERT_TRUE(isa(FC)); + FCmp = cast(FC); + EXPECT_FALSE(FCmp->hasAllowReciprocal()); + + FMF.clear(); + FMF.setAllowReciprocal(); + Builder.SetFastMathFlags(FMF); + + FC = Builder.CreateFCmpOEQ(F, F); + EXPECT_TRUE(Builder.getFastMathFlags().any()); + EXPECT_TRUE(Builder.getFastMathFlags().AllowReciprocal); + ASSERT_TRUE(isa(FC)); + FCmp = cast(FC); + EXPECT_TRUE(FCmp->hasAllowReciprocal()); + + Builder.clearFastMathFlags(); + + // To test a copy, make sure that a '0' and a '1' change state. F = Builder.CreateFDiv(F, F); ASSERT_TRUE(isa(F)); FDiv = cast(F); EXPECT_FALSE(FDiv->getFastMathFlags().any()); + FDiv->setHasAllowReciprocal(true); + FAdd->setHasAllowReciprocal(false); FDiv->copyFastMathFlags(FAdd); EXPECT_TRUE(FDiv->hasNoNaNs()); + EXPECT_FALSE(FDiv->hasAllowReciprocal()); } +TEST_F(IRBuilderTest, WrapFlags) { + IRBuilder Builder(BB); + + // Test instructions. + GlobalVariable *G = new GlobalVariable(*M, Builder.getInt32Ty(), true, + GlobalValue::ExternalLinkage, nullptr); + Value *V = Builder.CreateLoad(G); + EXPECT_TRUE( + cast(Builder.CreateNSWAdd(V, V))->hasNoSignedWrap()); + EXPECT_TRUE( + cast(Builder.CreateNSWMul(V, V))->hasNoSignedWrap()); + EXPECT_TRUE( + cast(Builder.CreateNSWSub(V, V))->hasNoSignedWrap()); + EXPECT_TRUE(cast( + Builder.CreateShl(V, V, "", /* NUW */ false, /* NSW */ true)) + ->hasNoSignedWrap()); + + EXPECT_TRUE( + cast(Builder.CreateNUWAdd(V, V))->hasNoUnsignedWrap()); + EXPECT_TRUE( + cast(Builder.CreateNUWMul(V, V))->hasNoUnsignedWrap()); + EXPECT_TRUE( + cast(Builder.CreateNUWSub(V, V))->hasNoUnsignedWrap()); + EXPECT_TRUE(cast( + Builder.CreateShl(V, V, "", /* NUW */ true, /* NSW */ false)) + ->hasNoUnsignedWrap()); + + // Test operators created with constants. + Constant *C = Builder.getInt32(42); + EXPECT_TRUE(cast(Builder.CreateNSWAdd(C, C)) + ->hasNoSignedWrap()); + EXPECT_TRUE(cast(Builder.CreateNSWSub(C, C)) + ->hasNoSignedWrap()); + EXPECT_TRUE(cast(Builder.CreateNSWMul(C, C)) + ->hasNoSignedWrap()); + EXPECT_TRUE(cast( + Builder.CreateShl(C, C, "", /* NUW */ false, /* NSW */ true)) + ->hasNoSignedWrap()); + + EXPECT_TRUE(cast(Builder.CreateNUWAdd(C, C)) + ->hasNoUnsignedWrap()); + EXPECT_TRUE(cast(Builder.CreateNUWSub(C, C)) + ->hasNoUnsignedWrap()); + EXPECT_TRUE(cast(Builder.CreateNUWMul(C, C)) + ->hasNoUnsignedWrap()); + EXPECT_TRUE(cast( + Builder.CreateShl(C, C, "", /* NUW */ true, /* NSW */ false)) + ->hasNoUnsignedWrap()); +} + TEST_F(IRBuilderTest, RAIIHelpersTest) { IRBuilder<> Builder(BB); EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal()); @@ -218,12 +299,93 @@ TEST_F(IRBuilderTest, RAIIHelpersTest) { { IRBuilder<>::InsertPointGuard Guard(Builder); Builder.SetInsertPoint(cast(F)); - EXPECT_EQ(F, Builder.GetInsertPoint()); + EXPECT_EQ(F, &*Builder.GetInsertPoint()); } EXPECT_EQ(BB->end(), Builder.GetInsertPoint()); EXPECT_EQ(BB, Builder.GetInsertBlock()); } +TEST_F(IRBuilderTest, DIBuilder) { + IRBuilder<> Builder(BB); + DIBuilder DIB(*M); + auto File = DIB.createFile("F.CBL", "/"); + auto CU = DIB.createCompileUnit(dwarf::DW_LANG_Cobol74, "F.CBL", "/", + "llvm-cobol74", true, "", 0); + auto Type = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None)); + auto SP = + DIB.createFunction(CU, "foo", "", File, 1, Type, false, true, 1, 0, true); + F->setSubprogram(SP); + AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty()); + auto BarSP = + DIB.createFunction(CU, "bar", "", File, 1, Type, false, true, 1, 0, true); + auto BadScope = DIB.createLexicalBlockFile(BarSP, File, 0); + I->setDebugLoc(DebugLoc::get(2, 0, BadScope)); + DIB.finalize(); + EXPECT_TRUE(verifyModule(*M)); +} + +TEST_F(IRBuilderTest, InsertExtractElement) { + IRBuilder<> Builder(BB); + + auto VecTy = VectorType::get(Builder.getInt64Ty(), 4); + auto Elt1 = Builder.getInt64(-1); + auto Elt2 = Builder.getInt64(-2); + Value *Vec = UndefValue::get(VecTy); + Vec = Builder.CreateInsertElement(Vec, Elt1, Builder.getInt8(1)); + Vec = Builder.CreateInsertElement(Vec, Elt2, 2); + auto X1 = Builder.CreateExtractElement(Vec, 1); + auto X2 = Builder.CreateExtractElement(Vec, Builder.getInt32(2)); + EXPECT_EQ(Elt1, X1); + EXPECT_EQ(Elt2, X2); +} +TEST_F(IRBuilderTest, CreateGlobalStringPtr) { + IRBuilder<> Builder(BB); + + auto String1a = Builder.CreateGlobalStringPtr("TestString", "String1a"); + auto String1b = Builder.CreateGlobalStringPtr("TestString", "String1b", 0); + auto String2 = Builder.CreateGlobalStringPtr("TestString", "String2", 1); + auto String3 = Builder.CreateGlobalString("TestString", "String3", 2); + + EXPECT_TRUE(String1a->getType()->getPointerAddressSpace() == 0); + EXPECT_TRUE(String1b->getType()->getPointerAddressSpace() == 0); + EXPECT_TRUE(String2->getType()->getPointerAddressSpace() == 1); + EXPECT_TRUE(String3->getType()->getPointerAddressSpace() == 2); +} + +TEST_F(IRBuilderTest, DebugLoc) { + auto CalleeTy = FunctionType::get(Type::getVoidTy(Ctx), + /*isVarArg=*/false); + auto Callee = + Function::Create(CalleeTy, Function::ExternalLinkage, "", M.get()); + + DIBuilder DIB(*M); + auto File = DIB.createFile("tmp.cpp", "/"); + auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C_plus_plus_11, "tmp.cpp", "/", + "", true, "", 0); + auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None)); + auto SP = + DIB.createFunction(CU, "foo", "foo", File, 1, SPType, false, true, 1); + DebugLoc DL1 = DILocation::get(Ctx, 2, 0, SP); + DebugLoc DL2 = DILocation::get(Ctx, 3, 0, SP); + + auto BB2 = BasicBlock::Create(Ctx, "bb2", F); + auto Br = BranchInst::Create(BB2, BB); + Br->setDebugLoc(DL1); + + IRBuilder<> Builder(Ctx); + Builder.SetInsertPoint(Br); + EXPECT_EQ(DL1, Builder.getCurrentDebugLocation()); + auto Call1 = Builder.CreateCall(Callee, None); + EXPECT_EQ(DL1, Call1->getDebugLoc()); + + Call1->setDebugLoc(DL2); + Builder.SetInsertPoint(Call1->getParent(), Call1->getIterator()); + EXPECT_EQ(DL2, Builder.getCurrentDebugLocation()); + auto Call2 = Builder.CreateCall(Callee, None); + EXPECT_EQ(DL2, Call2->getDebugLoc()); + + DIB.finalize(); +} }