Skip to content

Commit ee9a0f3

Browse files
committed
[InstCombine] canonicalize urem as cmp+select
Fix #60546 Reviewed By: nikic, efriedma, RKSimon, spatel Differential Revision: https://reviews.llvm.org/D143883
1 parent 45a0b81 commit ee9a0f3

File tree

2 files changed

+28
-11
lines changed

2 files changed

+28
-11
lines changed

llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1787,6 +1787,17 @@ Instruction *InstCombinerImpl::visitURem(BinaryOperator &I) {
17871787
return SelectInst::Create(Cmp, ConstantInt::getNullValue(Ty), Op0);
17881788
}
17891789

1790+
// For "(X + 1) % Op1" and if (X u< Op1) => (X + 1) == Op1 ? 0 : X + 1 .
1791+
if (match(Op0, m_Add(m_Value(X), m_One()))) {
1792+
Value *Val =
1793+
simplifyICmpInst(ICmpInst::ICMP_ULT, X, Op1, SQ.getWithInstruction(&I));
1794+
if (Val && match(Val, m_One())) {
1795+
Value *FrozenOp0 = Builder.CreateFreeze(Op0, Op0->getName() + ".frozen");
1796+
Value *Cmp = Builder.CreateICmpEQ(FrozenOp0, Op1);
1797+
return SelectInst::Create(Cmp, ConstantInt::getNullValue(Ty), FrozenOp0);
1798+
}
1799+
}
1800+
17901801
return nullptr;
17911802
}
17921803

llvm/test/Transforms/InstCombine/urem-via-cmp-select.ll

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
22
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
33

4-
; TODO: https://alive2.llvm.org/ce/z/5eCiWi
4+
; https://alive2.llvm.org/ce/z/5eCiWi
55
define i8 @urem_assume(i8 %x, i8 %n) {
66
; CHECK-LABEL: @urem_assume(
7-
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[N:%.*]]
7+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X:%.*]]
8+
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X_FR]], [[N:%.*]]
89
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]])
9-
; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X]], 1
10-
; CHECK-NEXT: [[OUT:%.*]] = urem i8 [[ADD]], [[N]]
10+
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X_FR]], 1
11+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[ADD]], [[N]]
12+
; CHECK-NEXT: [[OUT:%.*]] = select i1 [[TMP1]], i8 0, i8 [[ADD]]
1113
; CHECK-NEXT: ret i8 [[OUT]]
1214
;
1315
%cmp = icmp ult i8 %x, %n
@@ -17,13 +19,15 @@ define i8 @urem_assume(i8 %x, i8 %n) {
1719
ret i8 %out
1820
}
1921

20-
; TODO: https://alive2.llvm.org/ce/z/MGgtYN
22+
; https://alive2.llvm.org/ce/z/MGgtYN
2123
define i8 @urem_assume_without_nuw(i8 %x, i8 %n) {
2224
; CHECK-LABEL: @urem_assume_without_nuw(
23-
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[N:%.*]]
25+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X:%.*]]
26+
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X_FR]], [[N:%.*]]
2427
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]])
25-
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1
26-
; CHECK-NEXT: [[OUT:%.*]] = urem i8 [[ADD]], [[N]]
28+
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X_FR]], 1
29+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[ADD]], [[N]]
30+
; CHECK-NEXT: [[OUT:%.*]] = select i1 [[TMP1]], i8 0, i8 [[ADD]]
2731
; CHECK-NEXT: ret i8 [[OUT]]
2832
;
2933
%cmp = icmp ult i8 %x, %n
@@ -83,12 +87,14 @@ define i8 @urem_assume_with_unexpected_const(i8 %x, i8 %n) {
8387
ret i8 %out
8488
}
8589

86-
; TODO: https://alive2.llvm.org/ce/z/gNhZ2x
90+
; https://alive2.llvm.org/ce/z/gNhZ2x
8791
define i8 @urem_without_assume(i8 %arg, i8 %arg2) {
8892
; CHECK-LABEL: @urem_without_assume(
8993
; CHECK-NEXT: [[X:%.*]] = urem i8 [[ARG:%.*]], [[ARG2:%.*]]
90-
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1
91-
; CHECK-NEXT: [[OUT:%.*]] = urem i8 [[ADD]], [[ARG2]]
94+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X]]
95+
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X_FR]], 1
96+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[ADD]], [[ARG2]]
97+
; CHECK-NEXT: [[OUT:%.*]] = select i1 [[TMP1]], i8 0, i8 [[ADD]]
9298
; CHECK-NEXT: ret i8 [[OUT]]
9399
;
94100
%x = urem i8 %arg, %arg2

0 commit comments

Comments
 (0)