Skip to content

Commit 0c68968

Browse files
committed
match both or and add
1 parent f5842f6 commit 0c68968

File tree

2 files changed

+22
-69
lines changed

2 files changed

+22
-69
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,16 +1299,19 @@ Instruction *InstCombinerImpl::foldICmpWithZero(ICmpInst &Cmp) {
12991299
// will fold to a constant elsewhere.
13001300
}
13011301

1302-
// icmp eq/ne ((X >> C) | (X & mask(C) != 0)), 0 -> icmp eq/ne X, 0
1302+
// icmp eq/ne ((X >> C) or/add (X & mask(C) != 0)), 0 -> icmp eq/ne X, 0
13031303
if (ICmpInst::isEquality(Pred)) {
1304+
auto *BO = dyn_cast<BinaryOperator>(Cmp.getOperand(0));
13041305
Value *X;
13051306
const APInt *C1, *C2;
1306-
if (match(Cmp.getOperand(0),
1307-
m_OneUse(m_c_Or(
1308-
m_LShr(m_Value(X), m_APInt(C1)),
1309-
m_ZExt(m_SpecificICmp(ICmpInst::ICMP_NE,
1310-
m_And(m_Deferred(X), m_LowBitMask(C2)),
1311-
m_Zero()))))) &&
1307+
if (BO &&
1308+
(BO->getOpcode() == Instruction::Add ||
1309+
BO->getOpcode() == Instruction::Or) &&
1310+
match(BO, m_c_BinOp(m_LShr(m_Value(X), m_APInt(C1)),
1311+
m_ZExt(m_SpecificICmp(
1312+
ICmpInst::ICMP_NE,
1313+
m_And(m_Deferred(X), m_LowBitMask(C2)),
1314+
m_Zero())))) &&
13121315
C2->popcount() == C1->getZExtValue())
13131316
return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType()));
13141317
}

llvm/test/Transforms/InstCombine/ceil-shift.ll

