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