diff options
author | Michael Ilseman <milseman@apple.com> | 2013-11-19 06:54:19 +0000 |
---|---|---|
committer | Michael Ilseman <milseman@apple.com> | 2013-11-19 06:54:19 +0000 |
commit | d930c19d2090a05bfd30046fc0bfa4c721a07dea (patch) | |
tree | 4a77db960af6713c8820698fcb9929e1c1501524 /llvm/unittests/Transforms | |
parent | 01b337dc2d16d10b4cbc8d1ee346ad122deb72dd (diff) | |
download | bcm5719-llvm-d930c19d2090a05bfd30046fc0bfa4c721a07dea.tar.gz bcm5719-llvm-d930c19d2090a05bfd30046fc0bfa4c721a07dea.zip |
Add support for software expansion of 64-bit integer division instructions.
Patch by Dmitri Shtilman!
llvm-svn: 195116
Diffstat (limited to 'llvm/unittests/Transforms')
-rw-r--r-- | llvm/unittests/Transforms/Utils/IntegerDivision.cpp | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/llvm/unittests/Transforms/Utils/IntegerDivision.cpp b/llvm/unittests/Transforms/Utils/IntegerDivision.cpp index 44c2328ee35..f7318a2e789 100644 --- a/llvm/unittests/Transforms/Utils/IntegerDivision.cpp +++ b/llvm/unittests/Transforms/Utils/IntegerDivision.cpp @@ -19,6 +19,7 @@ using namespace llvm; namespace { + TEST(IntegerDivision, SDiv) { LLVMContext &C(getGlobalContext()); Module M("test division", C); @@ -139,4 +140,125 @@ TEST(IntegerDivision, URem) { EXPECT_TRUE(Remainder && Remainder->getOpcode() == Instruction::Sub); } + +TEST(IntegerDivision, SDiv64) { + LLVMContext &C(getGlobalContext()); + 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); + assert(F->getArgumentList().size() == 2); + + BasicBlock *BB = BasicBlock::Create(C, "", F); + Builder.SetInsertPoint(BB); + + Function::arg_iterator AI = F->arg_begin(); + Value *A = AI++; + Value *B = AI++; + + 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) { + LLVMContext &C(getGlobalContext()); + 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); + assert(F->getArgumentList().size() == 2); + + BasicBlock *BB = BasicBlock::Create(C, "", F); + Builder.SetInsertPoint(BB); + + Function::arg_iterator AI = F->arg_begin(); + Value *A = AI++; + Value *B = AI++; + + 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) { + LLVMContext &C(getGlobalContext()); + 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); + assert(F->getArgumentList().size() == 2); + + BasicBlock *BB = BasicBlock::Create(C, "", F); + Builder.SetInsertPoint(BB); + + Function::arg_iterator AI = F->arg_begin(); + Value *A = AI++; + Value *B = AI++; + + 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) { + LLVMContext &C(getGlobalContext()); + 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); + assert(F->getArgumentList().size() == 2); + + BasicBlock *BB = BasicBlock::Create(C, "", F); + Builder.SetInsertPoint(BB); + + Function::arg_iterator AI = F->arg_begin(); + Value *A = AI++; + Value *B = AI++; + + 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); +} + } |