Lines changed: 12 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,7 @@
44
define i1 @ceil_shift4(i32 %arg0) {
55
; CHECK-LABEL: define i1 @ceil_shift4(
66
; CHECK-SAME: i32 [[ARG0:%.*]]) {
7-
; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 4
8-
; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 15
9-
; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
10-
; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
11-
; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or i32 [[QUOT]], [[ZEXT_HAS_REM]]
12-
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[QUOT_OR_REM]], 0
7+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[ARG0]], 0
138
; CHECK-NEXT: ret i1 [[TMP1]]
149
;
1510
%quot = lshr i32 %arg0, 4
@@ -24,12 +19,7 @@ define i1 @ceil_shift4(i32 %arg0) {
2419
define i1 @ceil_shift4_add(i32 %arg0) {
2520
; CHECK-LABEL: define i1 @ceil_shift4_add(
2621
; CHECK-SAME: i32 [[ARG0:%.*]]) {
27-
; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 4
28-
; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 15
29-
; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
30-
; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
31-
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[QUOT]], [[ZEXT_HAS_REM]]
32-
; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP1]], 0
22+
; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[ARG0]], 0
3323
; CHECK-NEXT: ret i1 [[TMP6]]
3424
;
3525
%quot = lshr i32 %arg0, 4
@@ -44,12 +34,7 @@ define i1 @ceil_shift4_add(i32 %arg0) {
4434
define i1 @ceil_shift6(i32 %arg0) {
4535
; CHECK-LABEL: define i1 @ceil_shift6(
4636
; CHECK-SAME: i32 [[ARG0:%.*]]) {
47-
; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 6
48-
; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 63
49-
; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
50-
; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
51-
; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or i32 [[QUOT]], [[ZEXT_HAS_REM]]
52-
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[QUOT_OR_REM]], 0
37+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[ARG0]], 0
5338
; CHECK-NEXT: ret i1 [[TMP1]]
5439
;
5540
%quot = lshr i32 %arg0, 6
@@ -64,12 +49,7 @@ define i1 @ceil_shift6(i32 %arg0) {
6449
define i1 @ceil_shift6_ne(i32 %arg0) {
6550
; CHECK-LABEL: define i1 @ceil_shift6_ne(
6651
; CHECK-SAME: i32 [[ARG0:%.*]]) {
67-
; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 6
68-
; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 63
69-
; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
70-
; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
71-
; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or i32 [[QUOT]], [[ZEXT_HAS_REM]]
72-
; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[QUOT_OR_REM]], 0
52+
; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[ARG0]], 0
7353
; CHECK-NEXT: ret i1 [[RES]]
7454
;
7555
%quot = lshr i32 %arg0, 6
@@ -84,12 +64,7 @@ define i1 @ceil_shift6_ne(i32 %arg0) {
8464
define i1 @ceil_shift11(i32 %arg0) {
8565
; CHECK-LABEL: define i1 @ceil_shift11(
8666
; CHECK-SAME: i32 [[ARG0:%.*]]) {
87-
; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 11
88-
; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 2047
89-
; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
90-
; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
91-
; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or i32 [[QUOT]], [[ZEXT_HAS_REM]]
92-
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[QUOT_OR_REM]], 0
67+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[ARG0]], 0
9368
; CHECK-NEXT: ret i1 [[TMP1]]
9469
;
9570
%quot = lshr i32 %arg0, 11
@@ -104,12 +79,7 @@ define i1 @ceil_shift11(i32 %arg0) {
10479
define i1 @ceil_shift11_ne(i32 %arg0) {
10580
; CHECK-LABEL: define i1 @ceil_shift11_ne(
10681
; CHECK-SAME: i32 [[ARG0:%.*]]) {
107-
; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 6
108-
; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 63
109-
; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
110-
; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
111-
; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or i32 [[QUOT]], [[ZEXT_HAS_REM]]
112-
; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[QUOT_OR_REM]], 0
82+
; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[ARG0]], 0
11383
; CHECK-NEXT: ret i1 [[RES]]
11484
;
11585
%quot = lshr i32 %arg0, 6
@@ -139,12 +109,7 @@ define i1 @ceil_shift0(i32 %arg0) {
139109
define i1 @ceil_shift4_comm(i32 %arg0) {
140110
; CHECK-LABEL: define i1 @ceil_shift4_comm(
141111
; CHECK-SAME: i32 [[ARG0:%.*]]) {
142-
; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 4
143-
; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 15
144-
; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
145-
; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
146-
; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or i32 [[QUOT]], [[ZEXT_HAS_REM]]
147-
; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[QUOT_OR_REM]], 0
112+
; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[ARG0]], 0
148113
; CHECK-NEXT: ret i1 [[TMP6]]
149114
;
150115
%quot = lshr i32 %arg0, 4
@@ -163,11 +128,7 @@ define i1 @ceil_shift4_used_1(i32 %arg0) {
163128
; CHECK-SAME: i32 [[ARG0:%.*]]) {
164129
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[ARG0]], 4
165130
; CHECK-NEXT: call void @use(i32 [[TMP1]])
166-
; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 15
167-
; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
168-
; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
169-
; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or i32 [[TMP1]], [[ZEXT_HAS_REM]]
170-
; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[QUOT_OR_REM]], 0
131+
; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[ARG0]], 0
171132
; CHECK-NEXT: ret i1 [[TMP6]]
172133
;
173134
%quot = lshr i32 %arg0, 4
@@ -189,7 +150,7 @@ define i1 @ceil_shift4_used_5(i32 %arg0) {
189150
; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
190151
; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP1]], [[TMP4]]
191152
; CHECK-NEXT: call void @use(i32 [[TMP5]])
192-
; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0
153+
; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[ARG0]], 0
193154
; CHECK-NEXT: ret i1 [[TMP6]]
194155
;
195156
%quot = lshr i32 %arg0, 4
@@ -211,7 +172,7 @@ define i1 @ceil_shift4_used_add_nuw_nsw(i32 %arg0) {
211172
; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
212173
; CHECK-NEXT: [[CEIL:%.*]] = add nuw nsw i32 [[QUOT]], [[ZEXT_HAS_REM]]
213174
; CHECK-NEXT: call void @use(i32 [[CEIL]])
214-
; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[CEIL]], 0
175+
; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[ARG0]], 0
215176
; CHECK-NEXT: ret i1 [[RES]]
216177
;
217178
%quot = lshr i32 %arg0, 4
@@ -227,12 +188,7 @@ define i1 @ceil_shift4_used_add_nuw_nsw(i32 %arg0) {
227188
define <4 x i1> @ceil_shift4_v4i32(<4 x i32> %arg0) {
228189
; CHECK-LABEL: define <4 x i1> @ceil_shift4_v4i32(
229190
; CHECK-SAME: <4 x i32> [[ARG0:%.*]]) {
230-
; CHECK-NEXT: [[QUOT:%.*]] = lshr <4 x i32> [[ARG0]], splat (i32 16)
231-
; CHECK-NEXT: [[REM:%.*]] = and <4 x i32> [[ARG0]], splat (i32 65535)
232-
; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne <4 x i32> [[REM]], zeroinitializer
233-
; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext <4 x i1> [[HAS_REM]] to <4 x i32>
234-
; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or <4 x i32> [[QUOT]], [[ZEXT_HAS_REM]]
235-
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[QUOT_OR_REM]], zeroinitializer
191+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[ARG0]], zeroinitializer
236192
; CHECK-NEXT: ret <4 x i1> [[TMP1]]
237193
;
238194
%quot = lshr <4 x i32> %arg0, splat (i32 16)
@@ -247,12 +203,7 @@ define <4 x i1> @ceil_shift4_v4i32(<4 x i32> %arg0) {
247203
define <8 x i1> @ceil_shift4_v8i16(<8 x i16> %arg0) {
248204
; CHECK-LABEL: define <8 x i1> @ceil_shift4_v8i16(
249205
; CHECK-SAME: <8 x i16> [[ARG0:%.*]]) {
250-
; CHECK-NEXT: [[QUOT:%.*]] = lshr <8 x i16> [[ARG0]], splat (i16 4)
251-
; CHECK-NEXT: [[REM:%.*]] = and <8 x i16> [[ARG0]], splat (i16 15)
252-
; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne <8 x i16> [[REM]], zeroinitializer
253-
; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext <8 x i1> [[HAS_REM]] to <8 x i16>
254-
; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or <8 x i16> [[QUOT]], [[ZEXT_HAS_REM]]
255-
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <8 x i16> [[QUOT_OR_REM]], zeroinitializer
206+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <8 x i16> [[ARG0]], zeroinitializer
256207
; CHECK-NEXT: ret <8 x i1> [[TMP1]]
257208
;
258209
%quot = lshr <8 x i16> %arg0, splat (i16 4)
@@ -324,4 +275,3 @@ define i1 @ceil_shift_not_add_or(i32 %arg0) {
324275
%res = icmp eq i32 %quot_and_rem, 0
325276
ret i1 %res
326277
}
327-

0 commit comments

Comments
 (0)