Mercurial > hg > CbC > CbC_llvm
comparison unittests/IR/InstructionsTest.cpp @ 121:803732b1fca8
LLVM 5.0
author | kono |
---|---|
date | Fri, 27 Oct 2017 17:07:41 +0900 |
parents | 1172e4bd9c6f |
children | c2174574ed3a |
comparison
equal
deleted
inserted
replaced
120:1172e4bd9c6f | 121:803732b1fca8 |
---|---|
17 #include "llvm/IR/Function.h" | 17 #include "llvm/IR/Function.h" |
18 #include "llvm/IR/IRBuilder.h" | 18 #include "llvm/IR/IRBuilder.h" |
19 #include "llvm/IR/LLVMContext.h" | 19 #include "llvm/IR/LLVMContext.h" |
20 #include "llvm/IR/MDBuilder.h" | 20 #include "llvm/IR/MDBuilder.h" |
21 #include "llvm/IR/Module.h" | 21 #include "llvm/IR/Module.h" |
22 #include "llvm/IR/NoFolder.h" | |
22 #include "llvm/IR/Operator.h" | 23 #include "llvm/IR/Operator.h" |
24 #include "gmock/gmock-matchers.h" | |
23 #include "gtest/gtest.h" | 25 #include "gtest/gtest.h" |
24 #include <memory> | 26 #include <memory> |
25 | 27 |
26 namespace llvm { | 28 namespace llvm { |
27 namespace { | 29 namespace { |
402 MDNode *MD1 = MDHelper.createFPMath(1.0); | 404 MDNode *MD1 = MDHelper.createFPMath(1.0); |
403 Value *V1 = Builder.CreateFAdd(I, I, "", MD1); | 405 Value *V1 = Builder.CreateFAdd(I, I, "", MD1); |
404 EXPECT_TRUE(isa<FPMathOperator>(V1)); | 406 EXPECT_TRUE(isa<FPMathOperator>(V1)); |
405 FPMathOperator *O1 = cast<FPMathOperator>(V1); | 407 FPMathOperator *O1 = cast<FPMathOperator>(V1); |
406 EXPECT_EQ(O1->getFPAccuracy(), 1.0); | 408 EXPECT_EQ(O1->getFPAccuracy(), 1.0); |
407 delete V1; | 409 V1->deleteValue(); |
408 delete I; | 410 I->deleteValue(); |
409 } | 411 } |
410 | 412 |
411 | 413 |
412 TEST(InstructionsTest, isEliminableCastPair) { | 414 TEST(InstructionsTest, isEliminableCastPair) { |
413 LLVMContext C; | 415 LLVMContext C; |
514 | 516 |
515 // Test cloning an attribute. | 517 // Test cloning an attribute. |
516 { | 518 { |
517 AttrBuilder AB; | 519 AttrBuilder AB; |
518 AB.addAttribute(Attribute::ReadOnly); | 520 AB.addAttribute(Attribute::ReadOnly); |
519 Call->setAttributes(AttributeSet::get(C, AttributeSet::FunctionIndex, AB)); | 521 Call->setAttributes( |
522 AttributeList::get(C, AttributeList::FunctionIndex, AB)); | |
520 std::unique_ptr<CallInst> Clone(cast<CallInst>(Call->clone())); | 523 std::unique_ptr<CallInst> Clone(cast<CallInst>(Call->clone())); |
521 EXPECT_TRUE(Clone->onlyReadsMemory()); | 524 EXPECT_TRUE(Clone->onlyReadsMemory()); |
522 } | 525 } |
523 } | 526 } |
524 | 527 |
532 std::unique_ptr<CallInst> Call( | 535 std::unique_ptr<CallInst> Call( |
533 CallInst::Create(Callee, Args, OldBundle, "result")); | 536 CallInst::Create(Callee, Args, OldBundle, "result")); |
534 Call->setTailCallKind(CallInst::TailCallKind::TCK_NoTail); | 537 Call->setTailCallKind(CallInst::TailCallKind::TCK_NoTail); |
535 AttrBuilder AB; | 538 AttrBuilder AB; |
536 AB.addAttribute(Attribute::Cold); | 539 AB.addAttribute(Attribute::Cold); |
537 Call->setAttributes(AttributeSet::get(C, AttributeSet::FunctionIndex, AB)); | 540 Call->setAttributes(AttributeList::get(C, AttributeList::FunctionIndex, AB)); |
538 Call->setDebugLoc(DebugLoc(MDNode::get(C, None))); | 541 Call->setDebugLoc(DebugLoc(MDNode::get(C, None))); |
539 | 542 |
540 OperandBundleDef NewBundle("after", ConstantInt::get(Int32Ty, 7)); | 543 OperandBundleDef NewBundle("after", ConstantInt::get(Int32Ty, 7)); |
541 std::unique_ptr<CallInst> Clone(CallInst::Create(Call.get(), NewBundle)); | 544 std::unique_ptr<CallInst> Clone(CallInst::Create(Call.get(), NewBundle)); |
542 EXPECT_EQ(Call->getNumArgOperands(), Clone->getNumArgOperands()); | 545 EXPECT_EQ(Call->getNumArgOperands(), Clone->getNumArgOperands()); |
560 OperandBundleDef OldBundle("before", UndefValue::get(Int32Ty)); | 563 OperandBundleDef OldBundle("before", UndefValue::get(Int32Ty)); |
561 std::unique_ptr<InvokeInst> Invoke(InvokeInst::Create( | 564 std::unique_ptr<InvokeInst> Invoke(InvokeInst::Create( |
562 Callee, NormalDest.get(), UnwindDest.get(), Args, OldBundle, "result")); | 565 Callee, NormalDest.get(), UnwindDest.get(), Args, OldBundle, "result")); |
563 AttrBuilder AB; | 566 AttrBuilder AB; |
564 AB.addAttribute(Attribute::Cold); | 567 AB.addAttribute(Attribute::Cold); |
565 Invoke->setAttributes(AttributeSet::get(C, AttributeSet::FunctionIndex, AB)); | 568 Invoke->setAttributes( |
569 AttributeList::get(C, AttributeList::FunctionIndex, AB)); | |
566 Invoke->setDebugLoc(DebugLoc(MDNode::get(C, None))); | 570 Invoke->setDebugLoc(DebugLoc(MDNode::get(C, None))); |
567 | 571 |
568 OperandBundleDef NewBundle("after", ConstantInt::get(Int32Ty, 7)); | 572 OperandBundleDef NewBundle("after", ConstantInt::get(Int32Ty, 7)); |
569 std::unique_ptr<InvokeInst> Clone( | 573 std::unique_ptr<InvokeInst> Clone( |
570 InvokeInst::Create(Invoke.get(), NewBundle)); | 574 InvokeInst::Create(Invoke.get(), NewBundle)); |
577 EXPECT_EQ(Invoke->getDebugLoc(), Clone->getDebugLoc()); | 581 EXPECT_EQ(Invoke->getDebugLoc(), Clone->getDebugLoc()); |
578 EXPECT_EQ(Clone->getNumOperandBundles(), 1U); | 582 EXPECT_EQ(Clone->getNumOperandBundles(), 1U); |
579 EXPECT_TRUE(Clone->getOperandBundle("after").hasValue()); | 583 EXPECT_TRUE(Clone->getOperandBundle("after").hasValue()); |
580 } | 584 } |
581 | 585 |
586 TEST_F(ModuleWithFunctionTest, DropPoisonGeneratingFlags) { | |
587 auto *OnlyBB = BasicBlock::Create(Ctx, "bb", F); | |
588 auto *Arg0 = &*F->arg_begin(); | |
589 | |
590 IRBuilder<NoFolder> B(Ctx); | |
591 B.SetInsertPoint(OnlyBB); | |
592 | |
593 { | |
594 auto *UI = | |
595 cast<Instruction>(B.CreateUDiv(Arg0, Arg0, "", /*isExact*/ true)); | |
596 ASSERT_TRUE(UI->isExact()); | |
597 UI->dropPoisonGeneratingFlags(); | |
598 ASSERT_FALSE(UI->isExact()); | |
599 } | |
600 | |
601 { | |
602 auto *ShrI = | |
603 cast<Instruction>(B.CreateLShr(Arg0, Arg0, "", /*isExact*/ true)); | |
604 ASSERT_TRUE(ShrI->isExact()); | |
605 ShrI->dropPoisonGeneratingFlags(); | |
606 ASSERT_FALSE(ShrI->isExact()); | |
607 } | |
608 | |
609 { | |
610 auto *AI = cast<Instruction>( | |
611 B.CreateAdd(Arg0, Arg0, "", /*HasNUW*/ true, /*HasNSW*/ false)); | |
612 ASSERT_TRUE(AI->hasNoUnsignedWrap()); | |
613 AI->dropPoisonGeneratingFlags(); | |
614 ASSERT_FALSE(AI->hasNoUnsignedWrap()); | |
615 ASSERT_FALSE(AI->hasNoSignedWrap()); | |
616 } | |
617 | |
618 { | |
619 auto *SI = cast<Instruction>( | |
620 B.CreateAdd(Arg0, Arg0, "", /*HasNUW*/ false, /*HasNSW*/ true)); | |
621 ASSERT_TRUE(SI->hasNoSignedWrap()); | |
622 SI->dropPoisonGeneratingFlags(); | |
623 ASSERT_FALSE(SI->hasNoUnsignedWrap()); | |
624 ASSERT_FALSE(SI->hasNoSignedWrap()); | |
625 } | |
626 | |
627 { | |
628 auto *ShlI = cast<Instruction>( | |
629 B.CreateShl(Arg0, Arg0, "", /*HasNUW*/ true, /*HasNSW*/ true)); | |
630 ASSERT_TRUE(ShlI->hasNoSignedWrap()); | |
631 ASSERT_TRUE(ShlI->hasNoUnsignedWrap()); | |
632 ShlI->dropPoisonGeneratingFlags(); | |
633 ASSERT_FALSE(ShlI->hasNoUnsignedWrap()); | |
634 ASSERT_FALSE(ShlI->hasNoSignedWrap()); | |
635 } | |
636 | |
637 { | |
638 Value *GEPBase = Constant::getNullValue(B.getInt8PtrTy()); | |
639 auto *GI = cast<GetElementPtrInst>(B.CreateInBoundsGEP(GEPBase, {Arg0})); | |
640 ASSERT_TRUE(GI->isInBounds()); | |
641 GI->dropPoisonGeneratingFlags(); | |
642 ASSERT_FALSE(GI->isInBounds()); | |
643 } | |
644 } | |
645 | |
646 TEST(InstructionsTest, GEPIndices) { | |
647 LLVMContext Context; | |
648 IRBuilder<NoFolder> Builder(Context); | |
649 Type *ElementTy = Builder.getInt8Ty(); | |
650 Type *ArrTy = ArrayType::get(ArrayType::get(ElementTy, 64), 64); | |
651 Value *Indices[] = { | |
652 Builder.getInt32(0), | |
653 Builder.getInt32(13), | |
654 Builder.getInt32(42) }; | |
655 | |
656 Value *V = Builder.CreateGEP(ArrTy, UndefValue::get(PointerType::getUnqual(ArrTy)), | |
657 Indices); | |
658 ASSERT_TRUE(isa<GetElementPtrInst>(V)); | |
659 | |
660 auto *GEPI = cast<GetElementPtrInst>(V); | |
661 ASSERT_NE(GEPI->idx_begin(), GEPI->idx_end()); | |
662 ASSERT_EQ(GEPI->idx_end(), std::next(GEPI->idx_begin(), 3)); | |
663 EXPECT_EQ(Indices[0], GEPI->idx_begin()[0]); | |
664 EXPECT_EQ(Indices[1], GEPI->idx_begin()[1]); | |
665 EXPECT_EQ(Indices[2], GEPI->idx_begin()[2]); | |
666 EXPECT_EQ(GEPI->idx_begin(), GEPI->indices().begin()); | |
667 EXPECT_EQ(GEPI->idx_end(), GEPI->indices().end()); | |
668 | |
669 const auto *CGEPI = GEPI; | |
670 ASSERT_NE(CGEPI->idx_begin(), CGEPI->idx_end()); | |
671 ASSERT_EQ(CGEPI->idx_end(), std::next(CGEPI->idx_begin(), 3)); | |
672 EXPECT_EQ(Indices[0], CGEPI->idx_begin()[0]); | |
673 EXPECT_EQ(Indices[1], CGEPI->idx_begin()[1]); | |
674 EXPECT_EQ(Indices[2], CGEPI->idx_begin()[2]); | |
675 EXPECT_EQ(CGEPI->idx_begin(), CGEPI->indices().begin()); | |
676 EXPECT_EQ(CGEPI->idx_end(), CGEPI->indices().end()); | |
677 | |
678 delete GEPI; | |
679 } | |
680 | |
681 TEST(InstructionsTest, SwitchInst) { | |
682 LLVMContext C; | |
683 | |
684 std::unique_ptr<BasicBlock> BB1, BB2, BB3; | |
685 BB1.reset(BasicBlock::Create(C)); | |
686 BB2.reset(BasicBlock::Create(C)); | |
687 BB3.reset(BasicBlock::Create(C)); | |
688 | |
689 // We create block 0 after the others so that it gets destroyed first and | |
690 // clears the uses of the other basic blocks. | |
691 std::unique_ptr<BasicBlock> BB0(BasicBlock::Create(C)); | |
692 | |
693 auto *Int32Ty = Type::getInt32Ty(C); | |
694 | |
695 SwitchInst *SI = | |
696 SwitchInst::Create(UndefValue::get(Int32Ty), BB0.get(), 3, BB0.get()); | |
697 SI->addCase(ConstantInt::get(Int32Ty, 1), BB1.get()); | |
698 SI->addCase(ConstantInt::get(Int32Ty, 2), BB2.get()); | |
699 SI->addCase(ConstantInt::get(Int32Ty, 3), BB3.get()); | |
700 | |
701 auto CI = SI->case_begin(); | |
702 ASSERT_NE(CI, SI->case_end()); | |
703 EXPECT_EQ(1, CI->getCaseValue()->getSExtValue()); | |
704 EXPECT_EQ(BB1.get(), CI->getCaseSuccessor()); | |
705 EXPECT_EQ(2, (CI + 1)->getCaseValue()->getSExtValue()); | |
706 EXPECT_EQ(BB2.get(), (CI + 1)->getCaseSuccessor()); | |
707 EXPECT_EQ(3, (CI + 2)->getCaseValue()->getSExtValue()); | |
708 EXPECT_EQ(BB3.get(), (CI + 2)->getCaseSuccessor()); | |
709 EXPECT_EQ(CI + 1, std::next(CI)); | |
710 EXPECT_EQ(CI + 2, std::next(CI, 2)); | |
711 EXPECT_EQ(CI + 3, std::next(CI, 3)); | |
712 EXPECT_EQ(SI->case_end(), CI + 3); | |
713 EXPECT_EQ(0, CI - CI); | |
714 EXPECT_EQ(1, (CI + 1) - CI); | |
715 EXPECT_EQ(2, (CI + 2) - CI); | |
716 EXPECT_EQ(3, SI->case_end() - CI); | |
717 EXPECT_EQ(3, std::distance(CI, SI->case_end())); | |
718 | |
719 auto CCI = const_cast<const SwitchInst *>(SI)->case_begin(); | |
720 SwitchInst::ConstCaseIt CCE = SI->case_end(); | |
721 ASSERT_NE(CCI, SI->case_end()); | |
722 EXPECT_EQ(1, CCI->getCaseValue()->getSExtValue()); | |
723 EXPECT_EQ(BB1.get(), CCI->getCaseSuccessor()); | |
724 EXPECT_EQ(2, (CCI + 1)->getCaseValue()->getSExtValue()); | |
725 EXPECT_EQ(BB2.get(), (CCI + 1)->getCaseSuccessor()); | |
726 EXPECT_EQ(3, (CCI + 2)->getCaseValue()->getSExtValue()); | |
727 EXPECT_EQ(BB3.get(), (CCI + 2)->getCaseSuccessor()); | |
728 EXPECT_EQ(CCI + 1, std::next(CCI)); | |
729 EXPECT_EQ(CCI + 2, std::next(CCI, 2)); | |
730 EXPECT_EQ(CCI + 3, std::next(CCI, 3)); | |
731 EXPECT_EQ(CCE, CCI + 3); | |
732 EXPECT_EQ(0, CCI - CCI); | |
733 EXPECT_EQ(1, (CCI + 1) - CCI); | |
734 EXPECT_EQ(2, (CCI + 2) - CCI); | |
735 EXPECT_EQ(3, CCE - CCI); | |
736 EXPECT_EQ(3, std::distance(CCI, CCE)); | |
737 | |
738 // Make sure that the const iterator is compatible with a const auto ref. | |
739 const auto &Handle = *CCI; | |
740 EXPECT_EQ(1, Handle.getCaseValue()->getSExtValue()); | |
741 EXPECT_EQ(BB1.get(), Handle.getCaseSuccessor()); | |
742 } | |
743 | |
744 TEST(InstructionsTest, CommuteShuffleMask) { | |
745 SmallVector<int, 16> Indices({-1, 0, 7}); | |
746 ShuffleVectorInst::commuteShuffleMask(Indices, 4); | |
747 EXPECT_THAT(Indices, testing::ContainerEq(ArrayRef<int>({-1, 4, 3}))); | |
748 } | |
749 | |
582 } // end anonymous namespace | 750 } // end anonymous namespace |
583 } // end namespace llvm | 751 } // end namespace llvm |