[PATCH] D20036: [InstCombine] Fold icmp eq/ne (udiv i32 CI2, A), 0 -> icmp ugt/ule A, CI2

Chad Rosier via llvm-commits llvm-commits at lists.llvm.org
Fri May 6 15:25:27 PDT 2016


mcrosier created this revision.
mcrosier added a reviewer: majnemer.
mcrosier added a subscriber: llvm-commits.

Assuming it's fair game to remove the udiv with a potentially zero denominator (I believe this is undef behavior).

Please take a look,
 Chad

http://reviews.llvm.org/D20036

Files:
  lib/Transforms/InstCombine/InstCombineCompares.cpp
  lib/Transforms/InstCombine/InstCombineInternal.h
  test/Transforms/InstCombine/compare-udiv.ll

Index: test/Transforms/InstCombine/compare-udiv.ll
===================================================================
--- /dev/null
+++ test/Transforms/InstCombine/compare-udiv.ll
@@ -0,0 +1,17 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s
+
+; CHECK-LABEL: @test1
+; CHECK: %cmp1 = icmp ugt i32 %a, 64
+define i1 @test1(i32 %a) {
+  %div = udiv i32 64, %a
+  %cmp1 = icmp eq i32 %div, 0
+  ret i1 %cmp1
+}
+
+; CHECK-LABEL: @test2
+; CHECK: %cmp1 = icmp ult i32 %a, 65
+define i1 @test2(i32 %a) {
+  %div = udiv i32 64, %a
+  %cmp1 = icmp ne i32 %div, 0
+  ret i1 %cmp1
+}
Index: lib/Transforms/InstCombine/InstCombineInternal.h
===================================================================
--- lib/Transforms/InstCombine/InstCombineInternal.h
+++ lib/Transforms/InstCombine/InstCombineInternal.h
@@ -280,6 +280,8 @@
                                  ConstantInt *CI1, ConstantInt *CI2);
   Instruction *FoldICmpCstShlCst(ICmpInst &I, Value *Op, Value *A,
                                  ConstantInt *CI1, ConstantInt *CI2);
+  Instruction *FoldICmpCstUDivCst(ICmpInst &I, Value *Op, ConstantInt *CI1,
+                                  ConstantInt *CI2, Value *A);
   Instruction *FoldICmpAddOpCst(Instruction &ICI, Value *X, ConstantInt *CI,
                                 ICmpInst::Predicate Pred);
   Instruction *FoldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
Index: lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1537,6 +1537,22 @@
   return getConstant(false);
 }
 
+Instruction *InstCombiner::FoldICmpCstUDivCst(ICmpInst &I, Value *Op,
+                                              ConstantInt *CI1,
+                                              ConstantInt *CI2, Value *A) {
+  // (icmp eq/ne (udiv i32 CI2, A), 0) -> (icmp ugt/ule A, CI2)
+  if (I.isEquality() && CI1->isZero()) {
+    ICmpInst::Predicate Pred = I.getPredicate() == ICmpInst::ICMP_EQ
+                                   ? ICmpInst::ICMP_UGT
+                                   : ICmpInst::ICMP_ULE;
+    return new ICmpInst(Pred, A,
+                        ConstantInt::get(A->getType(), CI2->getValue()));
+  }
+  // FIXME: Handle (icmp ugt (udiv i32 CI2, A), CI1) and
+  // (icmp ult (udiv i32 CI2, A), CI1).
+  return nullptr;
+}
+
 /// visitICmpInstWithInstAndIntCst - Handle "icmp (instr, intcst)".
 ///
 Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
@@ -3287,8 +3303,12 @@
         if (Instruction *Inst = FoldICmpCstShlCst(I, Op0, A, CI, CI2))
           return Inst;
       }
+      if (match(Op0, m_UDiv(m_ConstantInt(CI2), m_Value(A)))) {
+        // (icmp eq/ne (udiv const2, A), const1)
+        if (Instruction *Inst = FoldICmpCstUDivCst(I, Op0, CI, CI2, A))
+          return Inst;
+      }
     }
-
     // If this comparison is a normal comparison, it demands all
     // bits, if it is a sign bit comparison, it only demands the sign bit.
     bool UnusedBit;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D20036.56474.patch
Type: text/x-patch
Size: 3085 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160506/d1ea8185/attachment.bin>


More information about the llvm-commits mailing list