]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
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 | ||
223e47cc | 10 | #include "llvm/Transforms/Utils/IntegerDivision.h" |
970d7e83 LB |
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" | |
223e47cc LB |
17 | |
18 | using namespace llvm; | |
19 | ||
20 | namespace { | |
21 | ||
1a4d82fc | 22 | |
223e47cc LB |
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 | ||
1a4d82fc JJ |
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 | ||
223e47cc | 264 | } |