[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