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 18using namespace llvm; 19 20namespace { 21 22class CloneInstruction : public ::testing::Test { 23protected: 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 53TEST_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 123TEST_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 136TEST_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