[llvm] ee9a0f3 - [InstCombine] canonicalize urem as cmp+select

via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 20 07:53:27 PST 2023


Author: zhongyunde
Date: 2023-02-20T23:52:10+08:00
New Revision: ee9a0f30ca8a3582d0738f7499ea902e1f713b39

URL: https://github.com/llvm/llvm-project/commit/ee9a0f30ca8a3582d0738f7499ea902e1f713b39
DIFF: https://github.com/llvm/llvm-project/commit/ee9a0f30ca8a3582d0738f7499ea902e1f713b39.diff

LOG: [InstCombine] canonicalize urem as cmp+select

Fix https://github.com/llvm/llvm-project/issues/60546

Reviewed By: nikic, efriedma, RKSimon, spatel

Differential Revision: https://reviews.llvm.org/D143883

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
    llvm/test/Transforms/InstCombine/urem-via-cmp-select.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index e0d7bd4d84c4..fbf229386701 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -1787,6 +1787,17 @@ Instruction *InstCombinerImpl::visitURem(BinaryOperator &I) {
     return SelectInst::Create(Cmp, ConstantInt::getNullValue(Ty), Op0);
   }
 
+  // For "(X + 1) % Op1" and if (X u< Op1) => (X + 1) == Op1 ? 0 : X + 1 .
+  if (match(Op0, m_Add(m_Value(X), m_One()))) {
+    Value *Val =
+        simplifyICmpInst(ICmpInst::ICMP_ULT, X, Op1, SQ.getWithInstruction(&I));
+    if (Val && match(Val, m_One())) {
+      Value *FrozenOp0 = Builder.CreateFreeze(Op0, Op0->getName() + ".frozen");
+      Value *Cmp = Builder.CreateICmpEQ(FrozenOp0, Op1);
+      return SelectInst::Create(Cmp, ConstantInt::getNullValue(Ty), FrozenOp0);
+    }
+  }
+
   return nullptr;
 }
 

diff  --git a/llvm/test/Transforms/InstCombine/urem-via-cmp-select.ll b/llvm/test/Transforms/InstCombine/urem-via-cmp-select.ll
index 3f509809ba50..b3304199d6c6 100644
--- a/llvm/test/Transforms/InstCombine/urem-via-cmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/urem-via-cmp-select.ll
@@ -1,13 +1,15 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
 
-; TODO: https://alive2.llvm.org/ce/z/5eCiWi
+; https://alive2.llvm.org/ce/z/5eCiWi
 define i8 @urem_assume(i8 %x, i8 %n) {
 ; CHECK-LABEL: @urem_assume(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[N:%.*]]
+; CHECK-NEXT:    [[X_FR:%.*]] = freeze i8 [[X:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X_FR]], [[N:%.*]]
 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
-; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X]], 1
-; CHECK-NEXT:    [[OUT:%.*]] = urem i8 [[ADD]], [[N]]
+; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X_FR]], 1
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[ADD]], [[N]]
+; CHECK-NEXT:    [[OUT:%.*]] = select i1 [[TMP1]], i8 0, i8 [[ADD]]
 ; CHECK-NEXT:    ret i8 [[OUT]]
 ;
   %cmp = icmp ult i8 %x, %n
@@ -17,13 +19,15 @@ define i8 @urem_assume(i8 %x, i8 %n) {
   ret i8 %out
 }
 
-; TODO: https://alive2.llvm.org/ce/z/MGgtYN
+; https://alive2.llvm.org/ce/z/MGgtYN
 define i8 @urem_assume_without_nuw(i8 %x, i8 %n) {
 ; CHECK-LABEL: @urem_assume_without_nuw(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[N:%.*]]
+; CHECK-NEXT:    [[X_FR:%.*]] = freeze i8 [[X:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X_FR]], [[N:%.*]]
 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
-; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X]], 1
-; CHECK-NEXT:    [[OUT:%.*]] = urem i8 [[ADD]], [[N]]
+; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X_FR]], 1
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[ADD]], [[N]]
+; CHECK-NEXT:    [[OUT:%.*]] = select i1 [[TMP1]], i8 0, i8 [[ADD]]
 ; CHECK-NEXT:    ret i8 [[OUT]]
 ;
   %cmp = icmp ult i8 %x, %n
@@ -83,12 +87,14 @@ define i8 @urem_assume_with_unexpected_const(i8 %x, i8 %n) {
   ret i8 %out
 }
 
-; TODO: https://alive2.llvm.org/ce/z/gNhZ2x
+; https://alive2.llvm.org/ce/z/gNhZ2x
 define i8 @urem_without_assume(i8 %arg, i8 %arg2) {
 ; CHECK-LABEL: @urem_without_assume(
 ; CHECK-NEXT:    [[X:%.*]] = urem i8 [[ARG:%.*]], [[ARG2:%.*]]
-; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X]], 1
-; CHECK-NEXT:    [[OUT:%.*]] = urem i8 [[ADD]], [[ARG2]]
+; CHECK-NEXT:    [[X_FR:%.*]] = freeze i8 [[X]]
+; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X_FR]], 1
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[ADD]], [[ARG2]]
+; CHECK-NEXT:    [[OUT:%.*]] = select i1 [[TMP1]], i8 0, i8 [[ADD]]
 ; CHECK-NEXT:    ret i8 [[OUT]]
 ;
   %x = urem i8 %arg, %arg2


        


More information about the llvm-commits mailing list