Mercurial > hg > CbC > CbC_llvm
comparison unittests/IR/InstructionsTest.cpp @ 147:c2174574ed3a
LLVM 10
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 16:55:33 +0900 |
parents | 803732b1fca8 |
children |
comparison
equal
deleted
inserted
replaced
134:3a76565eade5 | 147:c2174574ed3a |
---|---|
1 //===- llvm/unittest/IR/InstructionsTest.cpp - Instructions unit tests ----===// | 1 //===- llvm/unittest/IR/InstructionsTest.cpp - Instructions unit tests ----===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 // | 4 // See https://llvm.org/LICENSE.txt for license information. |
5 // This file is distributed under the University of Illinois Open Source | 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 // License. See LICENSE.TXT for details. | |
7 // | 6 // |
8 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
9 | 8 |
9 #include "llvm/AsmParser/Parser.h" | |
10 #include "llvm/IR/Instructions.h" | 10 #include "llvm/IR/Instructions.h" |
11 #include "llvm/ADT/STLExtras.h" | 11 #include "llvm/ADT/STLExtras.h" |
12 #include "llvm/Analysis/ValueTracking.h" | 12 #include "llvm/Analysis/ValueTracking.h" |
13 #include "llvm/IR/BasicBlock.h" | 13 #include "llvm/IR/BasicBlock.h" |
14 #include "llvm/IR/Constants.h" | 14 #include "llvm/IR/Constants.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/NoFolder.h" |
23 #include "llvm/IR/Operator.h" | 23 #include "llvm/IR/Operator.h" |
24 #include "llvm/Support/SourceMgr.h" | |
24 #include "gmock/gmock-matchers.h" | 25 #include "gmock/gmock-matchers.h" |
25 #include "gtest/gtest.h" | 26 #include "gtest/gtest.h" |
26 #include <memory> | 27 #include <memory> |
27 | 28 |
28 namespace llvm { | 29 namespace llvm { |
29 namespace { | 30 namespace { |
31 | |
32 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) { | |
33 SMDiagnostic Err; | |
34 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C); | |
35 if (!Mod) | |
36 Err.print("InstructionsTests", errs()); | |
37 return Mod; | |
38 } | |
30 | 39 |
31 TEST(InstructionsTest, ReturnInst) { | 40 TEST(InstructionsTest, ReturnInst) { |
32 LLVMContext C; | 41 LLVMContext C; |
33 | 42 |
34 // test for PR6589 | 43 // test for PR6589 |
493 | 502 |
494 TEST(InstructionsTest, CloneCall) { | 503 TEST(InstructionsTest, CloneCall) { |
495 LLVMContext C; | 504 LLVMContext C; |
496 Type *Int32Ty = Type::getInt32Ty(C); | 505 Type *Int32Ty = Type::getInt32Ty(C); |
497 Type *ArgTys[] = {Int32Ty, Int32Ty, Int32Ty}; | 506 Type *ArgTys[] = {Int32Ty, Int32Ty, Int32Ty}; |
498 Type *FnTy = FunctionType::get(Int32Ty, ArgTys, /*isVarArg=*/false); | 507 FunctionType *FnTy = FunctionType::get(Int32Ty, ArgTys, /*isVarArg=*/false); |
499 Value *Callee = Constant::getNullValue(FnTy->getPointerTo()); | 508 Value *Callee = Constant::getNullValue(FnTy->getPointerTo()); |
500 Value *Args[] = { | 509 Value *Args[] = { |
501 ConstantInt::get(Int32Ty, 1), | 510 ConstantInt::get(Int32Ty, 1), |
502 ConstantInt::get(Int32Ty, 2), | 511 ConstantInt::get(Int32Ty, 2), |
503 ConstantInt::get(Int32Ty, 3) | 512 ConstantInt::get(Int32Ty, 3) |
504 }; | 513 }; |
505 std::unique_ptr<CallInst> Call(CallInst::Create(Callee, Args, "result")); | 514 std::unique_ptr<CallInst> Call( |
515 CallInst::Create(FnTy, Callee, Args, "result")); | |
506 | 516 |
507 // Test cloning the tail call kind. | 517 // Test cloning the tail call kind. |
508 CallInst::TailCallKind Kinds[] = {CallInst::TCK_None, CallInst::TCK_Tail, | 518 CallInst::TailCallKind Kinds[] = {CallInst::TCK_None, CallInst::TCK_Tail, |
509 CallInst::TCK_MustTail}; | 519 CallInst::TCK_MustTail}; |
510 for (CallInst::TailCallKind TCK : Kinds) { | 520 for (CallInst::TailCallKind TCK : Kinds) { |
526 } | 536 } |
527 | 537 |
528 TEST(InstructionsTest, AlterCallBundles) { | 538 TEST(InstructionsTest, AlterCallBundles) { |
529 LLVMContext C; | 539 LLVMContext C; |
530 Type *Int32Ty = Type::getInt32Ty(C); | 540 Type *Int32Ty = Type::getInt32Ty(C); |
531 Type *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false); | 541 FunctionType *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false); |
532 Value *Callee = Constant::getNullValue(FnTy->getPointerTo()); | 542 Value *Callee = Constant::getNullValue(FnTy->getPointerTo()); |
533 Value *Args[] = {ConstantInt::get(Int32Ty, 42)}; | 543 Value *Args[] = {ConstantInt::get(Int32Ty, 42)}; |
534 OperandBundleDef OldBundle("before", UndefValue::get(Int32Ty)); | 544 OperandBundleDef OldBundle("before", UndefValue::get(Int32Ty)); |
535 std::unique_ptr<CallInst> Call( | 545 std::unique_ptr<CallInst> Call( |
536 CallInst::Create(Callee, Args, OldBundle, "result")); | 546 CallInst::Create(FnTy, Callee, Args, OldBundle, "result")); |
537 Call->setTailCallKind(CallInst::TailCallKind::TCK_NoTail); | 547 Call->setTailCallKind(CallInst::TailCallKind::TCK_NoTail); |
538 AttrBuilder AB; | 548 AttrBuilder AB; |
539 AB.addAttribute(Attribute::Cold); | 549 AB.addAttribute(Attribute::Cold); |
540 Call->setAttributes(AttributeList::get(C, AttributeList::FunctionIndex, AB)); | 550 Call->setAttributes(AttributeList::get(C, AttributeList::FunctionIndex, AB)); |
541 Call->setDebugLoc(DebugLoc(MDNode::get(C, None))); | 551 Call->setDebugLoc(DebugLoc(MDNode::get(C, None))); |
553 } | 563 } |
554 | 564 |
555 TEST(InstructionsTest, AlterInvokeBundles) { | 565 TEST(InstructionsTest, AlterInvokeBundles) { |
556 LLVMContext C; | 566 LLVMContext C; |
557 Type *Int32Ty = Type::getInt32Ty(C); | 567 Type *Int32Ty = Type::getInt32Ty(C); |
558 Type *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false); | 568 FunctionType *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false); |
559 Value *Callee = Constant::getNullValue(FnTy->getPointerTo()); | 569 Value *Callee = Constant::getNullValue(FnTy->getPointerTo()); |
560 Value *Args[] = {ConstantInt::get(Int32Ty, 42)}; | 570 Value *Args[] = {ConstantInt::get(Int32Ty, 42)}; |
561 std::unique_ptr<BasicBlock> NormalDest(BasicBlock::Create(C)); | 571 std::unique_ptr<BasicBlock> NormalDest(BasicBlock::Create(C)); |
562 std::unique_ptr<BasicBlock> UnwindDest(BasicBlock::Create(C)); | 572 std::unique_ptr<BasicBlock> UnwindDest(BasicBlock::Create(C)); |
563 OperandBundleDef OldBundle("before", UndefValue::get(Int32Ty)); | 573 OperandBundleDef OldBundle("before", UndefValue::get(Int32Ty)); |
564 std::unique_ptr<InvokeInst> Invoke(InvokeInst::Create( | 574 std::unique_ptr<InvokeInst> Invoke( |
565 Callee, NormalDest.get(), UnwindDest.get(), Args, OldBundle, "result")); | 575 InvokeInst::Create(FnTy, Callee, NormalDest.get(), UnwindDest.get(), Args, |
576 OldBundle, "result")); | |
566 AttrBuilder AB; | 577 AttrBuilder AB; |
567 AB.addAttribute(Attribute::Cold); | 578 AB.addAttribute(Attribute::Cold); |
568 Invoke->setAttributes( | 579 Invoke->setAttributes( |
569 AttributeList::get(C, AttributeList::FunctionIndex, AB)); | 580 AttributeList::get(C, AttributeList::FunctionIndex, AB)); |
570 Invoke->setDebugLoc(DebugLoc(MDNode::get(C, None))); | 581 Invoke->setDebugLoc(DebugLoc(MDNode::get(C, None))); |
634 ASSERT_FALSE(ShlI->hasNoSignedWrap()); | 645 ASSERT_FALSE(ShlI->hasNoSignedWrap()); |
635 } | 646 } |
636 | 647 |
637 { | 648 { |
638 Value *GEPBase = Constant::getNullValue(B.getInt8PtrTy()); | 649 Value *GEPBase = Constant::getNullValue(B.getInt8PtrTy()); |
639 auto *GI = cast<GetElementPtrInst>(B.CreateInBoundsGEP(GEPBase, {Arg0})); | 650 auto *GI = cast<GetElementPtrInst>( |
651 B.CreateInBoundsGEP(B.getInt8Ty(), GEPBase, Arg0)); | |
640 ASSERT_TRUE(GI->isInBounds()); | 652 ASSERT_TRUE(GI->isInBounds()); |
641 GI->dropPoisonGeneratingFlags(); | 653 GI->dropPoisonGeneratingFlags(); |
642 ASSERT_FALSE(GI->isInBounds()); | 654 ASSERT_FALSE(GI->isInBounds()); |
643 } | 655 } |
644 } | 656 } |
739 const auto &Handle = *CCI; | 751 const auto &Handle = *CCI; |
740 EXPECT_EQ(1, Handle.getCaseValue()->getSExtValue()); | 752 EXPECT_EQ(1, Handle.getCaseValue()->getSExtValue()); |
741 EXPECT_EQ(BB1.get(), Handle.getCaseSuccessor()); | 753 EXPECT_EQ(BB1.get(), Handle.getCaseSuccessor()); |
742 } | 754 } |
743 | 755 |
756 TEST(InstructionsTest, SwitchInstProfUpdateWrapper) { | |
757 LLVMContext C; | |
758 | |
759 std::unique_ptr<BasicBlock> BB1, BB2, BB3; | |
760 BB1.reset(BasicBlock::Create(C)); | |
761 BB2.reset(BasicBlock::Create(C)); | |
762 BB3.reset(BasicBlock::Create(C)); | |
763 | |
764 // We create block 0 after the others so that it gets destroyed first and | |
765 // clears the uses of the other basic blocks. | |
766 std::unique_ptr<BasicBlock> BB0(BasicBlock::Create(C)); | |
767 | |
768 auto *Int32Ty = Type::getInt32Ty(C); | |
769 | |
770 SwitchInst *SI = | |
771 SwitchInst::Create(UndefValue::get(Int32Ty), BB0.get(), 4, BB0.get()); | |
772 SI->addCase(ConstantInt::get(Int32Ty, 1), BB1.get()); | |
773 SI->addCase(ConstantInt::get(Int32Ty, 2), BB2.get()); | |
774 SI->setMetadata(LLVMContext::MD_prof, | |
775 MDBuilder(C).createBranchWeights({ 9, 1, 22 })); | |
776 | |
777 { | |
778 SwitchInstProfUpdateWrapper SIW(*SI); | |
779 EXPECT_EQ(*SIW.getSuccessorWeight(0), 9u); | |
780 EXPECT_EQ(*SIW.getSuccessorWeight(1), 1u); | |
781 EXPECT_EQ(*SIW.getSuccessorWeight(2), 22u); | |
782 SIW.setSuccessorWeight(0, 99u); | |
783 SIW.setSuccessorWeight(1, 11u); | |
784 EXPECT_EQ(*SIW.getSuccessorWeight(0), 99u); | |
785 EXPECT_EQ(*SIW.getSuccessorWeight(1), 11u); | |
786 EXPECT_EQ(*SIW.getSuccessorWeight(2), 22u); | |
787 } | |
788 | |
789 { // Create another wrapper and check that the data persist. | |
790 SwitchInstProfUpdateWrapper SIW(*SI); | |
791 EXPECT_EQ(*SIW.getSuccessorWeight(0), 99u); | |
792 EXPECT_EQ(*SIW.getSuccessorWeight(1), 11u); | |
793 EXPECT_EQ(*SIW.getSuccessorWeight(2), 22u); | |
794 } | |
795 } | |
796 | |
744 TEST(InstructionsTest, CommuteShuffleMask) { | 797 TEST(InstructionsTest, CommuteShuffleMask) { |
745 SmallVector<int, 16> Indices({-1, 0, 7}); | 798 SmallVector<int, 16> Indices({-1, 0, 7}); |
746 ShuffleVectorInst::commuteShuffleMask(Indices, 4); | 799 ShuffleVectorInst::commuteShuffleMask(Indices, 4); |
747 EXPECT_THAT(Indices, testing::ContainerEq(ArrayRef<int>({-1, 4, 3}))); | 800 EXPECT_THAT(Indices, testing::ContainerEq(ArrayRef<int>({-1, 4, 3}))); |
748 } | 801 } |
749 | 802 |
803 TEST(InstructionsTest, ShuffleMaskQueries) { | |
804 // Create the elements for various constant vectors. | |
805 LLVMContext Ctx; | |
806 Type *Int32Ty = Type::getInt32Ty(Ctx); | |
807 Constant *CU = UndefValue::get(Int32Ty); | |
808 Constant *C0 = ConstantInt::get(Int32Ty, 0); | |
809 Constant *C1 = ConstantInt::get(Int32Ty, 1); | |
810 Constant *C2 = ConstantInt::get(Int32Ty, 2); | |
811 Constant *C3 = ConstantInt::get(Int32Ty, 3); | |
812 Constant *C4 = ConstantInt::get(Int32Ty, 4); | |
813 Constant *C5 = ConstantInt::get(Int32Ty, 5); | |
814 Constant *C6 = ConstantInt::get(Int32Ty, 6); | |
815 Constant *C7 = ConstantInt::get(Int32Ty, 7); | |
816 | |
817 Constant *Identity = ConstantVector::get({C0, CU, C2, C3, C4}); | |
818 EXPECT_TRUE(ShuffleVectorInst::isIdentityMask(Identity)); | |
819 EXPECT_FALSE(ShuffleVectorInst::isSelectMask(Identity)); // identity is distinguished from select | |
820 EXPECT_FALSE(ShuffleVectorInst::isReverseMask(Identity)); | |
821 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(Identity)); // identity is always single source | |
822 EXPECT_FALSE(ShuffleVectorInst::isZeroEltSplatMask(Identity)); | |
823 EXPECT_FALSE(ShuffleVectorInst::isTransposeMask(Identity)); | |
824 | |
825 Constant *Select = ConstantVector::get({CU, C1, C5}); | |
826 EXPECT_FALSE(ShuffleVectorInst::isIdentityMask(Select)); | |
827 EXPECT_TRUE(ShuffleVectorInst::isSelectMask(Select)); | |
828 EXPECT_FALSE(ShuffleVectorInst::isReverseMask(Select)); | |
829 EXPECT_FALSE(ShuffleVectorInst::isSingleSourceMask(Select)); | |
830 EXPECT_FALSE(ShuffleVectorInst::isZeroEltSplatMask(Select)); | |
831 EXPECT_FALSE(ShuffleVectorInst::isTransposeMask(Select)); | |
832 | |
833 Constant *Reverse = ConstantVector::get({C3, C2, C1, CU}); | |
834 EXPECT_FALSE(ShuffleVectorInst::isIdentityMask(Reverse)); | |
835 EXPECT_FALSE(ShuffleVectorInst::isSelectMask(Reverse)); | |
836 EXPECT_TRUE(ShuffleVectorInst::isReverseMask(Reverse)); | |
837 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(Reverse)); // reverse is always single source | |
838 EXPECT_FALSE(ShuffleVectorInst::isZeroEltSplatMask(Reverse)); | |
839 EXPECT_FALSE(ShuffleVectorInst::isTransposeMask(Reverse)); | |
840 | |
841 Constant *SingleSource = ConstantVector::get({C2, C2, C0, CU}); | |
842 EXPECT_FALSE(ShuffleVectorInst::isIdentityMask(SingleSource)); | |
843 EXPECT_FALSE(ShuffleVectorInst::isSelectMask(SingleSource)); | |
844 EXPECT_FALSE(ShuffleVectorInst::isReverseMask(SingleSource)); | |
845 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(SingleSource)); | |
846 EXPECT_FALSE(ShuffleVectorInst::isZeroEltSplatMask(SingleSource)); | |
847 EXPECT_FALSE(ShuffleVectorInst::isTransposeMask(SingleSource)); | |
848 | |
849 Constant *ZeroEltSplat = ConstantVector::get({C0, C0, CU, C0}); | |
850 EXPECT_FALSE(ShuffleVectorInst::isIdentityMask(ZeroEltSplat)); | |
851 EXPECT_FALSE(ShuffleVectorInst::isSelectMask(ZeroEltSplat)); | |
852 EXPECT_FALSE(ShuffleVectorInst::isReverseMask(ZeroEltSplat)); | |
853 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(ZeroEltSplat)); // 0-splat is always single source | |
854 EXPECT_TRUE(ShuffleVectorInst::isZeroEltSplatMask(ZeroEltSplat)); | |
855 EXPECT_FALSE(ShuffleVectorInst::isTransposeMask(ZeroEltSplat)); | |
856 | |
857 Constant *Transpose = ConstantVector::get({C0, C4, C2, C6}); | |
858 EXPECT_FALSE(ShuffleVectorInst::isIdentityMask(Transpose)); | |
859 EXPECT_FALSE(ShuffleVectorInst::isSelectMask(Transpose)); | |
860 EXPECT_FALSE(ShuffleVectorInst::isReverseMask(Transpose)); | |
861 EXPECT_FALSE(ShuffleVectorInst::isSingleSourceMask(Transpose)); | |
862 EXPECT_FALSE(ShuffleVectorInst::isZeroEltSplatMask(Transpose)); | |
863 EXPECT_TRUE(ShuffleVectorInst::isTransposeMask(Transpose)); | |
864 | |
865 // More tests to make sure the logic is/stays correct... | |
866 EXPECT_TRUE(ShuffleVectorInst::isIdentityMask(ConstantVector::get({CU, C1, CU, C3}))); | |
867 EXPECT_TRUE(ShuffleVectorInst::isIdentityMask(ConstantVector::get({C4, CU, C6, CU}))); | |
868 | |
869 EXPECT_TRUE(ShuffleVectorInst::isSelectMask(ConstantVector::get({C4, C1, C6, CU}))); | |
870 EXPECT_TRUE(ShuffleVectorInst::isSelectMask(ConstantVector::get({CU, C1, C6, C3}))); | |
871 | |
872 EXPECT_TRUE(ShuffleVectorInst::isReverseMask(ConstantVector::get({C7, C6, CU, C4}))); | |
873 EXPECT_TRUE(ShuffleVectorInst::isReverseMask(ConstantVector::get({C3, CU, C1, CU}))); | |
874 | |
875 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(ConstantVector::get({C7, C5, CU, C7}))); | |
876 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(ConstantVector::get({C3, C0, CU, C3}))); | |
877 | |
878 EXPECT_TRUE(ShuffleVectorInst::isZeroEltSplatMask(ConstantVector::get({C4, CU, CU, C4}))); | |
879 EXPECT_TRUE(ShuffleVectorInst::isZeroEltSplatMask(ConstantVector::get({CU, C0, CU, C0}))); | |
880 | |
881 EXPECT_TRUE(ShuffleVectorInst::isTransposeMask(ConstantVector::get({C1, C5, C3, C7}))); | |
882 EXPECT_TRUE(ShuffleVectorInst::isTransposeMask(ConstantVector::get({C1, C3}))); | |
883 | |
884 // Nothing special about the values here - just re-using inputs to reduce code. | |
885 Constant *V0 = ConstantVector::get({C0, C1, C2, C3}); | |
886 Constant *V1 = ConstantVector::get({C3, C2, C1, C0}); | |
887 | |
888 // Identity with undef elts. | |
889 ShuffleVectorInst *Id1 = new ShuffleVectorInst(V0, V1, | |
890 ConstantVector::get({C0, C1, CU, CU})); | |
891 EXPECT_TRUE(Id1->isIdentity()); | |
892 EXPECT_FALSE(Id1->isIdentityWithPadding()); | |
893 EXPECT_FALSE(Id1->isIdentityWithExtract()); | |
894 EXPECT_FALSE(Id1->isConcat()); | |
895 delete Id1; | |
896 | |
897 // Result has less elements than operands. | |
898 ShuffleVectorInst *Id2 = new ShuffleVectorInst(V0, V1, | |
899 ConstantVector::get({C0, C1, C2})); | |
900 EXPECT_FALSE(Id2->isIdentity()); | |
901 EXPECT_FALSE(Id2->isIdentityWithPadding()); | |
902 EXPECT_TRUE(Id2->isIdentityWithExtract()); | |
903 EXPECT_FALSE(Id2->isConcat()); | |
904 delete Id2; | |
905 | |
906 // Result has less elements than operands; choose from Op1. | |
907 ShuffleVectorInst *Id3 = new ShuffleVectorInst(V0, V1, | |
908 ConstantVector::get({C4, CU, C6})); | |
909 EXPECT_FALSE(Id3->isIdentity()); | |
910 EXPECT_FALSE(Id3->isIdentityWithPadding()); | |
911 EXPECT_TRUE(Id3->isIdentityWithExtract()); | |
912 EXPECT_FALSE(Id3->isConcat()); | |
913 delete Id3; | |
914 | |
915 // Result has less elements than operands; choose from Op0 and Op1 is not identity. | |
916 ShuffleVectorInst *Id4 = new ShuffleVectorInst(V0, V1, | |
917 ConstantVector::get({C4, C1, C6})); | |
918 EXPECT_FALSE(Id4->isIdentity()); | |
919 EXPECT_FALSE(Id4->isIdentityWithPadding()); | |
920 EXPECT_FALSE(Id4->isIdentityWithExtract()); | |
921 EXPECT_FALSE(Id4->isConcat()); | |
922 delete Id4; | |
923 | |
924 // Result has more elements than operands, and extra elements are undef. | |
925 ShuffleVectorInst *Id5 = new ShuffleVectorInst(V0, V1, | |
926 ConstantVector::get({CU, C1, C2, C3, CU, CU})); | |
927 EXPECT_FALSE(Id5->isIdentity()); | |
928 EXPECT_TRUE(Id5->isIdentityWithPadding()); | |
929 EXPECT_FALSE(Id5->isIdentityWithExtract()); | |
930 EXPECT_FALSE(Id5->isConcat()); | |
931 delete Id5; | |
932 | |
933 // Result has more elements than operands, and extra elements are undef; choose from Op1. | |
934 ShuffleVectorInst *Id6 = new ShuffleVectorInst(V0, V1, | |
935 ConstantVector::get({C4, C5, C6, CU, CU, CU})); | |
936 EXPECT_FALSE(Id6->isIdentity()); | |
937 EXPECT_TRUE(Id6->isIdentityWithPadding()); | |
938 EXPECT_FALSE(Id6->isIdentityWithExtract()); | |
939 EXPECT_FALSE(Id6->isConcat()); | |
940 delete Id6; | |
941 | |
942 // Result has more elements than operands, but extra elements are not undef. | |
943 ShuffleVectorInst *Id7 = new ShuffleVectorInst(V0, V1, | |
944 ConstantVector::get({C0, C1, C2, C3, CU, C1})); | |
945 EXPECT_FALSE(Id7->isIdentity()); | |
946 EXPECT_FALSE(Id7->isIdentityWithPadding()); | |
947 EXPECT_FALSE(Id7->isIdentityWithExtract()); | |
948 EXPECT_FALSE(Id7->isConcat()); | |
949 delete Id7; | |
950 | |
951 // Result has more elements than operands; choose from Op0 and Op1 is not identity. | |
952 ShuffleVectorInst *Id8 = new ShuffleVectorInst(V0, V1, | |
953 ConstantVector::get({C4, CU, C2, C3, CU, CU})); | |
954 EXPECT_FALSE(Id8->isIdentity()); | |
955 EXPECT_FALSE(Id8->isIdentityWithPadding()); | |
956 EXPECT_FALSE(Id8->isIdentityWithExtract()); | |
957 EXPECT_FALSE(Id8->isConcat()); | |
958 delete Id8; | |
959 | |
960 // Result has twice as many elements as operands; choose consecutively from Op0 and Op1 is concat. | |
961 ShuffleVectorInst *Id9 = new ShuffleVectorInst(V0, V1, | |
962 ConstantVector::get({C0, CU, C2, C3, CU, CU, C6, C7})); | |
963 EXPECT_FALSE(Id9->isIdentity()); | |
964 EXPECT_FALSE(Id9->isIdentityWithPadding()); | |
965 EXPECT_FALSE(Id9->isIdentityWithExtract()); | |
966 EXPECT_TRUE(Id9->isConcat()); | |
967 delete Id9; | |
968 | |
969 // Result has less than twice as many elements as operands, so not a concat. | |
970 ShuffleVectorInst *Id10 = new ShuffleVectorInst(V0, V1, | |
971 ConstantVector::get({C0, CU, C2, C3, CU, CU, C6})); | |
972 EXPECT_FALSE(Id10->isIdentity()); | |
973 EXPECT_FALSE(Id10->isIdentityWithPadding()); | |
974 EXPECT_FALSE(Id10->isIdentityWithExtract()); | |
975 EXPECT_FALSE(Id10->isConcat()); | |
976 delete Id10; | |
977 | |
978 // Result has more than twice as many elements as operands, so not a concat. | |
979 ShuffleVectorInst *Id11 = new ShuffleVectorInst(V0, V1, | |
980 ConstantVector::get({C0, CU, C2, C3, CU, CU, C6, C7, CU})); | |
981 EXPECT_FALSE(Id11->isIdentity()); | |
982 EXPECT_FALSE(Id11->isIdentityWithPadding()); | |
983 EXPECT_FALSE(Id11->isIdentityWithExtract()); | |
984 EXPECT_FALSE(Id11->isConcat()); | |
985 delete Id11; | |
986 | |
987 // If an input is undef, it's not a concat. | |
988 // TODO: IdentityWithPadding should be true here even though the high mask values are not undef. | |
989 ShuffleVectorInst *Id12 = new ShuffleVectorInst(V0, ConstantVector::get({CU, CU, CU, CU}), | |
990 ConstantVector::get({C0, CU, C2, C3, CU, CU, C6, C7})); | |
991 EXPECT_FALSE(Id12->isIdentity()); | |
992 EXPECT_FALSE(Id12->isIdentityWithPadding()); | |
993 EXPECT_FALSE(Id12->isIdentityWithExtract()); | |
994 EXPECT_FALSE(Id12->isConcat()); | |
995 delete Id12; | |
996 } | |
997 | |
998 TEST(InstructionsTest, SkipDebug) { | |
999 LLVMContext C; | |
1000 std::unique_ptr<Module> M = parseIR(C, | |
1001 R"( | |
1002 declare void @llvm.dbg.value(metadata, metadata, metadata) | |
1003 | |
1004 define void @f() { | |
1005 entry: | |
1006 call void @llvm.dbg.value(metadata i32 0, metadata !11, metadata !DIExpression()), !dbg !13 | |
1007 ret void | |
1008 } | |
1009 | |
1010 !llvm.dbg.cu = !{!0} | |
1011 !llvm.module.flags = !{!3, !4} | |
1012 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) | |
1013 !1 = !DIFile(filename: "t2.c", directory: "foo") | |
1014 !2 = !{} | |
1015 !3 = !{i32 2, !"Dwarf Version", i32 4} | |
1016 !4 = !{i32 2, !"Debug Info Version", i32 3} | |
1017 !8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, retainedNodes: !2) | |
1018 !9 = !DISubroutineType(types: !10) | |
1019 !10 = !{null} | |
1020 !11 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !12) | |
1021 !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) | |
1022 !13 = !DILocation(line: 2, column: 7, scope: !8) | |
1023 )"); | |
1024 ASSERT_TRUE(M); | |
1025 Function *F = cast<Function>(M->getNamedValue("f")); | |
1026 BasicBlock &BB = F->front(); | |
1027 | |
1028 // The first non-debug instruction is the terminator. | |
1029 auto *Term = BB.getTerminator(); | |
1030 EXPECT_EQ(Term, BB.begin()->getNextNonDebugInstruction()); | |
1031 EXPECT_EQ(Term->getIterator(), skipDebugIntrinsics(BB.begin())); | |
1032 | |
1033 // After the terminator, there are no non-debug instructions. | |
1034 EXPECT_EQ(nullptr, Term->getNextNonDebugInstruction()); | |
1035 } | |
1036 | |
1037 TEST(InstructionsTest, PhiIsNotFPMathOperator) { | |
1038 LLVMContext Context; | |
1039 IRBuilder<> Builder(Context); | |
1040 MDBuilder MDHelper(Context); | |
1041 Instruction *I = Builder.CreatePHI(Builder.getDoubleTy(), 0); | |
1042 EXPECT_FALSE(isa<FPMathOperator>(I)); | |
1043 I->deleteValue(); | |
1044 } | |
1045 | |
1046 TEST(InstructionsTest, FNegInstruction) { | |
1047 LLVMContext Context; | |
1048 Type *FltTy = Type::getFloatTy(Context); | |
1049 Constant *One = ConstantFP::get(FltTy, 1.0); | |
1050 BinaryOperator *FAdd = BinaryOperator::CreateFAdd(One, One); | |
1051 FAdd->setHasNoNaNs(true); | |
1052 UnaryOperator *FNeg = UnaryOperator::CreateFNegFMF(One, FAdd); | |
1053 EXPECT_TRUE(FNeg->hasNoNaNs()); | |
1054 EXPECT_FALSE(FNeg->hasNoInfs()); | |
1055 EXPECT_FALSE(FNeg->hasNoSignedZeros()); | |
1056 EXPECT_FALSE(FNeg->hasAllowReciprocal()); | |
1057 EXPECT_FALSE(FNeg->hasAllowContract()); | |
1058 EXPECT_FALSE(FNeg->hasAllowReassoc()); | |
1059 EXPECT_FALSE(FNeg->hasApproxFunc()); | |
1060 FAdd->deleteValue(); | |
1061 FNeg->deleteValue(); | |
1062 } | |
1063 | |
750 } // end anonymous namespace | 1064 } // end anonymous namespace |
751 } // end namespace llvm | 1065 } // end namespace llvm |