unittests: Remove implicit ilist iterator conversions, NFC
[oota-llvm.git] / unittests / Transforms / Utils / IntegerDivision.cpp
1 //===- IntegerDivision.cpp - Unit tests for the integer division code -----===//
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/Transforms/Utils/IntegerDivision.h"
11 #include "llvm/IR/BasicBlock.h"
12 #include "llvm/IR/Function.h"
13 #include "llvm/IR/GlobalValue.h"
14 #include "llvm/IR/IRBuilder.h"
15 #include "llvm/IR/Module.h"
16 #include "gtest/gtest.h"
17
18 using namespace llvm;
19
20 namespace {
21
22
23 TEST(IntegerDivision, SDiv) {
24   LLVMContext &C(getGlobalContext());
25   Module M("test division", C);
26   IRBuilder<> Builder(C);
27
28   SmallVector<Type*, 2> ArgTys(2, Builder.getInt32Ty());
29   Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(),
30                                                    ArgTys, false),
31                                  GlobalValue::ExternalLinkage, "F", &M);
32   assert(F->getArgumentList().size() == 2);
33
34   BasicBlock *BB = BasicBlock::Create(C, "", F);
35   Builder.SetInsertPoint(BB);
36
37   Function::arg_iterator AI = F->arg_begin();
38   Value *A = &*AI++;
39   Value *B = &*AI++;
40
41   Value *Div = Builder.CreateSDiv(A, B);
42   EXPECT_TRUE(BB->front().getOpcode() == Instruction::SDiv);
43
44   Value *Ret = Builder.CreateRet(Div);
45
46   expandDivision(cast<BinaryOperator>(Div));
47   EXPECT_TRUE(BB->front().getOpcode() == Instruction::AShr);
48
49   Instruction* Quotient = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
50   EXPECT_TRUE(Quotient && Quotient->getOpcode() == Instruction::Sub);
51 }
52
53 TEST(IntegerDivision, UDiv) {
54   LLVMContext &C(getGlobalContext());
55   Module M("test division", C);
56   IRBuilder<> Builder(C);
57
58   SmallVector<Type*, 2> ArgTys(2, Builder.getInt32Ty());
59   Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(),
60                                                    ArgTys, false),
61                                  GlobalValue::ExternalLinkage, "F", &M);
62   assert(F->getArgumentList().size() == 2);
63
64   BasicBlock *BB = BasicBlock::Create(C, "", F);
65   Builder.SetInsertPoint(BB);
66
67   Function::arg_iterator AI = F->arg_begin();
68   Value *A = &*AI++;
69   Value *B = &*AI++;
70
71   Value *Div = Builder.CreateUDiv(A, B);
72   EXPECT_TRUE(BB->front().getOpcode() == Instruction::UDiv);
73
74   Value *Ret = Builder.CreateRet(Div);
75
76   expandDivision(cast<BinaryOperator>(Div));
77   EXPECT_TRUE(BB->front().getOpcode() == Instruction::ICmp);
78
79   Instruction* Quotient = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
80   EXPECT_TRUE(Quotient && Quotient->getOpcode() == Instruction::PHI);
81 }
82
83 TEST(IntegerDivision, SRem) {
84   LLVMContext &C(getGlobalContext());
85   Module M("test remainder", C);
86   IRBuilder<> Builder(C);
87
88   SmallVector<Type*, 2> ArgTys(2, Builder.getInt32Ty());
89   Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(),
90                                                    ArgTys, false),
91                                  GlobalValue::ExternalLinkage, "F", &M);
92   assert(F->getArgumentList().size() == 2);
93
94   BasicBlock *BB = BasicBlock::Create(C, "", F);
95   Builder.SetInsertPoint(BB);
96
97   Function::arg_iterator AI = F->arg_begin();
98   Value *A = &*AI++;
99   Value *B = &*AI++;
100
101   Value *Rem = Builder.CreateSRem(A, B);
102   EXPECT_TRUE(BB->front().getOpcode() == Instruction::SRem);
103
104   Value *Ret = Builder.CreateRet(Rem);
105
106   expandRemainder(cast<BinaryOperator>(Rem));
107   EXPECT_TRUE(BB->front().getOpcode() == Instruction::AShr);
108
109   Instruction* Remainder = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
110   EXPECT_TRUE(Remainder && Remainder->getOpcode() == Instruction::Sub);
111 }
112
113 TEST(IntegerDivision, URem) {
114   LLVMContext &C(getGlobalContext());
115   Module M("test remainder", C);
116   IRBuilder<> Builder(C);
117
118   SmallVector<Type*, 2> ArgTys(2, Builder.getInt32Ty());
119   Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(),
120                                                    ArgTys, false),
121                                  GlobalValue::ExternalLinkage, "F", &M);
122   assert(F->getArgumentList().size() == 2);
123
124   BasicBlock *BB = BasicBlock::Create(C, "", F);
125   Builder.SetInsertPoint(BB);
126
127   Function::arg_iterator AI = F->arg_begin();
128   Value *A = &*AI++;
129   Value *B = &*AI++;
130
131   Value *Rem = Builder.CreateURem(A, B);
132   EXPECT_TRUE(BB->front().getOpcode() == Instruction::URem);
133
134   Value *Ret = Builder.CreateRet(Rem);
135
136   expandRemainder(cast<BinaryOperator>(Rem));
137   EXPECT_TRUE(BB->front().getOpcode() == Instruction::ICmp);
138
139   Instruction* Remainder = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
140   EXPECT_TRUE(Remainder && Remainder->getOpcode() == Instruction::Sub);
141 }
142
143
144 TEST(IntegerDivision, SDiv64) {
145   LLVMContext &C(getGlobalContext());
146   Module M("test division", C);
147   IRBuilder<> Builder(C);
148
149   SmallVector<Type*, 2> ArgTys(2, Builder.getInt64Ty());
150   Function *F = Function::Create(FunctionType::get(Builder.getInt64Ty(),
151                                                    ArgTys, false),
152                                  GlobalValue::ExternalLinkage, "F", &M);
153   assert(F->getArgumentList().size() == 2);
154
155   BasicBlock *BB = BasicBlock::Create(C, "", F);
156   Builder.SetInsertPoint(BB);
157
158   Function::arg_iterator AI = F->arg_begin();
159   Value *A = &*AI++;
160   Value *B = &*AI++;
161
162   Value *Div = Builder.CreateSDiv(A, B);
163   EXPECT_TRUE(BB->front().getOpcode() == Instruction::SDiv);
164
165   Value *Ret = Builder.CreateRet(Div);
166
167   expandDivision(cast<BinaryOperator>(Div));
168   EXPECT_TRUE(BB->front().getOpcode() == Instruction::AShr);
169
170   Instruction* Quotient = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
171   EXPECT_TRUE(Quotient && Quotient->getOpcode() == Instruction::Sub);
172 }
173
174 TEST(IntegerDivision, UDiv64) {
175   LLVMContext &C(getGlobalContext());
176   Module M("test division", C);
177   IRBuilder<> Builder(C);
178
179   SmallVector<Type*, 2> ArgTys(2, Builder.getInt64Ty());
180   Function *F = Function::Create(FunctionType::get(Builder.getInt64Ty(),
181                                                    ArgTys, false),
182                                  GlobalValue::ExternalLinkage, "F", &M);
183   assert(F->getArgumentList().size() == 2);
184
185   BasicBlock *BB = BasicBlock::Create(C, "", F);
186   Builder.SetInsertPoint(BB);
187
188   Function::arg_iterator AI = F->arg_begin();
189   Value *A = &*AI++;
190   Value *B = &*AI++;
191
192   Value *Div = Builder.CreateUDiv(A, B);
193   EXPECT_TRUE(BB->front().getOpcode() == Instruction::UDiv);
194
195   Value *Ret = Builder.CreateRet(Div);
196
197   expandDivision(cast<BinaryOperator>(Div));
198   EXPECT_TRUE(BB->front().getOpcode() == Instruction::ICmp);
199
200   Instruction* Quotient = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
201   EXPECT_TRUE(Quotient && Quotient->getOpcode() == Instruction::PHI);
202 }
203
204 TEST(IntegerDivision, SRem64) {
205   LLVMContext &C(getGlobalContext());
206   Module M("test remainder", C);
207   IRBuilder<> Builder(C);
208
209   SmallVector<Type*, 2> ArgTys(2, Builder.getInt64Ty());
210   Function *F = Function::Create(FunctionType::get(Builder.getInt64Ty(),
211                                                    ArgTys, false),
212                                  GlobalValue::ExternalLinkage, "F", &M);
213   assert(F->getArgumentList().size() == 2);
214
215   BasicBlock *BB = BasicBlock::Create(C, "", F);
216   Builder.SetInsertPoint(BB);
217
218   Function::arg_iterator AI = F->arg_begin();
219   Value *A = &*AI++;
220   Value *B = &*AI++;
221
222   Value *Rem = Builder.CreateSRem(A, B);
223   EXPECT_TRUE(BB->front().getOpcode() == Instruction::SRem);
224
225   Value *Ret = Builder.CreateRet(Rem);
226
227   expandRemainder(cast<BinaryOperator>(Rem));
228   EXPECT_TRUE(BB->front().getOpcode() == Instruction::AShr);
229
230   Instruction* Remainder = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
231   EXPECT_TRUE(Remainder && Remainder->getOpcode() == Instruction::Sub);
232 }
233
234 TEST(IntegerDivision, URem64) {
235   LLVMContext &C(getGlobalContext());
236   Module M("test remainder", C);
237   IRBuilder<> Builder(C);
238
239   SmallVector<Type*, 2> ArgTys(2, Builder.getInt64Ty());
240   Function *F = Function::Create(FunctionType::get(Builder.getInt64Ty(),
241                                                    ArgTys, false),
242                                  GlobalValue::ExternalLinkage, "F", &M);
243   assert(F->getArgumentList().size() == 2);
244
245   BasicBlock *BB = BasicBlock::Create(C, "", F);
246   Builder.SetInsertPoint(BB);
247
248   Function::arg_iterator AI = F->arg_begin();
249   Value *A = &*AI++;
250   Value *B = &*AI++;
251
252   Value *Rem = Builder.CreateURem(A, B);
253   EXPECT_TRUE(BB->front().getOpcode() == Instruction::URem);
254
255   Value *Ret = Builder.CreateRet(Rem);
256
257   expandRemainder(cast<BinaryOperator>(Rem));
258   EXPECT_TRUE(BB->front().getOpcode() == Instruction::ICmp);
259
260   Instruction* Remainder = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
261   EXPECT_TRUE(Remainder && Remainder->getOpcode() == Instruction::Sub);
262 }
263
264 }