Skip to content

Commit

Permalink
Optimize integral reciprocal (udiv 1, x and sdiv 1, x) to not use div…
Browse files Browse the repository at this point in the history
…ision. This fires exactly once in a clang bootstrap, but covers a few different results from http://www.cs.utah.edu/~regehr/souper/

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208750 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
nlewycky committed May 14, 2014
1 parent ee8af3e commit 8f84449
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
21 changes: 20 additions & 1 deletion lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) {
if (Instruction::BinaryOps(LHS->getOpcode()) == I.getOpcode())
if (ConstantInt *LHSRHS = dyn_cast<ConstantInt>(LHS->getOperand(1))) {
if (MultiplyOverflows(RHS, LHSRHS,
I.getOpcode()==Instruction::SDiv))
I.getOpcode() == Instruction::SDiv))
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
return BinaryOperator::Create(I.getOpcode(), LHS->getOperand(0),
ConstantExpr::getMul(RHS, LHSRHS));
Expand All @@ -743,6 +743,25 @@ Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) {
}
}

if (ConstantInt *One = dyn_cast<ConstantInt>(Op0)) {
if (One->isOne() && !I.getType()->isIntegerTy(1)) {
bool isSigned = I.getOpcode() == Instruction::SDiv;
if (isSigned) {
// If Op1 is 0 then it's undefined behaviour, if Op1 is 1 then the
// result is one, if Op1 is -1 then the result is minus one, otherwise
// it's zero.
Value *Inc = Builder->CreateAdd(Op1, One);
Value *Cmp = Builder->CreateICmpULT(
Inc, ConstantInt::get(I.getType(), 3));
return SelectInst::Create(Cmp, Op1, ConstantInt::get(I.getType(), 0));
} else {
// If Op1 is 0 then it's undefined behaviour. If Op1 is 1 then the
// result is one, otherwise it's zero.
return new ZExtInst(Builder->CreateICmpEQ(Op1, One), I.getType());
}
}
}

// See if we can fold away this div instruction.
if (SimplifyDemandedInstructionBits(I))
return &I;
Expand Down
19 changes: 19 additions & 0 deletions test/Transforms/InstCombine/div.ll
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,22 @@ define <2 x i64> @test18(<2 x i64> %x) nounwind {
; CHECK-NEXT: sub <2 x i64> zeroinitializer, %x
; CHECK-NEXT: ret <2 x i64>
}

define i32 @test19(i32 %x) {
%A = udiv i32 1, %x
ret i32 %A
; CHECK-LABEL: @test19(
; CHECK-NEXT: icmp eq i32 %x, 1
; CHECK-NEXT: zext i1 %{{.*}} to i32
; CHECK-NEXT ret i32
}

define i32 @test20(i32 %x) {
%A = sdiv i32 1, %x
ret i32 %A
; CHECK-LABEL: @test20(
; CHECK-NEXT: add i32 %x, 1
; CHECK-NEXT: icmp ult i32 %{{.*}}, 3
; CHECK-NEXT: select i1 %{{.*}}, i32 %x, i32 {{.*}}
; CHECK-NEXT: ret i32
}

0 comments on commit 8f84449

Please sign in to comment.