mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 17:32:19 +00:00
Optimize integral reciprocal (udiv 1, x and sdiv 1, x) to not use division. 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
This commit is contained in:
parent
ee8af3e2a0
commit
8f84449093
@ -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));
|
||||
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user