Skip to content

Commit b212eb7

Browse files
committed
Revert "[InstCombine] fold zext of masked bit set/clear"
This reverts commit a041c4e. This looks like a non-trivial change and there has been no code reviews (at least there were no phabricator revisions attached to the commit description). It is also causing a regression in one of our downstream integration tests, we haven't been able to come up with a minimal reproducer yet.
1 parent 903e5c3 commit b212eb7

File tree

2 files changed

+31
-54
lines changed

2 files changed

+31
-54
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

+3-17
Original file line numberDiff line numberDiff line change
@@ -922,24 +922,10 @@ Instruction *InstCombiner::transformZExtICmp(ICmpInst *Cmp, ZExtInst &Zext,
922922
}
923923
}
924924

925+
// icmp ne A, B is equal to xor A, B when A and B only really have one bit.
926+
// It is also profitable to transform icmp eq into not(xor(A, B)) because that
927+
// may lead to additional simplifications.
925928
if (Cmp->isEquality() && Zext.getType() == Cmp->getOperand(0)->getType()) {
926-
// Test if a bit is clear/set using a shifted-one mask:
927-
// zext (icmp eq (and X, (1 << ShAmt)), 0) --> and (lshr (not X), ShAmt), 1
928-
// zext (icmp ne (and X, (1 << ShAmt)), 0) --> and (lshr X, ShAmt), 1
929-
Value *X, *ShAmt;
930-
if (Cmp->hasOneUse() && match(Cmp->getOperand(1), m_ZeroInt()) &&
931-
match(Cmp->getOperand(0),
932-
m_OneUse(m_c_And(m_Shl(m_One(), m_Value(ShAmt)), m_Value(X))))) {
933-
if (Cmp->getPredicate() == ICmpInst::ICMP_EQ)
934-
X = Builder.CreateNot(X);
935-
Value *Lshr = Builder.CreateLShr(X, ShAmt);
936-
Value *And1 = Builder.CreateAnd(Lshr, ConstantInt::get(X->getType(), 1));
937-
return replaceInstUsesWith(Zext, And1);
938-
}
939-
940-
// icmp ne A, B is equal to xor A, B when A and B only really have one bit.
941-
// It is also profitable to transform icmp eq into not(xor(A, B)) because
942-
// that may lead to additional simplifications.
943929
if (IntegerType *ITy = dyn_cast<IntegerType>(Zext.getType())) {
944930
Value *LHS = Cmp->getOperand(0);
945931
Value *RHS = Cmp->getOperand(1);

llvm/test/Transforms/InstCombine/zext.ll

+28-37
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,11 @@ declare void @use32(i32)
177177

178178
define i32 @masked_bit_set(i32 %x, i32 %y) {
179179
; CHECK-LABEL: @masked_bit_set(
180-
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]
181-
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 1
182-
; CHECK-NEXT: ret i32 [[TMP2]]
180+
; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
181+
; CHECK-NEXT: [[AND:%.*]] = and i32 [[SH1]], [[X:%.*]]
182+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
183+
; CHECK-NEXT: [[R:%.*]] = zext i1 [[CMP]] to i32
184+
; CHECK-NEXT: ret i32 [[R]]
183185
;
184186
%sh1 = shl i32 1, %y
185187
%and = and i32 %sh1, %x
@@ -190,10 +192,11 @@ define i32 @masked_bit_set(i32 %x, i32 %y) {
190192

191193
define <2 x i32> @masked_bit_clear(<2 x i32> %x, <2 x i32> %y) {
192194
; CHECK-LABEL: @masked_bit_clear(
193-
; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], <i32 -1, i32 -1>
194-
; CHECK-NEXT: [[TMP2:%.*]] = lshr <2 x i32> [[TMP1]], [[Y:%.*]]
195-
; CHECK-NEXT: [[TMP3:%.*]] = and <2 x i32> [[TMP2]], <i32 1, i32 1>
196-
; CHECK-NEXT: ret <2 x i32> [[TMP3]]
195+
; CHECK-NEXT: [[SH1:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[Y:%.*]]
196+
; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[SH1]], [[X:%.*]]
197+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], zeroinitializer
198+
; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[CMP]] to <2 x i32>
199+
; CHECK-NEXT: ret <2 x i32> [[R]]
197200
;
198201
%sh1 = shl <2 x i32> <i32 1, i32 1>, %y
199202
%and = and <2 x i32> %sh1, %x
@@ -205,9 +208,11 @@ define <2 x i32> @masked_bit_clear(<2 x i32> %x, <2 x i32> %y) {
205208
define <2 x i32> @masked_bit_set_commute(<2 x i32> %px, <2 x i32> %y) {
206209
; CHECK-LABEL: @masked_bit_set_commute(
207210
; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> <i32 42, i32 3>, [[PX:%.*]]
208-
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]]
209-
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 1, i32 1>
210-
; CHECK-NEXT: ret <2 x i32> [[TMP2]]
211+
; CHECK-NEXT: [[SH1:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[Y:%.*]]
212+
; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X]], [[SH1]]
213+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
214+
; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[CMP]] to <2 x i32>
215+
; CHECK-NEXT: ret <2 x i32> [[R]]
211216
;
212217
%x = srem <2 x i32> <i32 42, i32 3>, %px ; thwart complexity-based canonicalization
213218
%sh1 = shl <2 x i32> <i32 1, i32 1>, %y
@@ -220,10 +225,11 @@ define <2 x i32> @masked_bit_set_commute(<2 x i32> %px, <2 x i32> %y) {
220225
define i32 @masked_bit_clear_commute(i32 %px, i32 %y) {
221226
; CHECK-LABEL: @masked_bit_clear_commute(
222227
; CHECK-NEXT: [[X:%.*]] = srem i32 42, [[PX:%.*]]
223-
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X]], -1
224-
; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP1]], [[Y:%.*]]
225-
; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 1
226-
; CHECK-NEXT: ret i32 [[TMP3]]
228+
; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
229+
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[SH1]]
230+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
231+
; CHECK-NEXT: [[R:%.*]] = zext i1 [[CMP]] to i32
232+
; CHECK-NEXT: ret i32 [[R]]
227233
;
228234
%x = srem i32 42, %px ; thwart complexity-based canonicalization
229235
%sh1 = shl i32 1, %y
@@ -237,9 +243,10 @@ define i32 @masked_bit_set_use1(i32 %x, i32 %y) {
237243
; CHECK-LABEL: @masked_bit_set_use1(
238244
; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
239245
; CHECK-NEXT: call void @use32(i32 [[SH1]])
240-
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], [[Y]]
241-
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 1
242-
; CHECK-NEXT: ret i32 [[TMP2]]
246+
; CHECK-NEXT: [[AND:%.*]] = and i32 [[SH1]], [[X:%.*]]
247+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
248+
; CHECK-NEXT: [[R:%.*]] = zext i1 [[CMP]] to i32
249+
; CHECK-NEXT: ret i32 [[R]]
243250
;
244251
%sh1 = shl i32 1, %y
245252
call void @use32(i32 %sh1)
@@ -249,8 +256,6 @@ define i32 @masked_bit_set_use1(i32 %x, i32 %y) {
249256
ret i32 %r
250257
}
251258

252-
; Negative test
253-
254259
define i32 @masked_bit_set_use2(i32 %x, i32 %y) {
255260
; CHECK-LABEL: @masked_bit_set_use2(
256261
; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
@@ -268,8 +273,6 @@ define i32 @masked_bit_set_use2(i32 %x, i32 %y) {
268273
ret i32 %r
269274
}
270275

271-
; Negative test
272-
273276
define i32 @masked_bit_set_use3(i32 %x, i32 %y) {
274277
; CHECK-LABEL: @masked_bit_set_use3(
275278
; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
@@ -291,10 +294,10 @@ define i32 @masked_bit_clear_use1(i32 %x, i32 %y) {
291294
; CHECK-LABEL: @masked_bit_clear_use1(
292295
; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
293296
; CHECK-NEXT: call void @use32(i32 [[SH1]])
294-
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], -1
295-
; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP1]], [[Y]]
296-
; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 1
297-
; CHECK-NEXT: ret i32 [[TMP3]]
297+
; CHECK-NEXT: [[AND:%.*]] = and i32 [[SH1]], [[X:%.*]]
298+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
299+
; CHECK-NEXT: [[R:%.*]] = zext i1 [[CMP]] to i32
300+
; CHECK-NEXT: ret i32 [[R]]
298301
;
299302
%sh1 = shl i32 1, %y
300303
call void @use32(i32 %sh1)
@@ -304,8 +307,6 @@ define i32 @masked_bit_clear_use1(i32 %x, i32 %y) {
304307
ret i32 %r
305308
}
306309

307-
; Negative test
308-
309310
define i32 @masked_bit_clear_use2(i32 %x, i32 %y) {
310311
; CHECK-LABEL: @masked_bit_clear_use2(
311312
; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
@@ -323,8 +324,6 @@ define i32 @masked_bit_clear_use2(i32 %x, i32 %y) {
323324
ret i32 %r
324325
}
325326

326-
; Negative test
327-
328327
define i32 @masked_bit_clear_use3(i32 %x, i32 %y) {
329328
; CHECK-LABEL: @masked_bit_clear_use3(
330329
; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
@@ -342,8 +341,6 @@ define i32 @masked_bit_clear_use3(i32 %x, i32 %y) {
342341
ret i32 %r
343342
}
344343

345-
; Negative test
346-
347344
define i32 @masked_bits_set(i32 %x, i32 %y) {
348345
; CHECK-LABEL: @masked_bits_set(
349346
; CHECK-NEXT: [[SH1:%.*]] = shl i32 3, [[Y:%.*]]
@@ -359,8 +356,6 @@ define i32 @masked_bits_set(i32 %x, i32 %y) {
359356
ret i32 %r
360357
}
361358

362-
; Negative test
363-
364359
define i32 @div_bit_set(i32 %x, i32 %y) {
365360
; CHECK-LABEL: @div_bit_set(
366361
; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
@@ -376,8 +371,6 @@ define i32 @div_bit_set(i32 %x, i32 %y) {
376371
ret i32 %r
377372
}
378373

379-
; Negative test
380-
381374
define i32 @masked_bit_set_nonzero_cmp(i32 %x, i32 %y) {
382375
; CHECK-LABEL: @masked_bit_set_nonzero_cmp(
383376
; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
@@ -393,8 +386,6 @@ define i32 @masked_bit_set_nonzero_cmp(i32 %x, i32 %y) {
393386
ret i32 %r
394387
}
395388

396-
; Negative test
397-
398389
define i32 @masked_bit_wrong_pred(i32 %x, i32 %y) {
399390
; CHECK-LABEL: @masked_bit_wrong_pred(
400391
; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]

0 commit comments

Comments
 (0)