Mercurial > hg > CbC > CbC_llvm
diff unittests/IR/InstructionsTest.cpp @ 121:803732b1fca8
LLVM 5.0
author | kono |
---|---|
date | Fri, 27 Oct 2017 17:07:41 +0900 |
parents | 1172e4bd9c6f |
children | c2174574ed3a |
line wrap: on
line diff
--- a/unittests/IR/InstructionsTest.cpp Fri Nov 25 19:14:25 2016 +0900 +++ b/unittests/IR/InstructionsTest.cpp Fri Oct 27 17:07:41 2017 +0900 @@ -19,7 +19,9 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Module.h" +#include "llvm/IR/NoFolder.h" #include "llvm/IR/Operator.h" +#include "gmock/gmock-matchers.h" #include "gtest/gtest.h" #include <memory> @@ -404,8 +406,8 @@ EXPECT_TRUE(isa<FPMathOperator>(V1)); FPMathOperator *O1 = cast<FPMathOperator>(V1); EXPECT_EQ(O1->getFPAccuracy(), 1.0); - delete V1; - delete I; + V1->deleteValue(); + I->deleteValue(); } @@ -516,7 +518,8 @@ { AttrBuilder AB; AB.addAttribute(Attribute::ReadOnly); - Call->setAttributes(AttributeSet::get(C, AttributeSet::FunctionIndex, AB)); + Call->setAttributes( + AttributeList::get(C, AttributeList::FunctionIndex, AB)); std::unique_ptr<CallInst> Clone(cast<CallInst>(Call->clone())); EXPECT_TRUE(Clone->onlyReadsMemory()); } @@ -534,7 +537,7 @@ Call->setTailCallKind(CallInst::TailCallKind::TCK_NoTail); AttrBuilder AB; AB.addAttribute(Attribute::Cold); - Call->setAttributes(AttributeSet::get(C, AttributeSet::FunctionIndex, AB)); + Call->setAttributes(AttributeList::get(C, AttributeList::FunctionIndex, AB)); Call->setDebugLoc(DebugLoc(MDNode::get(C, None))); OperandBundleDef NewBundle("after", ConstantInt::get(Int32Ty, 7)); @@ -562,7 +565,8 @@ Callee, NormalDest.get(), UnwindDest.get(), Args, OldBundle, "result")); AttrBuilder AB; AB.addAttribute(Attribute::Cold); - Invoke->setAttributes(AttributeSet::get(C, AttributeSet::FunctionIndex, AB)); + Invoke->setAttributes( + AttributeList::get(C, AttributeList::FunctionIndex, AB)); Invoke->setDebugLoc(DebugLoc(MDNode::get(C, None))); OperandBundleDef NewBundle("after", ConstantInt::get(Int32Ty, 7)); @@ -579,5 +583,169 @@ EXPECT_TRUE(Clone->getOperandBundle("after").hasValue()); } +TEST_F(ModuleWithFunctionTest, DropPoisonGeneratingFlags) { + auto *OnlyBB = BasicBlock::Create(Ctx, "bb", F); + auto *Arg0 = &*F->arg_begin(); + + IRBuilder<NoFolder> B(Ctx); + B.SetInsertPoint(OnlyBB); + + { + auto *UI = + cast<Instruction>(B.CreateUDiv(Arg0, Arg0, "", /*isExact*/ true)); + ASSERT_TRUE(UI->isExact()); + UI->dropPoisonGeneratingFlags(); + ASSERT_FALSE(UI->isExact()); + } + + { + auto *ShrI = + cast<Instruction>(B.CreateLShr(Arg0, Arg0, "", /*isExact*/ true)); + ASSERT_TRUE(ShrI->isExact()); + ShrI->dropPoisonGeneratingFlags(); + ASSERT_FALSE(ShrI->isExact()); + } + + { + auto *AI = cast<Instruction>( + B.CreateAdd(Arg0, Arg0, "", /*HasNUW*/ true, /*HasNSW*/ false)); + ASSERT_TRUE(AI->hasNoUnsignedWrap()); + AI->dropPoisonGeneratingFlags(); + ASSERT_FALSE(AI->hasNoUnsignedWrap()); + ASSERT_FALSE(AI->hasNoSignedWrap()); + } + + { + auto *SI = cast<Instruction>( + B.CreateAdd(Arg0, Arg0, "", /*HasNUW*/ false, /*HasNSW*/ true)); + ASSERT_TRUE(SI->hasNoSignedWrap()); + SI->dropPoisonGeneratingFlags(); + ASSERT_FALSE(SI->hasNoUnsignedWrap()); + ASSERT_FALSE(SI->hasNoSignedWrap()); + } + + { + auto *ShlI = cast<Instruction>( + B.CreateShl(Arg0, Arg0, "", /*HasNUW*/ true, /*HasNSW*/ true)); + ASSERT_TRUE(ShlI->hasNoSignedWrap()); + ASSERT_TRUE(ShlI->hasNoUnsignedWrap()); + ShlI->dropPoisonGeneratingFlags(); + ASSERT_FALSE(ShlI->hasNoUnsignedWrap()); + ASSERT_FALSE(ShlI->hasNoSignedWrap()); + } + + { + Value *GEPBase = Constant::getNullValue(B.getInt8PtrTy()); + auto *GI = cast<GetElementPtrInst>(B.CreateInBoundsGEP(GEPBase, {Arg0})); + ASSERT_TRUE(GI->isInBounds()); + GI->dropPoisonGeneratingFlags(); + ASSERT_FALSE(GI->isInBounds()); + } +} + +TEST(InstructionsTest, GEPIndices) { + LLVMContext Context; + IRBuilder<NoFolder> Builder(Context); + Type *ElementTy = Builder.getInt8Ty(); + Type *ArrTy = ArrayType::get(ArrayType::get(ElementTy, 64), 64); + Value *Indices[] = { + Builder.getInt32(0), + Builder.getInt32(13), + Builder.getInt32(42) }; + + Value *V = Builder.CreateGEP(ArrTy, UndefValue::get(PointerType::getUnqual(ArrTy)), + Indices); + ASSERT_TRUE(isa<GetElementPtrInst>(V)); + + auto *GEPI = cast<GetElementPtrInst>(V); + ASSERT_NE(GEPI->idx_begin(), GEPI->idx_end()); + ASSERT_EQ(GEPI->idx_end(), std::next(GEPI->idx_begin(), 3)); + EXPECT_EQ(Indices[0], GEPI->idx_begin()[0]); + EXPECT_EQ(Indices[1], GEPI->idx_begin()[1]); + EXPECT_EQ(Indices[2], GEPI->idx_begin()[2]); + EXPECT_EQ(GEPI->idx_begin(), GEPI->indices().begin()); + EXPECT_EQ(GEPI->idx_end(), GEPI->indices().end()); + + const auto *CGEPI = GEPI; + ASSERT_NE(CGEPI->idx_begin(), CGEPI->idx_end()); + ASSERT_EQ(CGEPI->idx_end(), std::next(CGEPI->idx_begin(), 3)); + EXPECT_EQ(Indices[0], CGEPI->idx_begin()[0]); + EXPECT_EQ(Indices[1], CGEPI->idx_begin()[1]); + EXPECT_EQ(Indices[2], CGEPI->idx_begin()[2]); + EXPECT_EQ(CGEPI->idx_begin(), CGEPI->indices().begin()); + EXPECT_EQ(CGEPI->idx_end(), CGEPI->indices().end()); + + delete GEPI; +} + +TEST(InstructionsTest, SwitchInst) { + LLVMContext C; + + std::unique_ptr<BasicBlock> BB1, BB2, BB3; + BB1.reset(BasicBlock::Create(C)); + BB2.reset(BasicBlock::Create(C)); + BB3.reset(BasicBlock::Create(C)); + + // We create block 0 after the others so that it gets destroyed first and + // clears the uses of the other basic blocks. + std::unique_ptr<BasicBlock> BB0(BasicBlock::Create(C)); + + auto *Int32Ty = Type::getInt32Ty(C); + + SwitchInst *SI = + SwitchInst::Create(UndefValue::get(Int32Ty), BB0.get(), 3, BB0.get()); + SI->addCase(ConstantInt::get(Int32Ty, 1), BB1.get()); + SI->addCase(ConstantInt::get(Int32Ty, 2), BB2.get()); + SI->addCase(ConstantInt::get(Int32Ty, 3), BB3.get()); + + auto CI = SI->case_begin(); + ASSERT_NE(CI, SI->case_end()); + EXPECT_EQ(1, CI->getCaseValue()->getSExtValue()); + EXPECT_EQ(BB1.get(), CI->getCaseSuccessor()); + EXPECT_EQ(2, (CI + 1)->getCaseValue()->getSExtValue()); + EXPECT_EQ(BB2.get(), (CI + 1)->getCaseSuccessor()); + EXPECT_EQ(3, (CI + 2)->getCaseValue()->getSExtValue()); + EXPECT_EQ(BB3.get(), (CI + 2)->getCaseSuccessor()); + EXPECT_EQ(CI + 1, std::next(CI)); + EXPECT_EQ(CI + 2, std::next(CI, 2)); + EXPECT_EQ(CI + 3, std::next(CI, 3)); + EXPECT_EQ(SI->case_end(), CI + 3); + EXPECT_EQ(0, CI - CI); + EXPECT_EQ(1, (CI + 1) - CI); + EXPECT_EQ(2, (CI + 2) - CI); + EXPECT_EQ(3, SI->case_end() - CI); + EXPECT_EQ(3, std::distance(CI, SI->case_end())); + + auto CCI = const_cast<const SwitchInst *>(SI)->case_begin(); + SwitchInst::ConstCaseIt CCE = SI->case_end(); + ASSERT_NE(CCI, SI->case_end()); + EXPECT_EQ(1, CCI->getCaseValue()->getSExtValue()); + EXPECT_EQ(BB1.get(), CCI->getCaseSuccessor()); + EXPECT_EQ(2, (CCI + 1)->getCaseValue()->getSExtValue()); + EXPECT_EQ(BB2.get(), (CCI + 1)->getCaseSuccessor()); + EXPECT_EQ(3, (CCI + 2)->getCaseValue()->getSExtValue()); + EXPECT_EQ(BB3.get(), (CCI + 2)->getCaseSuccessor()); + EXPECT_EQ(CCI + 1, std::next(CCI)); + EXPECT_EQ(CCI + 2, std::next(CCI, 2)); + EXPECT_EQ(CCI + 3, std::next(CCI, 3)); + EXPECT_EQ(CCE, CCI + 3); + EXPECT_EQ(0, CCI - CCI); + EXPECT_EQ(1, (CCI + 1) - CCI); + EXPECT_EQ(2, (CCI + 2) - CCI); + EXPECT_EQ(3, CCE - CCI); + EXPECT_EQ(3, std::distance(CCI, CCE)); + + // Make sure that the const iterator is compatible with a const auto ref. + const auto &Handle = *CCI; + EXPECT_EQ(1, Handle.getCaseValue()->getSExtValue()); + EXPECT_EQ(BB1.get(), Handle.getCaseSuccessor()); +} + +TEST(InstructionsTest, CommuteShuffleMask) { + SmallVector<int, 16> Indices({-1, 0, 7}); + ShuffleVectorInst::commuteShuffleMask(Indices, 4); + EXPECT_THAT(Indices, testing::ContainerEq(ArrayRef<int>({-1, 4, 3}))); +} + } // end anonymous namespace } // end namespace llvm