1 //===- Cloning.cpp - Unit tests for the Cloner ----------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "gtest/gtest.h" 11 #include "llvm/Argument.h" 12 #include "llvm/Constant.h" 13 #include "llvm/Instructions.h" 14 #include "llvm/LLVMContext.h" 15 #include "llvm/ADT/SmallPtrSet.h" 16 #include "llvm/ADT/STLExtras.h" 17 18 using namespace llvm; 19 20 namespace { 21 22 class CloneInstruction : public ::testing::Test { 23 protected: 24 virtual void SetUp() { 25 V = NULL; 26 } 27 28 template <typename T> 29 T *clone(T *V1) { 30 Value *V2 = V1->clone(); 31 Orig.insert(V1); 32 Clones.insert(V2); 33 return cast<T>(V2); 34 } 35 36 void eraseClones() { 37 DeleteContainerPointers(Clones); 38 } 39 40 virtual void TearDown() { 41 eraseClones(); 42 DeleteContainerPointers(Orig); 43 delete V; 44 } 45 46 SmallPtrSet<Value *, 4> Orig; // Erase on exit 47 SmallPtrSet<Value *, 4> Clones; // Erase in eraseClones 48 49 LLVMContext context; 50 Value *V; 51 }; 52 53 TEST_F(CloneInstruction, OverflowBits) { 54 V = new Argument(Type::getInt32Ty(context)); 55 56 BinaryOperator *Add = BinaryOperator::Create(Instruction::Add, V, V); 57 BinaryOperator *Sub = BinaryOperator::Create(Instruction::Sub, V, V); 58 BinaryOperator *Mul = BinaryOperator::Create(Instruction::Mul, V, V); 59 60 BinaryOperator *AddClone = this->clone(Add); 61 BinaryOperator *SubClone = this->clone(Sub); 62 BinaryOperator *MulClone = this->clone(Mul); 63 64 EXPECT_FALSE(AddClone->hasNoUnsignedWrap()); 65 EXPECT_FALSE(AddClone->hasNoSignedWrap()); 66 EXPECT_FALSE(SubClone->hasNoUnsignedWrap()); 67 EXPECT_FALSE(SubClone->hasNoSignedWrap()); 68 EXPECT_FALSE(MulClone->hasNoUnsignedWrap()); 69 EXPECT_FALSE(MulClone->hasNoSignedWrap()); 70 71 eraseClones(); 72 73 Add->setHasNoUnsignedWrap(); 74 Sub->setHasNoUnsignedWrap(); 75 Mul->setHasNoUnsignedWrap(); 76 77 AddClone = this->clone(Add); 78 SubClone = this->clone(Sub); 79 MulClone = this->clone(Mul); 80 81 EXPECT_TRUE(AddClone->hasNoUnsignedWrap()); 82 EXPECT_FALSE(AddClone->hasNoSignedWrap()); 83 EXPECT_TRUE(SubClone->hasNoUnsignedWrap()); 84 EXPECT_FALSE(SubClone->hasNoSignedWrap()); 85 EXPECT_TRUE(MulClone->hasNoUnsignedWrap()); 86 EXPECT_FALSE(MulClone->hasNoSignedWrap()); 87 88 eraseClones(); 89 90 Add->setHasNoSignedWrap(); 91 Sub->setHasNoSignedWrap(); 92 Mul->setHasNoSignedWrap(); 93 94 AddClone = this->clone(Add); 95 SubClone = this->clone(Sub); 96 MulClone = this->clone(Mul); 97 98 EXPECT_TRUE(AddClone->hasNoUnsignedWrap()); 99 EXPECT_TRUE(AddClone->hasNoSignedWrap()); 100 EXPECT_TRUE(SubClone->hasNoUnsignedWrap()); 101 EXPECT_TRUE(SubClone->hasNoSignedWrap()); 102 EXPECT_TRUE(MulClone->hasNoUnsignedWrap()); 103 EXPECT_TRUE(MulClone->hasNoSignedWrap()); 104 105 eraseClones(); 106 107 Add->setHasNoUnsignedWrap(false); 108 Sub->setHasNoUnsignedWrap(false); 109 Mul->setHasNoUnsignedWrap(false); 110 111 AddClone = this->clone(Add); 112 SubClone = this->clone(Sub); 113 MulClone = this->clone(Mul); 114 115 EXPECT_FALSE(AddClone->hasNoUnsignedWrap()); 116 EXPECT_TRUE(AddClone->hasNoSignedWrap()); 117 EXPECT_FALSE(SubClone->hasNoUnsignedWrap()); 118 EXPECT_TRUE(SubClone->hasNoSignedWrap()); 119 EXPECT_FALSE(MulClone->hasNoUnsignedWrap()); 120 EXPECT_TRUE(MulClone->hasNoSignedWrap()); 121 } 122 123 TEST_F(CloneInstruction, Inbounds) { 124 V = new Argument(Type::getInt32PtrTy(context)); 125 126 Constant *Z = Constant::getNullValue(Type::getInt32Ty(context)); 127 std::vector<Value *> ops; 128 ops.push_back(Z); 129 GetElementPtrInst *GEP = GetElementPtrInst::Create(V, ops); 130 EXPECT_FALSE(this->clone(GEP)->isInBounds()); 131 132 GEP->setIsInBounds(); 133 EXPECT_TRUE(this->clone(GEP)->isInBounds()); 134 } 135 136 TEST_F(CloneInstruction, Exact) { 137 V = new Argument(Type::getInt32Ty(context)); 138 139 BinaryOperator *SDiv = BinaryOperator::Create(Instruction::SDiv, V, V); 140 EXPECT_FALSE(this->clone(SDiv)->isExact()); 141 142 SDiv->setIsExact(true); 143 EXPECT_TRUE(this->clone(SDiv)->isExact()); 144 } 145 146 } 147