Skip to content

Commit ab68929

Browse files
committed
[InstCombine] allow sext in fold of mask using signbit, part 2
https://alive2.llvm.org/ce/z/rcbZmx Sibling tranform to 275aa24 This pattern is seen in the examples in issue #57381.
1 parent 0636aec commit ab68929

File tree

3 files changed

+27
-20
lines changed

3 files changed

+27
-20
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2244,12 +2244,11 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
22442244
A->getType()->isIntOrIntVectorTy(1))
22452245
return SelectInst::Create(A, Op0, Constant::getNullValue(Ty));
22462246

2247-
// (iN X s>> (N-1)) & Y --> (X s< 0) ? Y : 0
2248-
// TODO: Peek through optional sext.
2249-
unsigned FullShift = Ty->getScalarSizeInBits() - 1;
2250-
if (match(&I, m_c_And(m_OneUse(m_AShr(m_Value(X),
2251-
m_SpecificIntAllowUndef(FullShift))),
2252-
m_Value(Y)))) {
2247+
// (iN X s>> (N-1)) & Y --> (X s< 0) ? Y : 0 -- with optional sext
2248+
if (match(&I, m_c_And(m_OneUse(m_SExtOrSelf(
2249+
m_AShr(m_Value(X), m_APIntAllowUndef(C)))),
2250+
m_Value(Y))) &&
2251+
*C == X->getType()->getScalarSizeInBits() - 1) {
22532252
Value *IsNeg = Builder.CreateIsNeg(X, "isneg");
22542253
return SelectInst::Create(IsNeg, Y, ConstantInt::getNullValue(Ty));
22552254
}

llvm/test/Transforms/InstCombine/and.ll

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,9 +1682,8 @@ define i8 @lshr_bitwidth_mask(i8 %x, i8 %y) {
16821682

16831683
define i16 @signbit_splat_mask(i8 %x, i16 %y) {
16841684
; CHECK-LABEL: @signbit_splat_mask(
1685-
; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 7
1686-
; CHECK-NEXT: [[S:%.*]] = sext i8 [[A]] to i16
1687-
; CHECK-NEXT: [[R:%.*]] = and i16 [[S]], [[Y:%.*]]
1685+
; CHECK-NEXT: [[ISNEG:%.*]] = icmp slt i8 [[X:%.*]], 0
1686+
; CHECK-NEXT: [[R:%.*]] = select i1 [[ISNEG]], i16 [[Y:%.*]], i16 0
16881687
; CHECK-NEXT: ret i16 [[R]]
16891688
;
16901689
%a = ashr i8 %x, 7
@@ -1696,9 +1695,8 @@ define i16 @signbit_splat_mask(i8 %x, i16 %y) {
16961695
define <2 x i16> @signbit_splat_mask_commute(<2 x i5> %x, <2 x i16> %p) {
16971696
; CHECK-LABEL: @signbit_splat_mask_commute(
16981697
; CHECK-NEXT: [[Y:%.*]] = mul <2 x i16> [[P:%.*]], [[P]]
1699-
; CHECK-NEXT: [[A:%.*]] = ashr <2 x i5> [[X:%.*]], <i5 4, i5 poison>
1700-
; CHECK-NEXT: [[S:%.*]] = sext <2 x i5> [[A]] to <2 x i16>
1701-
; CHECK-NEXT: [[R:%.*]] = and <2 x i16> [[Y]], [[S]]
1698+
; CHECK-NEXT: [[ISNEG:%.*]] = icmp slt <2 x i5> [[X:%.*]], zeroinitializer
1699+
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[ISNEG]], <2 x i16> [[Y]], <2 x i16> zeroinitializer
17021700
; CHECK-NEXT: ret <2 x i16> [[R]]
17031701
;
17041702
%y = mul <2 x i16> %p, %p ; thwart complexity-based canonicalization
@@ -1712,8 +1710,8 @@ define i16 @signbit_splat_mask_use1(i8 %x, i16 %y) {
17121710
; CHECK-LABEL: @signbit_splat_mask_use1(
17131711
; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 7
17141712
; CHECK-NEXT: call void @use8(i8 [[A]])
1715-
; CHECK-NEXT: [[S:%.*]] = sext i8 [[A]] to i16
1716-
; CHECK-NEXT: [[R:%.*]] = and i16 [[S]], [[Y:%.*]]
1713+
; CHECK-NEXT: [[ISNEG:%.*]] = icmp slt i8 [[X]], 0
1714+
; CHECK-NEXT: [[R:%.*]] = select i1 [[ISNEG]], i16 [[Y:%.*]], i16 0
17171715
; CHECK-NEXT: ret i16 [[R]]
17181716
;
17191717
%a = ashr i8 %x, 7
@@ -1723,6 +1721,8 @@ define i16 @signbit_splat_mask_use1(i8 %x, i16 %y) {
17231721
ret i16 %r
17241722
}
17251723

1724+
; negative test - extra use
1725+
17261726
define i16 @signbit_splat_mask_use2(i8 %x, i16 %y) {
17271727
; CHECK-LABEL: @signbit_splat_mask_use2(
17281728
; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 7
@@ -1738,6 +1738,8 @@ define i16 @signbit_splat_mask_use2(i8 %x, i16 %y) {
17381738
ret i16 %r
17391739
}
17401740

1741+
; negative test - wrong extend
1742+
17411743
define i16 @not_signbit_splat_mask1(i8 %x, i16 %y) {
17421744
; CHECK-LABEL: @not_signbit_splat_mask1(
17431745
; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 7
@@ -1751,6 +1753,8 @@ define i16 @not_signbit_splat_mask1(i8 %x, i16 %y) {
17511753
ret i16 %r
17521754
}
17531755

1756+
; negative test - wrong shift amount
1757+
17541758
define i16 @not_signbit_splat_mask2(i8 %x, i16 %y) {
17551759
; CHECK-LABEL: @not_signbit_splat_mask2(
17561760
; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 6
@@ -1915,6 +1919,8 @@ define i16 @invert_signbit_splat_mask_use2(i8 %x, i16 %y) {
19151919
ret i16 %r
19161920
}
19171921

1922+
; negative test - extra use
1923+
19181924
define i16 @invert_signbit_splat_mask_use3(i8 %x, i16 %y) {
19191925
; CHECK-LABEL: @invert_signbit_splat_mask_use3(
19201926
; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 7
@@ -1932,6 +1938,8 @@ define i16 @invert_signbit_splat_mask_use3(i8 %x, i16 %y) {
19321938
ret i16 %r
19331939
}
19341940

1941+
; negative test - wrong extend
1942+
19351943
define i16 @not_invert_signbit_splat_mask1(i8 %x, i16 %y) {
19361944
; CHECK-LABEL: @not_invert_signbit_splat_mask1(
19371945
; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 7
@@ -1947,6 +1955,8 @@ define i16 @not_invert_signbit_splat_mask1(i8 %x, i16 %y) {
19471955
ret i16 %r
19481956
}
19491957

1958+
; negative test - wrong shift amount
1959+
19501960
define i16 @not_invert_signbit_splat_mask2(i8 %x, i16 %y) {
19511961
; CHECK-LABEL: @not_invert_signbit_splat_mask2(
19521962
; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 6

llvm/test/Transforms/InstCombine/negated-bitmask.ll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,8 @@ define i32 @neg_mask(i32 %x, i16 %y) {
278278
; CHECK-LABEL: @neg_mask(
279279
; CHECK-NEXT: [[S:%.*]] = sext i16 [[Y:%.*]] to i32
280280
; CHECK-NEXT: [[SUB1:%.*]] = sub nsw i32 [[X:%.*]], [[S]]
281-
; CHECK-NEXT: [[TMP1:%.*]] = ashr i16 [[Y]], 15
282-
; CHECK-NEXT: [[TMP2:%.*]] = sext i16 [[TMP1]] to i32
283-
; CHECK-NEXT: [[R:%.*]] = and i32 [[SUB1]], [[TMP2]]
281+
; CHECK-NEXT: [[ISNEG:%.*]] = icmp slt i16 [[Y]], 0
282+
; CHECK-NEXT: [[R:%.*]] = select i1 [[ISNEG]], i32 [[SUB1]], i32 0
284283
; CHECK-NEXT: ret i32 [[R]]
285284
;
286285
%s = sext i16 %y to i32
@@ -296,9 +295,8 @@ define i32 @neg_mask_const(i16 %x) {
296295
; CHECK-LABEL: @neg_mask_const(
297296
; CHECK-NEXT: [[S:%.*]] = sext i16 [[X:%.*]] to i32
298297
; CHECK-NEXT: [[SUB1:%.*]] = sub nsw i32 1000, [[S]]
299-
; CHECK-NEXT: [[TMP1:%.*]] = ashr i16 [[X]], 15
300-
; CHECK-NEXT: [[TMP2:%.*]] = sext i16 [[TMP1]] to i32
301-
; CHECK-NEXT: [[R:%.*]] = and i32 [[SUB1]], [[TMP2]]
298+
; CHECK-NEXT: [[ISNEG:%.*]] = icmp slt i16 [[X]], 0
299+
; CHECK-NEXT: [[R:%.*]] = select i1 [[ISNEG]], i32 [[SUB1]], i32 0
302300
; CHECK-NEXT: ret i32 [[R]]
303301
;
304302
%s = sext i16 %x to i32

0 commit comments

Comments
 (0)