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 class CloneInstruction : public ::testing::Test {
21 protected:
SetUp()22   virtual void SetUp() {
23     V = NULL;
24   }
25 
26   template <typename T>
clone(T * V1)27   T *clone(T *V1) {
28     Value *V2 = V1->clone();
29     Orig.insert(V1);
30     Clones.insert(V2);
31     return cast<T>(V2);
32   }
33 
eraseClones()34   void eraseClones() {
35     DeleteContainerPointers(Clones);
36   }
37 
TearDown()38   virtual void TearDown() {
39     eraseClones();
40     DeleteContainerPointers(Orig);
41     delete V;
42   }
43 
44   SmallPtrSet<Value *, 4> Orig;   // Erase on exit
45   SmallPtrSet<Value *, 4> Clones; // Erase in eraseClones
46 
47   LLVMContext context;
48   Value *V;
49 };
50 
TEST_F(CloneInstruction,OverflowBits)51 TEST_F(CloneInstruction, OverflowBits) {
52   V = new Argument(Type::getInt32Ty(context));
53 
54   BinaryOperator *Add = BinaryOperator::Create(Instruction::Add, V, V);
55   BinaryOperator *Sub = BinaryOperator::Create(Instruction::Sub, V, V);
56   BinaryOperator *Mul = BinaryOperator::Create(Instruction::Mul, V, V);
57 
58   BinaryOperator *AddClone = this->clone(Add);
59   BinaryOperator *SubClone = this->clone(Sub);
60   BinaryOperator *MulClone = this->clone(Mul);
61 
62   EXPECT_FALSE(AddClone->hasNoUnsignedWrap());
63   EXPECT_FALSE(AddClone->hasNoSignedWrap());
64   EXPECT_FALSE(SubClone->hasNoUnsignedWrap());
65   EXPECT_FALSE(SubClone->hasNoSignedWrap());
66   EXPECT_FALSE(MulClone->hasNoUnsignedWrap());
67   EXPECT_FALSE(MulClone->hasNoSignedWrap());
68 
69   eraseClones();
70 
71   Add->setHasNoUnsignedWrap();
72   Sub->setHasNoUnsignedWrap();
73   Mul->setHasNoUnsignedWrap();
74 
75   AddClone = this->clone(Add);
76   SubClone = this->clone(Sub);
77   MulClone = this->clone(Mul);
78 
79   EXPECT_TRUE(AddClone->hasNoUnsignedWrap());
80   EXPECT_FALSE(AddClone->hasNoSignedWrap());
81   EXPECT_TRUE(SubClone->hasNoUnsignedWrap());
82   EXPECT_FALSE(SubClone->hasNoSignedWrap());
83   EXPECT_TRUE(MulClone->hasNoUnsignedWrap());
84   EXPECT_FALSE(MulClone->hasNoSignedWrap());
85 
86   eraseClones();
87 
88   Add->setHasNoSignedWrap();
89   Sub->setHasNoSignedWrap();
90   Mul->setHasNoSignedWrap();
91 
92   AddClone = this->clone(Add);
93   SubClone = this->clone(Sub);
94   MulClone = this->clone(Mul);
95 
96   EXPECT_TRUE(AddClone->hasNoUnsignedWrap());
97   EXPECT_TRUE(AddClone->hasNoSignedWrap());
98   EXPECT_TRUE(SubClone->hasNoUnsignedWrap());
99   EXPECT_TRUE(SubClone->hasNoSignedWrap());
100   EXPECT_TRUE(MulClone->hasNoUnsignedWrap());
101   EXPECT_TRUE(MulClone->hasNoSignedWrap());
102 
103   eraseClones();
104 
105   Add->setHasNoUnsignedWrap(false);
106   Sub->setHasNoUnsignedWrap(false);
107   Mul->setHasNoUnsignedWrap(false);
108 
109   AddClone = this->clone(Add);
110   SubClone = this->clone(Sub);
111   MulClone = this->clone(Mul);
112 
113   EXPECT_FALSE(AddClone->hasNoUnsignedWrap());
114   EXPECT_TRUE(AddClone->hasNoSignedWrap());
115   EXPECT_FALSE(SubClone->hasNoUnsignedWrap());
116   EXPECT_TRUE(SubClone->hasNoSignedWrap());
117   EXPECT_FALSE(MulClone->hasNoUnsignedWrap());
118   EXPECT_TRUE(MulClone->hasNoSignedWrap());
119 }
120 
TEST_F(CloneInstruction,Inbounds)121 TEST_F(CloneInstruction, Inbounds) {
122   V = new Argument(Type::getInt32PtrTy(context));
123 
124   Constant *Z = Constant::getNullValue(Type::getInt32Ty(context));
125   std::vector<Value *> ops;
126   ops.push_back(Z);
127   GetElementPtrInst *GEP = GetElementPtrInst::Create(V, ops);
128   EXPECT_FALSE(this->clone(GEP)->isInBounds());
129 
130   GEP->setIsInBounds();
131   EXPECT_TRUE(this->clone(GEP)->isInBounds());
132 }
133 
TEST_F(CloneInstruction,Exact)134 TEST_F(CloneInstruction, Exact) {
135   V = new Argument(Type::getInt32Ty(context));
136 
137   BinaryOperator *SDiv = BinaryOperator::Create(Instruction::SDiv, V, V);
138   EXPECT_FALSE(this->clone(SDiv)->isExact());
139 
140   SDiv->setIsExact(true);
141   EXPECT_TRUE(this->clone(SDiv)->isExact());
142 }
143