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