[llvm] r268960 - [InstCombine] Fold icmp eq/ne (udiv i32 A, B), 0 -> icmp ugt/ule B, A.
Chad Rosier via llvm-commits
llvm-commits at lists.llvm.org
Mon May 9 12:30:21 PDT 2016
Author: mcrosier
Date: Mon May 9 14:30:20 2016
New Revision: 268960
URL: http://llvm.org/viewvc/llvm-project?rev=268960&view=rev
Log:
[InstCombine] Fold icmp eq/ne (udiv i32 A, B), 0 -> icmp ugt/ule B, A.
Differential Revision: http://reviews.llvm.org/D20036
Added:
llvm/trunk/test/Transforms/InstCombine/compare-udiv.ll
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/trunk/test/Transforms/InstCombine/exact.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=268960&r1=268959&r2=268960&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Mon May 9 14:30:20 2016
@@ -2105,6 +2105,8 @@ Instruction *InstCombiner::visitICmpInst
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
// 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
Added: llvm/trunk/test/Transforms/InstCombine/compare-udiv.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/compare-udiv.ll?rev=268960&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/compare-udiv.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/compare-udiv.ll Mon May 9 14:30:20 2016
@@ -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
+}
Modified: llvm/trunk/test/Transforms/InstCombine/exact.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/exact.ll?rev=268960&r1=268959&r2=268960&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/exact.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/exact.ll Mon May 9 14:30:20 2016
@@ -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 {
More information about the llvm-commits
mailing list