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
20class CloneInstruction : public ::testing::Test {
21protected:
22  virtual void SetUp() {
23    V = NULL;
24  }
25
26  template <typename T>
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
34  void eraseClones() {
35    DeleteContainerPointers(Clones);
36  }
37
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
51TEST_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
121TEST_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
134TEST_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