mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-20 03:23:01 +02:00
[InstCombine] Fold icmp eq/ne (udiv i32 A, B), 0 -> icmp ugt/ule B, A.
Differential Revision: http://reviews.llvm.org/D20036 llvm-svn: 268960
This commit is contained in:
parent
89c9635b0a
commit
8b41062bd4
@ -2105,6 +2105,8 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
|
||||
if (Instruction *R = FoldICmpDivCst(ICI, cast<BinaryOperator>(LHSI),
|
||||
DivRHS))
|
||||
return R;
|
||||
// FIXME: Handle (icmp ugt (udiv i32 CI2, A), CI) and
|
||||
// (icmp ult (udiv i32 CI2, A), CI).
|
||||
break;
|
||||
|
||||
case Instruction::Sub: {
|
||||
@ -3583,12 +3585,22 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
|
||||
// See if we are doing a comparison between a constant and an instruction that
|
||||
// can be folded into the comparison.
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
|
||||
Value *A = nullptr, *B = nullptr;
|
||||
// Since the RHS is a ConstantInt (CI), if the left hand side is an
|
||||
// instruction, see if that instruction also has constants so that the
|
||||
// instruction can be folded into the icmp
|
||||
if (Instruction *LHSI = dyn_cast<Instruction>(Op0))
|
||||
if (Instruction *Res = visitICmpInstWithInstAndIntCst(I, LHSI, CI))
|
||||
return Res;
|
||||
|
||||
// (icmp eq/ne (udiv A, B), 0) -> (icmp ugt/ule i32 B, A)
|
||||
if (I.isEquality() && CI->isZero() &&
|
||||
match(Op0, m_UDiv(m_Value(A), m_Value(B)))) {
|
||||
ICmpInst::Predicate Pred = I.getPredicate() == ICmpInst::ICMP_EQ
|
||||
? ICmpInst::ICMP_UGT
|
||||
: ICmpInst::ICMP_ULE;
|
||||
return new ICmpInst(Pred, B, A);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle icmp with constant (but not simple integer constant) RHS
|
||||
|
41
test/Transforms/InstCombine/compare-udiv.ll
Normal file
41
test/Transforms/InstCombine/compare-udiv.ll
Normal file
@ -0,0 +1,41 @@
|
||||
; RUN: opt -instcombine -S < %s | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: @test1
|
||||
; CHECK: %cmp1 = icmp ugt i32 %d, %n
|
||||
define i1 @test1(i32 %n, i32 %d) {
|
||||
%div = udiv i32 %n, %d
|
||||
%cmp1 = icmp eq i32 %div, 0
|
||||
ret i1 %cmp1
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @test2
|
||||
; CHECK: %cmp1 = icmp ugt i32 %d, 64
|
||||
define i1 @test2(i32 %d) {
|
||||
%div = udiv i32 64, %d
|
||||
%cmp1 = icmp eq i32 %div, 0
|
||||
ret i1 %cmp1
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @test3
|
||||
; CHECK: %cmp1 = icmp ule i32 %d, %n
|
||||
define i1 @test3(i32 %n, i32 %d) {
|
||||
%div = udiv i32 %n, %d
|
||||
%cmp1 = icmp ne i32 %div, 0
|
||||
ret i1 %cmp1
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @test4
|
||||
; CHECK: %cmp1 = icmp ult i32 %d, 65
|
||||
define i1 @test4(i32 %d) {
|
||||
%div = udiv i32 64, %d
|
||||
%cmp1 = icmp ne i32 %div, 0
|
||||
ret i1 %cmp1
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @test5
|
||||
; CHECK: ret i1 true
|
||||
define i1 @test5(i32 %d) {
|
||||
%div = udiv i32 -1, %d
|
||||
%cmp1 = icmp ne i32 %div, 0
|
||||
ret i1 %cmp1
|
||||
}
|
@ -121,6 +121,14 @@ define i1 @udiv_icmp1(i64 %X) nounwind {
|
||||
ret i1 %B
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @udiv_icmp2(
|
||||
; CHECK: icmp eq i64 %X, 0
|
||||
define i1 @udiv_icmp2(i64 %X) nounwind {
|
||||
%A = udiv exact i64 %X, 5 ; X/5 == 0 --> x == 0
|
||||
%B = icmp eq i64 %A, 0
|
||||
ret i1 %B
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @sdiv_icmp1(
|
||||
; CHECK: icmp eq i64 %X, 0
|
||||
define i1 @sdiv_icmp1(i64 %X) nounwind {
|
||||
|
Loading…
Reference in New Issue
Block a user