[PATCH] D150091: [InstCombine] Transform `icmp eq/ne ({su}div exact X,Y),C` -> `icmp eq/ne X, Y*C`

Noah Goldstein via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 12 17:48:08 PDT 2023


goldstein.w.n updated this revision to Diff 539807.
goldstein.w.n added a comment.

Fixup some nits


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150091/new/

https://reviews.llvm.org/D150091

Files:
  llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
  llvm/test/Transforms/InstCombine/sdiv-icmp.ll


Index: llvm/test/Transforms/InstCombine/sdiv-icmp.ll
===================================================================
--- llvm/test/Transforms/InstCombine/sdiv-icmp.ll
+++ llvm/test/Transforms/InstCombine/sdiv-icmp.ll
@@ -4,8 +4,7 @@
 declare void @use.i8(i8)
 define i1 @sdiv_exact_eq_0(i8 %x, i8 %y) {
 ; CHECK-LABEL: @sdiv_exact_eq_0(
-; CHECK-NEXT:    [[D:%.*]] = sdiv exact i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[D]], 0
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X:%.*]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %d = sdiv exact i8 %x, %y
@@ -15,7 +14,7 @@
 
 define i1 @udiv_exact_ne_0(i8 %x, i8 %y) {
 ; CHECK-LABEL: @udiv_exact_ne_0(
-; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[X:%.*]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %d = udiv exact i8 %x, %y
@@ -25,8 +24,7 @@
 
 define i1 @sdiv_exact_ne_1(i8 %x, i8 %y) {
 ; CHECK-LABEL: @sdiv_exact_ne_1(
-; CHECK-NEXT:    [[D:%.*]] = sdiv exact i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[D]], 0
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X:%.*]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %d = sdiv exact i8 %x, %y
@@ -36,8 +34,7 @@
 
 define i1 @udiv_exact_eq_1(i8 %x, i8 %y) {
 ; CHECK-LABEL: @udiv_exact_eq_1(
-; CHECK-NEXT:    [[D:%.*]] = udiv exact i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[D]], 1
+; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %d = udiv exact i8 %x, %y
@@ -48,8 +45,8 @@
 define i1 @sdiv_exact_eq_9_no_of(i8 %x, i8 %y) {
 ; CHECK-LABEL: @sdiv_exact_eq_9_no_of(
 ; CHECK-NEXT:    [[YY:%.*]] = and i8 [[Y:%.*]], 7
-; CHECK-NEXT:    [[D:%.*]] = sdiv exact i8 [[X:%.*]], [[YY]]
-; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[D]], 9
+; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw nsw i8 [[YY]], 9
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %yy = and i8 %y, 7
@@ -100,8 +97,8 @@
 define i1 @udiv_exact_ne_30_no_of(i8 %x, i8 %y) {
 ; CHECK-LABEL: @udiv_exact_ne_30_no_of(
 ; CHECK-NEXT:    [[YY:%.*]] = and i8 [[Y:%.*]], 7
-; CHECK-NEXT:    [[D:%.*]] = udiv exact i8 [[X:%.*]], [[YY]]
-; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[D]], 30
+; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw i8 [[YY]], 30
+; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %yy = and i8 %y, 7
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3323,7 +3323,29 @@
     break;
   }
   case Instruction::UDiv:
-    if (C.isZero()) {
+  case Instruction::SDiv:
+    if (BO->isExact()) {
+      // div exact X, Y eq/ne 0 -> X eq/ne 0
+      // div exact X, Y eq/ne 1 -> X eq/ne Y
+      // div exact X, Y eq/ne C ->
+      //    if Y * C never-overflow && OneUse:
+      //      -> Y * C eq/ne X
+      if (C.isZero())
+        return new ICmpInst(Pred, BOp0, Constant::getNullValue(BO->getType()));
+      else if (C.isOne())
+        return new ICmpInst(Pred, BOp0, BOp1);
+      else if (BO->hasOneUse()) {
+        OverflowResult OR = computeOverflow(
+            Instruction::Mul, BO->getOpcode() == Instruction::SDiv, BOp1,
+            Cmp.getOperand(1), BO);
+        if (OR == OverflowResult::NeverOverflows) {
+          Value *YC =
+              Builder.CreateMul(BOp1, ConstantInt::get(BO->getType(), C));
+          return new ICmpInst(Pred, YC, BOp0);
+        }
+      }
+    }
+    if (BO->getOpcode() == Instruction::UDiv && C.isZero()) {
       // (icmp eq/ne (udiv A, B), 0) -> (icmp ugt/ule i32 B, A)
       auto NewPred = isICMP_NE ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_UGT;
       return new ICmpInst(NewPred, BOp1, BOp0);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D150091.539807.patch
Type: text/x-patch
Size: 3865 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230713/e6c4f250/attachment.bin>


More information about the llvm-commits mailing list