Skip to content

Commit 5d13b45

Browse files
committed
[InstCombine] Recognize (icmp eq/ne (and X, ~Mask), 0) pattern in foldICmpWithLowBitMaskedVal
`(icmp eq/ne (and X, ~Mask), 0)` is equivilent to `(icmp eq/ne (and X, Mask), X` and we sometimes generate the former pattern intentionally to reduce number of uses of `X`. Proof: https://alive2.llvm.org/ce/z/3u-usC Differential Revision: https://reviews.llvm.org/D159329
1 parent d182569 commit 5d13b45

File tree

6 files changed

+29
-35
lines changed

6 files changed

+29
-35
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4162,6 +4162,7 @@ static bool isMaskOrZero(const Value *V, bool Not, const SimplifyQuery &Q,
41624162
/// a check for a lossy truncation.
41634163
/// Folds:
41644164
/// icmp SrcPred (x & Mask), x to icmp DstPred x, Mask
4165+
/// icmp eq/ne (x & ~Mask), 0 to icmp DstPred x, Mask
41654166
/// Where Mask is some pattern that produces all-ones in low bits:
41664167
/// (-1 >> y)
41674168
/// ((-1 << y) >> y) <- non-canonical, has extra uses
@@ -4194,6 +4195,16 @@ static Value *foldICmpWithLowBitMaskedVal(ICmpInst &I, const SimplifyQuery &Q,
41944195
SrcPred = ICmpInst::getSwappedPredicate(Pred);
41954196
return CheckMask(M, /*Not*/ false);
41964197
}
4198+
if (OpNo == 1 && match(I.getOperand(1), m_Zero()) &&
4199+
ICmpInst::isEquality(Pred) &&
4200+
match(I.getOperand(0), m_OneUse(m_And(m_Value(X), m_Value(M))))) {
4201+
NeedsNot = true;
4202+
if (IC.isFreeToInvert(X, X->hasOneUse()) && CheckMask(X, /*Not*/ true)) {
4203+
std::swap(X, M);
4204+
return true;
4205+
}
4206+
return IC.isFreeToInvert(M, M->hasOneUse()) && CheckMask(M, /*Not*/ true);
4207+
}
41974208
return false;
41984209
};
41994210

llvm/test/Transforms/InstCombine/icmp-and-lowbit-mask.ll

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,7 @@ define i1 @src_is_mask_sext(i16 %x_in, i8 %y) {
4343
; CHECK-NEXT: [[X:%.*]] = xor i16 [[X_IN:%.*]], 123
4444
; CHECK-NEXT: [[M_IN:%.*]] = lshr i8 31, [[Y:%.*]]
4545
; CHECK-NEXT: [[MASK:%.*]] = zext nneg i8 [[M_IN]] to i16
46-
; CHECK-NEXT: [[NOTMASK:%.*]] = xor i16 [[MASK]], -1
47-
; CHECK-NEXT: [[AND:%.*]] = and i16 [[X]], [[NOTMASK]]
48-
; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[AND]], 0
46+
; CHECK-NEXT: [[R:%.*]] = icmp ule i16 [[X]], [[MASK]]
4947
; CHECK-NEXT: ret i1 [[R]]
5048
;
5149
%x = xor i16 %x_in, 123
@@ -213,9 +211,7 @@ define i1 @src_is_mask_shl_lshr(i8 %x_in, i8 %y, i1 %cond) {
213211
; CHECK-LABEL: @src_is_mask_shl_lshr(
214212
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 122
215213
; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 -1, [[Y:%.*]]
216-
; CHECK-NEXT: [[NOTMASK:%.*]] = xor i8 [[TMP1]], -1
217-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[NOTMASK]]
218-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND]], 0
214+
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[TMP1]]
219215
; CHECK-NEXT: ret i1 [[R]]
220216
;
221217
%x = xor i8 %x_in, 123
@@ -560,11 +556,10 @@ define i1 @src_is_notmask_neg_p2(i8 %x_in, i8 %y) {
560556
define i1 @src_is_notmask_neg_p2_fail_not_invertable(i8 %x_in, i8 %y) {
561557
; CHECK-LABEL: @src_is_notmask_neg_p2_fail_not_invertable(
562558
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
563-
; CHECK-NEXT: [[NY:%.*]] = sub i8 0, [[Y:%.*]]
564-
; CHECK-NEXT: [[P2:%.*]] = and i8 [[NY]], [[Y]]
565-
; CHECK-NEXT: [[NOTMASK:%.*]] = sub i8 0, [[P2]]
566-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[NOTMASK]]
567-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], 0
559+
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], -1
560+
; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[Y]], -1
561+
; CHECK-NEXT: [[TMP3:%.*]] = and i8 [[TMP1]], [[TMP2]]
562+
; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X]], [[TMP3]]
568563
; CHECK-NEXT: ret i1 [[R]]
569564
;
570565
%x = xor i8 %x_in, 123

