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 "llvm/ADT/STLExtras.h" 11 #include "llvm/ADT/SmallPtrSet.h" 12 #include "llvm/IR/Argument.h" 13 #include "llvm/IR/Constant.h" 14 #include "llvm/IR/Function.h" 15 #include "llvm/IR/Instructions.h" 16 #include "llvm/IR/IRBuilder.h" 17 #include "llvm/IR/LLVMContext.h" 18 #include "llvm/Transforms/Utils/Cloning.h" 19 #include "gtest/gtest.h" 20 21 using namespace llvm; 22 23 namespace { 24 25 class CloneInstruction : public ::testing::Test { 26 protected: 27 virtual void SetUp() { 28 V = NULL; 29 } 30 31 template <typename T> 32 T *clone(T *V1) { 33 Value *V2 = V1->clone(); 34 Orig.insert(V1); 35 Clones.insert(V2); 36 return cast<T>(V2); 37 } 38 39 void eraseClones() { 40 DeleteContainerPointers(Clones); 41 } 42 43 virtual void TearDown() { 44 eraseClones(); 45 DeleteContainerPointers(Orig); 46 delete V; 47 } 48 49 SmallPtrSet<Value *, 4> Orig; // Erase on exit 50 SmallPtrSet<Value *, 4> Clones; // Erase in eraseClones 51 52 LLVMContext context; 53 Value *V; 54 }; 55 56 TEST_F(CloneInstruction, OverflowBits) { 57 V = new Argument(Type::getInt32Ty(context)); 58 59 BinaryOperator *Add = BinaryOperator::Create(Instruction::Add, V, V); 60 BinaryOperator *Sub = BinaryOperator::Create(Instruction::Sub, V, V); 61 BinaryOperator *Mul = BinaryOperator::Create(Instruction::Mul, V, V); 62 63 BinaryOperator *AddClone = this->clone(Add); 64 BinaryOperator *SubClone = this->clone(Sub); 65 BinaryOperator *MulClone = this->clone(Mul); 66 67 EXPECT_FALSE(AddClone->hasNoUnsignedWrap()); 68 EXPECT_FALSE(AddClone->hasNoSignedWrap()); 69 EXPECT_FALSE(SubClone->hasNoUnsignedWrap()); 70 EXPECT_FALSE(SubClone->hasNoSignedWrap()); 71 EXPECT_FALSE(MulClone->hasNoUnsignedWrap()); 72 EXPECT_FALSE(MulClone->hasNoSignedWrap()); 73 74 eraseClones(); 75 76 Add->setHasNoUnsignedWrap(); 77 Sub->setHasNoUnsignedWrap(); 78 Mul->setHasNoUnsignedWrap(); 79 80 AddClone = this->clone(Add); 81 SubClone = this->clone(Sub); 82 MulClone = this->clone(Mul); 83 84 EXPECT_TRUE(AddClone->hasNoUnsignedWrap()); 85 EXPECT_FALSE(AddClone->hasNoSignedWrap()); 86 EXPECT_TRUE(SubClone->hasNoUnsignedWrap()); 87 EXPECT_FALSE(SubClone->hasNoSignedWrap()); 88 EXPECT_TRUE(MulClone->hasNoUnsignedWrap()); 89 EXPECT_FALSE(MulClone->hasNoSignedWrap()); 90 91 eraseClones(); 92 93 Add->setHasNoSignedWrap(); 94 Sub->setHasNoSignedWrap(); 95 Mul->setHasNoSignedWrap(); 96 97 AddClone = this->clone(Add); 98 SubClone = this->clone(Sub); 99 MulClone = this->clone(Mul); 100 101 EXPECT_TRUE(AddClone->hasNoUnsignedWrap()); 102 EXPECT_TRUE(AddClone->hasNoSignedWrap()); 103 EXPECT_TRUE(SubClone->hasNoUnsignedWrap()); 104 EXPECT_TRUE(SubClone->hasNoSignedWrap()); 105 EXPECT_TRUE(MulClone->hasNoUnsignedWrap()); 106 EXPECT_TRUE(MulClone->hasNoSignedWrap()); 107 108 eraseClones(); 109 110 Add->setHasNoUnsignedWrap(false); 111 Sub->setHasNoUnsignedWrap(false); 112 Mul->setHasNoUnsignedWrap(false); 113 114 AddClone = this->clone(Add); 115 SubClone = this->clone(Sub); 116 MulClone = this->clone(Mul); 117 118 EXPECT_FALSE(AddClone->hasNoUnsignedWrap()); 119 EXPECT_TRUE(AddClone->hasNoSignedWrap()); 120 EXPECT_FALSE(SubClone->hasNoUnsignedWrap()); 121 EXPECT_TRUE(SubClone->hasNoSignedWrap()); 122 EXPECT_FALSE(MulClone->hasNoUnsignedWrap()); 123 EXPECT_TRUE(MulClone->hasNoSignedWrap()); 124 } 125 126 TEST_F(CloneInstruction, Inbounds) { 127 V = new Argument(Type::getInt32PtrTy(context)); 128 129 Constant *Z = Constant::getNullValue(Type::getInt32Ty(context)); 130 std::vector<Value *> ops; 131 ops.push_back(Z); 132 GetElementPtrInst *GEP = GetElementPtrInst::Create(V, ops); 133 EXPECT_FALSE(this->clone(GEP)->isInBounds()); 134 135 GEP->setIsInBounds(); 136 EXPECT_TRUE(this->clone(GEP)->isInBounds()); 137 } 138 139 TEST_F(CloneInstruction, Exact) { 140 V = new Argument(Type::getInt32Ty(context)); 141 142 BinaryOperator *SDiv = BinaryOperator::Create(Instruction::SDiv, V, V); 143 EXPECT_FALSE(this->clone(SDiv)->isExact()); 144 145 SDiv->setIsExact(true); 146 EXPECT_TRUE(this->clone(SDiv)->isExact()); 147 } 148 149 TEST_F(CloneInstruction, Attributes) { 150 Type *ArgTy1[] = { Type::getInt32PtrTy(context) }; 151 FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false); 152 153 Function *F1 = Function::Create(FT1, Function::ExternalLinkage); 154 BasicBlock *BB = BasicBlock::Create(context, "", F1); 155 IRBuilder<> Builder(BB); 156 Builder.CreateRetVoid(); 157 158 Function *F2 = Function::Create(FT1, Function::ExternalLinkage); 159 160 Attribute::AttrKind AK[] = { Attribute::NoCapture }; 161 AttributeSet AS = AttributeSet::get(context, 0, AK); 162 Argument *A = F1->arg_begin(); 163 A->addAttr(AS); 164 165 SmallVector<ReturnInst*, 4> Returns; 166 ValueToValueMapTy VMap; 167 VMap[A] = UndefValue::get(A->getType()); 168 169 CloneFunctionInto(F2, F1, VMap, false, Returns); 170 EXPECT_FALSE(F2->arg_begin()->hasNoCaptureAttr()); 171 172 delete F1; 173 delete F2; 174 } 175 176 } 177