2012-09-25 01:33:33 +00:00
|
|
|
//===- IntegerDivision.cpp - Unit tests for the integer division code -----===//
|
|
|
|
//
|
2019-01-19 08:50:56 +00:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2012-09-25 01:33:33 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2012-12-04 10:23:08 +00:00
|
|
|
#include "llvm/Transforms/Utils/IntegerDivision.h"
|
2013-01-02 11:36:10 +00:00
|
|
|
#include "llvm/IR/BasicBlock.h"
|
|
|
|
#include "llvm/IR/Function.h"
|
|
|
|
#include "llvm/IR/GlobalValue.h"
|
|
|
|
#include "llvm/IR/IRBuilder.h"
|
|
|
|
#include "llvm/IR/Module.h"
|
2012-12-04 10:23:08 +00:00
|
|
|
#include "gtest/gtest.h"
|
2012-09-25 01:33:33 +00:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2013-11-19 06:54:19 +00:00
|
|
|
|
2012-09-25 01:33:33 +00:00
|
|
|
TEST(IntegerDivision, SDiv) {
|
2016-04-14 21:59:01 +00:00
|
|
|
LLVMContext C;
|
2012-09-25 01:33:33 +00:00
|
|
|
Module M("test division", C);
|
|
|
|
IRBuilder<> Builder(C);
|
|
|
|
|
|
|
|
SmallVector<Type*, 2> ArgTys(2, Builder.getInt32Ty());
|
|
|
|
Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(),
|
|
|
|
ArgTys, false),
|
|
|
|
GlobalValue::ExternalLinkage, "F", &M);
|
Remove getArgumentList() in favor of arg_begin(), args(), etc
Users often call getArgumentList().size(), which is a linear way to get
the number of function arguments. arg_size(), on the other hand, is
constant time.
In general, the fact that arguments are stored in an iplist is an
implementation detail, so I've removed it from the Function interface
and moved all other users to the argument container APIs (arg_begin(),
arg_end(), args(), arg_size()).
Reviewed By: chandlerc
Differential Revision: https://reviews.llvm.org/D31052
llvm-svn: 298010
2017-03-16 22:59:15 +00:00
|
|
|
assert(F->arg_size() == 2);
|
2012-09-25 01:33:33 +00:00
|
|
|
|
|
|
|
BasicBlock *BB = BasicBlock::Create(C, "", F);
|
|
|
|
Builder.SetInsertPoint(BB);
|
|
|
|
|
|
|
|
Function::arg_iterator AI = F->arg_begin();
|
2015-10-20 18:30:20 +00:00
|
|
|
Value *A = &*AI++;
|
|
|
|
Value *B = &*AI++;
|
2012-09-25 01:33:33 +00:00
|
|
|
|
|
|
|
Value *Div = Builder.CreateSDiv(A, B);
|
|
|
|
EXPECT_TRUE(BB->front().getOpcode() == Instruction::SDiv);
|
|
|
|
|
|
|
|
Value *Ret = Builder.CreateRet(Div);
|
|
|
|
|
|
|
|
expandDivision(cast<BinaryOperator>(Div));
|
|
|
|
EXPECT_TRUE(BB->front().getOpcode() == Instruction::AShr);
|
|
|
|
|
|
|
|
Instruction* Quotient = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
|
|
|
|
EXPECT_TRUE(Quotient && Quotient->getOpcode() == Instruction::Sub);
|
|
|
|
}
|
|
|
|
|
2012-09-26 01:55:01 +00:00
|
|
|
TEST(IntegerDivision, UDiv) {
|
2016-04-14 21:59:01 +00:00
|
|
|
LLVMContext C;
|
2012-09-26 01:55:01 +00:00
|
|
|
Module M("test division", C);
|
|
|
|
IRBuilder<> Builder(C);
|
|
|
|
|
|
|
|
SmallVector<Type*, 2> ArgTys(2, Builder.getInt32Ty());
|
|
|
|
Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(),
|
|
|
|
ArgTys, false),
|
|
|
|
GlobalValue::ExternalLinkage, "F", &M);
|
Remove getArgumentList() in favor of arg_begin(), args(), etc
Users often call getArgumentList().size(), which is a linear way to get
the number of function arguments. arg_size(), on the other hand, is
constant time.
In general, the fact that arguments are stored in an iplist is an
implementation detail, so I've removed it from the Function interface
and moved all other users to the argument container APIs (arg_begin(),
arg_end(), args(), arg_size()).
Reviewed By: chandlerc
Differential Revision: https://reviews.llvm.org/D31052
llvm-svn: 298010
2017-03-16 22:59:15 +00:00
|
|
|
assert(F->arg_size() == 2);
|
2012-09-26 01:55:01 +00:00
|
|
|
|
|
|
|
BasicBlock *BB = BasicBlock::Create(C, "", F);
|
|
|
|
Builder.SetInsertPoint(BB);
|
|
|
|
|
|
|
|
Function::arg_iterator AI = F->arg_begin();
|
2015-10-20 18:30:20 +00:00
|
|
|
Value *A = &*AI++;
|
|
|
|
Value *B = &*AI++;
|
2012-09-26 01:55:01 +00:00
|
|
|
|
|
|
|
Value *Div = Builder.CreateUDiv(A, B);
|
|
|
|
EXPECT_TRUE(BB->front().getOpcode() == Instruction::UDiv);
|
|
|
|
|
|
|
|
Value *Ret = Builder.CreateRet(Div);
|
|
|
|
|
|
|
|
expandDivision(cast<BinaryOperator>(Div));
|
|
|
|
EXPECT_TRUE(BB->front().getOpcode() == Instruction::ICmp);
|
|
|
|
|
|
|
|
Instruction* Quotient = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
|
|
|
|
EXPECT_TRUE(Quotient && Quotient->getOpcode() == Instruction::PHI);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(IntegerDivision, SRem) {
|
2016-04-14 21:59:01 +00:00
|
|
|
LLVMContext C;
|
2012-09-26 01:55:01 +00:00
|
|
|
Module M("test remainder", C);
|
|
|
|
IRBuilder<> Builder(C);
|
|
|
|
|
|
|
|
SmallVector<Type*, 2> ArgTys(2, Builder.getInt32Ty());
|
|
|
|
Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(),
|
|
|
|
ArgTys, false),
|
|
|
|
GlobalValue::ExternalLinkage, "F", &M);
|
Remove getArgumentList() in favor of arg_begin(), args(), etc
Users often call getArgumentList().size(), which is a linear way to get
the number of function arguments. arg_size(), on the other hand, is
constant time.
In general, the fact that arguments are stored in an iplist is an
implementation detail, so I've removed it from the Function interface
and moved all other users to the argument container APIs (arg_begin(),
arg_end(), args(), arg_size()).
Reviewed By: chandlerc
Differential Revision: https://reviews.llvm.org/D31052
llvm-svn: 298010
2017-03-16 22:59:15 +00:00
|
|
|
assert(F->arg_size() == 2);
|
2012-09-26 01:55:01 +00:00
|
|
|
|
|
|
|
BasicBlock *BB = BasicBlock::Create(C, "", F);
|
|
|
|
Builder.SetInsertPoint(BB);
|
|
|
|
|
|
|
|
Function::arg_iterator AI = F->arg_begin();
|
2015-10-20 18:30:20 +00:00
|
|
|
Value *A = &*AI++;
|
|
|
|
Value *B = &*AI++;
|
2012-09-26 01:55:01 +00:00
|
|
|
|
|
|
|
Value *Rem = Builder.CreateSRem(A, B);
|
|
|
|
EXPECT_TRUE(BB->front().getOpcode() == Instruction::SRem);
|
|
|
|
|
|
|
|
Value *Ret = Builder.CreateRet(Rem);
|
|
|
|
|
|
|
|
expandRemainder(cast<BinaryOperator>(Rem));
|
|
|
|
EXPECT_TRUE(BB->front().getOpcode() == Instruction::AShr);
|
|
|
|
|
|
|
|
Instruction* Remainder = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
|
|
|
|
EXPECT_TRUE(Remainder && Remainder->getOpcode() == Instruction::Sub);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(IntegerDivision, URem) {
|
2016-04-14 21:59:01 +00:00
|
|
|
LLVMContext C;
|
2012-09-26 01:55:01 +00:00
|
|
|
Module M("test remainder", C);
|
|
|
|
IRBuilder<> Builder(C);
|
|
|
|
|
|
|
|
SmallVector<Type*, 2> ArgTys(2, Builder.getInt32Ty());
|
|
|
|
Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(),
|
|
|
|
ArgTys, false),
|
|
|
|
GlobalValue::ExternalLinkage, "F", &M);
|
Remove getArgumentList() in favor of arg_begin(), args(), etc
Users often call getArgumentList().size(), which is a linear way to get
the number of function arguments. arg_size(), on the other hand, is
constant time.
In general, the fact that arguments are stored in an iplist is an
implementation detail, so I've removed it from the Function interface
and moved all other users to the argument container APIs (arg_begin(),
arg_end(), args(), arg_size()).
Reviewed By: chandlerc
Differential Revision: https://reviews.llvm.org/D31052
llvm-svn: 298010
2017-03-16 22:59:15 +00:00
|
|
|
assert(F->arg_size() == 2);
|
2012-09-26 01:55:01 +00:00
|
|
|
|
|
|
|
BasicBlock *BB = BasicBlock::Create(C, "", F);
|
|
|
|
Builder.SetInsertPoint(BB);
|
|
|
|
|
|
|
|
Function::arg_iterator AI = F->arg_begin();
|
2015-10-20 18:30:20 +00:00
|
|
|
Value *A = &*AI++;
|
|
|
|
Value *B = &*AI++;
|
2012-09-26 01:55:01 +00:00
|
|
|
|
|
|
|
Value *Rem = Builder.CreateURem(A, B);
|
|
|
|
EXPECT_TRUE(BB->front().getOpcode() == Instruction::URem);
|
|
|
|
|
|
|
|
Value *Ret = Builder.CreateRet(Rem);
|
|
|
|
|
|
|
|
expandRemainder(cast<BinaryOperator>(Rem));
|
|
|
|
EXPECT_TRUE(BB->front().getOpcode() == Instruction::ICmp);
|
|
|
|
|
|
|
|
Instruction* Remainder = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
|
|
|
|
EXPECT_TRUE(Remainder && Remainder->getOpcode() == Instruction::Sub);
|
|
|
|
}
|
|
|
|
|
2013-11-19 06:54:19 +00:00
|
|
|
|
|
|
|
TEST(IntegerDivision, SDiv64) {
|
2016-04-14 21:59:01 +00:00
|
|
|
LLVMContext C;
|
2013-11-19 06:54:19 +00:00
|
|
|
Module M("test division", C);
|
|
|
|
IRBuilder<> Builder(C);
|
|
|
|
|
|
|
|
SmallVector<Type*, 2> ArgTys(2, Builder.getInt64Ty());
|
|
|
|
Function *F = Function::Create(FunctionType::get(Builder.getInt64Ty(),
|
|
|
|
ArgTys, false),
|
|
|
|
GlobalValue::ExternalLinkage, "F", &M);
|
Remove getArgumentList() in favor of arg_begin(), args(), etc
Users often call getArgumentList().size(), which is a linear way to get
the number of function arguments. arg_size(), on the other hand, is
constant time.
In general, the fact that arguments are stored in an iplist is an
implementation detail, so I've removed it from the Function interface
and moved all other users to the argument container APIs (arg_begin(),
arg_end(), args(), arg_size()).
Reviewed By: chandlerc
Differential Revision: https://reviews.llvm.org/D31052
llvm-svn: 298010
2017-03-16 22:59:15 +00:00
|
|
|
assert(F->arg_size() == 2);
|
2013-11-19 06:54:19 +00:00
|
|
|
|
|
|
|
BasicBlock *BB = BasicBlock::Create(C, "", F);
|
|
|
|
Builder.SetInsertPoint(BB);
|
|
|
|
|
|
|
|
Function::arg_iterator AI = F->arg_begin();
|
2015-10-20 18:30:20 +00:00
|
|
|
Value *A = &*AI++;
|
|
|
|
Value *B = &*AI++;
|
2013-11-19 06:54:19 +00:00
|
|
|
|
|
|
|
Value *Div = Builder.CreateSDiv(A, B);
|
|
|
|
EXPECT_TRUE(BB->front().getOpcode() == Instruction::SDiv);
|
|
|
|
|
|
|
|
Value *Ret = Builder.CreateRet(Div);
|
|
|
|
|
|
|
|
expandDivision(cast<BinaryOperator>(Div));
|
|
|
|
EXPECT_TRUE(BB->front().getOpcode() == Instruction::AShr);
|
|
|
|
|
|
|
|
Instruction* Quotient = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
|
|
|
|
EXPECT_TRUE(Quotient && Quotient->getOpcode() == Instruction::Sub);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(IntegerDivision, UDiv64) {
|
2016-04-14 21:59:01 +00:00
|
|
|
LLVMContext C;
|
2013-11-19 06:54:19 +00:00
|
|
|
Module M("test division", C);
|
|
|
|
IRBuilder<> Builder(C);
|
|
|
|
|
|
|
|
SmallVector<Type*, 2> ArgTys(2, Builder.getInt64Ty());
|
|
|
|
Function *F = Function::Create(FunctionType::get(Builder.getInt64Ty(),
|
|
|
|
ArgTys, false),
|
|
|
|
GlobalValue::ExternalLinkage, "F", &M);
|
Remove getArgumentList() in favor of arg_begin(), args(), etc
Users often call getArgumentList().size(), which is a linear way to get
the number of function arguments. arg_size(), on the other hand, is
constant time.
In general, the fact that arguments are stored in an iplist is an
implementation detail, so I've removed it from the Function interface
and moved all other users to the argument container APIs (arg_begin(),
arg_end(), args(), arg_size()).
Reviewed By: chandlerc
Differential Revision: https://reviews.llvm.org/D31052
llvm-svn: 298010
2017-03-16 22:59:15 +00:00
|
|
|
assert(F->arg_size() == 2);
|
2013-11-19 06:54:19 +00:00
|
|
|
|
|
|
|
BasicBlock *BB = BasicBlock::Create(C, "", F);
|
|
|
|
Builder.SetInsertPoint(BB);
|
|
|
|
|
|
|
|
Function::arg_iterator AI = F->arg_begin();
|
2015-10-20 18:30:20 +00:00
|
|
|
Value *A = &*AI++;
|
|
|
|
Value *B = &*AI++;
|
2013-11-19 06:54:19 +00:00
|
|
|
|
|
|
|
Value *Div = Builder.CreateUDiv(A, B);
|
|
|
|
EXPECT_TRUE(BB->front().getOpcode() == Instruction::UDiv);
|
|
|
|
|
|
|
|
Value *Ret = Builder.CreateRet(Div);
|
|
|
|
|
|
|
|
expandDivision(cast<BinaryOperator>(Div));
|
|
|
|
EXPECT_TRUE(BB->front().getOpcode() == Instruction::ICmp);
|
|
|
|
|
|
|
|
Instruction* Quotient = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
|
|
|
|
EXPECT_TRUE(Quotient && Quotient->getOpcode() == Instruction::PHI);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(IntegerDivision, SRem64) {
|
2016-04-14 21:59:01 +00:00
|
|
|
LLVMContext C;
|
2013-11-19 06:54:19 +00:00
|
|
|
Module M("test remainder", C);
|
|
|
|
IRBuilder<> Builder(C);
|
|
|
|
|
|
|
|
SmallVector<Type*, 2> ArgTys(2, Builder.getInt64Ty());
|
|
|
|
Function *F = Function::Create(FunctionType::get(Builder.getInt64Ty(),
|
|
|
|
ArgTys, false),
|
|
|
|
GlobalValue::ExternalLinkage, "F", &M);
|
Remove getArgumentList() in favor of arg_begin(), args(), etc
Users often call getArgumentList().size(), which is a linear way to get
the number of function arguments. arg_size(), on the other hand, is
constant time.
In general, the fact that arguments are stored in an iplist is an
implementation detail, so I've removed it from the Function interface
and moved all other users to the argument container APIs (arg_begin(),
arg_end(), args(), arg_size()).
Reviewed By: chandlerc
Differential Revision: https://reviews.llvm.org/D31052
llvm-svn: 298010
2017-03-16 22:59:15 +00:00
|
|
|
assert(F->arg_size() == 2);
|
2013-11-19 06:54:19 +00:00
|
|
|
|
|
|
|
BasicBlock *BB = BasicBlock::Create(C, "", F);
|
|
|
|
Builder.SetInsertPoint(BB);
|
|
|
|
|
|
|
|
Function::arg_iterator AI = F->arg_begin();
|
2015-10-20 18:30:20 +00:00
|
|
|
Value *A = &*AI++;
|
|
|
|
Value *B = &*AI++;
|
2013-11-19 06:54:19 +00:00
|
|
|
|
|
|
|
Value *Rem = Builder.CreateSRem(A, B);
|
|
|
|
EXPECT_TRUE(BB->front().getOpcode() == Instruction::SRem);
|
|
|
|
|
|
|
|
Value *Ret = Builder.CreateRet(Rem);
|
|
|
|
|
|
|
|
expandRemainder(cast<BinaryOperator>(Rem));
|
|
|
|
EXPECT_TRUE(BB->front().getOpcode() == Instruction::AShr);
|
|
|
|
|
|
|
|
Instruction* Remainder = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
|
|
|
|
EXPECT_TRUE(Remainder && Remainder->getOpcode() == Instruction::Sub);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(IntegerDivision, URem64) {
|
2016-04-14 21:59:01 +00:00
|
|
|
LLVMContext C;
|
2013-11-19 06:54:19 +00:00
|
|
|
Module M("test remainder", C);
|
|
|
|
IRBuilder<> Builder(C);
|
|
|
|
|
|
|
|
SmallVector<Type*, 2> ArgTys(2, Builder.getInt64Ty());
|
|
|
|
Function *F = Function::Create(FunctionType::get(Builder.getInt64Ty(),
|
|
|
|
ArgTys, false),
|
|
|
|
GlobalValue::ExternalLinkage, "F", &M);
|
Remove getArgumentList() in favor of arg_begin(), args(), etc
Users often call getArgumentList().size(), which is a linear way to get
the number of function arguments. arg_size(), on the other hand, is
constant time.
In general, the fact that arguments are stored in an iplist is an
implementation detail, so I've removed it from the Function interface
and moved all other users to the argument container APIs (arg_begin(),
arg_end(), args(), arg_size()).
Reviewed By: chandlerc
Differential Revision: https://reviews.llvm.org/D31052
llvm-svn: 298010
2017-03-16 22:59:15 +00:00
|
|
|
assert(F->arg_size() == 2);
|
2013-11-19 06:54:19 +00:00
|
|
|
|
|
|
|
BasicBlock *BB = BasicBlock::Create(C, "", F);
|
|
|
|
Builder.SetInsertPoint(BB);
|
|
|
|
|
|
|
|
Function::arg_iterator AI = F->arg_begin();
|
2015-10-20 18:30:20 +00:00
|
|
|
Value *A = &*AI++;
|
|
|
|
Value *B = &*AI++;
|
2013-11-19 06:54:19 +00:00
|
|
|
|
|
|
|
Value *Rem = Builder.CreateURem(A, B);
|
|
|
|
EXPECT_TRUE(BB->front().getOpcode() == Instruction::URem);
|
|
|
|
|
|
|
|
Value *Ret = Builder.CreateRet(Rem);
|
|
|
|
|
|
|
|
expandRemainder(cast<BinaryOperator>(Rem));
|
|
|
|
EXPECT_TRUE(BB->front().getOpcode() == Instruction::ICmp);
|
|
|
|
|
|
|
|
Instruction* Remainder = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
|
|
|
|
EXPECT_TRUE(Remainder && Remainder->getOpcode() == Instruction::Sub);
|
|
|
|
}
|
|
|
|
|
2012-09-25 01:33:33 +00:00
|
|
|
}
|