llvm/test/Transforms/InstCombine/lshr-and-negC-icmpeq-zero.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ define <4 x i1> @vec_4xi32_lshr_and_negC_eq(<4 x i32> %x, <4 x i32> %y) {
8484
define <4 x i1> @vec_lshr_and_negC_eq_undef1(<4 x i32> %x, <4 x i32> %y) {
8585
; CHECK-LABEL: @vec_lshr_and_negC_eq_undef1(
8686
; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> [[X:%.*]], [[Y:%.*]]
87-
; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[LSHR]], <i32 -8, i32 undef, i32 -8, i32 -8>
88-
; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], zeroinitializer
87+
; CHECK-NEXT: [[R:%.*]] = icmp ult <4 x i32> [[LSHR]], <i32 8, i32 8, i32 8, i32 8>
8988
; CHECK-NEXT: ret <4 x i1> [[R]]
9089
;
9190
%lshr = lshr <4 x i32> %x, %y
@@ -97,8 +96,7 @@ define <4 x i1> @vec_lshr_and_negC_eq_undef1(<4 x i32> %x, <4 x i32> %y) {
9796
define <4 x i1> @vec_lshr_and_negC_eq_undef2(<4 x i32> %x, <4 x i32> %y) {
9897
; CHECK-LABEL: @vec_lshr_and_negC_eq_undef2(
9998
; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> [[X:%.*]], [[Y:%.*]]
100-
; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[LSHR]], <i32 -8, i32 -8, i32 -8, i32 -8>
101-
; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], <i32 0, i32 0, i32 0, i32 undef>
99+
; CHECK-NEXT: [[R:%.*]] = icmp ult <4 x i32> [[LSHR]], <i32 8, i32 8, i32 8, i32 8>
102100
; CHECK-NEXT: ret <4 x i1> [[R]]
103101
;
104102
%lshr = lshr <4 x i32> %x, %y
@@ -110,8 +108,7 @@ define <4 x i1> @vec_lshr_and_negC_eq_undef2(<4 x i32> %x, <4 x i32> %y) {
110108
define <4 x i1> @vec_lshr_and_negC_eq_undef3(<4 x i32> %x, <4 x i32> %y) {
111109
; CHECK-LABEL: @vec_lshr_and_negC_eq_undef3(
112110
; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> [[X:%.*]], [[Y:%.*]]
113-
; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[LSHR]], <i32 -8, i32 -8, i32 undef, i32 -8>
114-
; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], <i32 0, i32 0, i32 0, i32 undef>
111+
; CHECK-NEXT: [[R:%.*]] = icmp ult <4 x i32> [[LSHR]], <i32 8, i32 8, i32 8, i32 8>
115112
; CHECK-NEXT: ret <4 x i1> [[R]]
116113
;
117114
%lshr = lshr <4 x i32> %x, %y

llvm/test/Transforms/InstCombine/lshr-and-signbit-icmpeq-zero.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ define <4 x i1> @vec_4xi32_lshr_and_signbit_eq(<4 x i32> %x, <4 x i32> %y) {
8484
define <4 x i1> @vec_4xi32_lshr_and_signbit_eq_undef1(<4 x i32> %x, <4 x i32> %y) {
8585
; CHECK-LABEL: @vec_4xi32_lshr_and_signbit_eq_undef1(
8686
; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> [[X:%.*]], [[Y:%.*]]
87-
; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[LSHR]], <i32 -2147483648, i32 undef, i32 -2147483648, i32 -2147483648>
88-
; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], zeroinitializer
87+
; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[LSHR]], <i32 -1, i32 -1, i32 -1, i32 -1>
8988
; CHECK-NEXT: ret <4 x i1> [[R]]
9089
;
9190
%lshr = lshr <4 x i32> %x, %y
@@ -97,8 +96,7 @@ define <4 x i1> @vec_4xi32_lshr_and_signbit_eq_undef1(<4 x i32> %x, <4 x i32> %y
9796
define <4 x i1> @vec_4xi32_lshr_and_signbit_eq_undef2(<4 x i32> %x, <4 x i32> %y) {
9897
; CHECK-LABEL: @vec_4xi32_lshr_and_signbit_eq_undef2(
9998
; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> [[X:%.*]], [[Y:%.*]]
100-
; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[LSHR]], <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>
101-
; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], <i32 undef, i32 0, i32 0, i32 0>
99+
; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[LSHR]], <i32 -1, i32 -1, i32 -1, i32 -1>
102100
; CHECK-NEXT: ret <4 x i1> [[R]]
103101
;
104102
%lshr = lshr <4 x i32> %x, %y
@@ -110,8 +108,7 @@ define <4 x i1> @vec_4xi32_lshr_and_signbit_eq_undef2(<4 x i32> %x, <4 x i32> %y
110108
define <4 x i1> @vec_4xi32_lshr_and_signbit_eq_undef3(<4 x i32> %x, <4 x i32> %y) {
111109
; CHECK-LABEL: @vec_4xi32_lshr_and_signbit_eq_undef3(
112110
; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> [[X:%.*]], [[Y:%.*]]
113-
; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[LSHR]], <i32 -2147483648, i32 undef, i32 -2147483648, i32 -2147483648>
114-
; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], <i32 0, i32 0, i32 0, i32 undef>
111+
; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[LSHR]], <i32 -1, i32 -1, i32 -1, i32 -1>
115112
; CHECK-NEXT: ret <4 x i1> [[R]]
116113
;
117114
%lshr = lshr <4 x i32> %x, %y

llvm/test/Transforms/InstCombine/shl-and-negC-icmpeq-zero.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ define <4 x i1> @vec_4xi32_shl_and_negC_eq(<4 x i32> %x, <4 x i32> %y) {
8484
define <4 x i1> @vec_shl_and_negC_eq_undef1(<4 x i32> %x, <4 x i32> %y) {
8585
; CHECK-LABEL: @vec_shl_and_negC_eq_undef1(
8686
; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], [[Y:%.*]]
87-
; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[SHL]], <i32 -8, i32 undef, i32 -8, i32 -8>
88-
; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], zeroinitializer
87+
; CHECK-NEXT: [[R:%.*]] = icmp ult <4 x i32> [[SHL]], <i32 8, i32 8, i32 8, i32 8>
8988
; CHECK-NEXT: ret <4 x i1> [[R]]
9089
;
9190
%shl = shl <4 x i32> %x, %y
@@ -97,8 +96,7 @@ define <4 x i1> @vec_shl_and_negC_eq_undef1(<4 x i32> %x, <4 x i32> %y) {
9796
define <4 x i1> @vec_shl_and_negC_eq_undef2(<4 x i32> %x, <4 x i32> %y) {
9897
; CHECK-LABEL: @vec_shl_and_negC_eq_undef2(
9998
; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], [[Y:%.*]]
100-
; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[SHL]], <i32 -8, i32 -8, i32 -8, i32 -8>
101-
; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], <i32 0, i32 0, i32 0, i32 undef>
99+
; CHECK-NEXT: [[R:%.*]] = icmp ult <4 x i32> [[SHL]], <i32 8, i32 8, i32 8, i32 8>
102100
; CHECK-NEXT: ret <4 x i1> [[R]]
103101
;
104102
%shl = shl <4 x i32> %x, %y
@@ -110,8 +108,7 @@ define <4 x i1> @vec_shl_and_negC_eq_undef2(<4 x i32> %x, <4 x i32> %y) {
110108
define <4 x i1> @vec_shl_and_negC_eq_undef3(<4 x i32> %x, <4 x i32> %y) {
111109
; CHECK-LABEL: @vec_shl_and_negC_eq_undef3(
112110
; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], [[Y:%.*]]
113-
; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[SHL]], <i32 -8, i32 -8, i32 undef, i32 -8>
114-
; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], <i32 0, i32 0, i32 0, i32 undef>
111+
; CHECK-NEXT: [[R:%.*]] = icmp ult <4 x i32> [[SHL]], <i32 8, i32 8, i32 8, i32 8>
115112
; CHECK-NEXT: ret <4 x i1> [[R]]
116113
;
117114
%shl = shl <4 x i32> %x, %y

llvm/test/Transforms/InstCombine/shl-and-signbit-icmpeq-zero.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ define <4 x i1> @vec_4xi32_shl_and_signbit_eq(<4 x i32> %x, <4 x i32> %y) {
8484
define <4 x i1> @vec_4xi32_shl_and_signbit_eq_undef1(<4 x i32> %x, <4 x i32> %y) {
8585
; CHECK-LABEL: @vec_4xi32_shl_and_signbit_eq_undef1(
8686
; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], [[Y:%.*]]
87-
; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[SHL]], <i32 -2147483648, i32 undef, i32 -2147483648, i32 -2147483648>
88-
; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], zeroinitializer
87+
; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[SHL]], <i32 -1, i32 -1, i32 -1, i32 -1>
8988
; CHECK-NEXT: ret <4 x i1> [[R]]
9089
;
9190
%shl = shl <4 x i32> %x, %y
@@ -97,8 +96,7 @@ define <4 x i1> @vec_4xi32_shl_and_signbit_eq_undef1(<4 x i32> %x, <4 x i32> %y)
9796
define <4 x i1> @vec_4xi32_shl_and_signbit_eq_undef2(<4 x i32> %x, <4 x i32> %y) {
9897
; CHECK-LABEL: @vec_4xi32_shl_and_signbit_eq_undef2(
9998
; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], [[Y:%.*]]
100-
; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[SHL]], <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>
101-
; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], <i32 undef, i32 0, i32 0, i32 0>
99+
; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[SHL]], <i32 -1, i32 -1, i32 -1, i32 -1>
102100
; CHECK-NEXT: ret <4 x i1> [[R]]
103101
;
104102
%shl = shl <4 x i32> %x, %y
@@ -110,8 +108,7 @@ define <4 x i1> @vec_4xi32_shl_and_signbit_eq_undef2(<4 x i32> %x, <4 x i32> %y)
110108
define <4 x i1> @vec_4xi32_shl_and_signbit_eq_undef3(<4 x i32> %x, <4 x i32> %y) {
111109
; CHECK-LABEL: @vec_4xi32_shl_and_signbit_eq_undef3(
112110
; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], [[Y:%.*]]
113-
; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[SHL]], <i32 -2147483648, i32 undef, i32 -2147483648, i32 -2147483648>
114-
; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], <i32 0, i32 0, i32 0, i32 undef>
111+
; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[SHL]], <i32 -1, i32 -1, i32 -1, i32 -1>
115112
; CHECK-NEXT: ret <4 x i1> [[R]]
116113
;
117114
%shl = shl <4 x i32> %x, %y

0 commit comments

Comments
 (0)