Skip to content

Commit 7b07c01

Browse files
[InstCombine] Support arbitrary const shift amount for lshr (sext i1 ...)
Add lshr (sext i1 X to iN), C --> select (X, -1 >> C, 0) case. This expands C == N-1 case to arbitrary C. Fixes PR52078. Reviewed By: spatel, RKSimon, lebedev.ri Differential Revision: https://reviews.llvm.org/D111330
1 parent e23351c commit 7b07c01

File tree

3 files changed

+27
-30
lines changed

3 files changed

+27
-30
lines changed

llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,28 +1067,31 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
10671067
return new ZExtInst(NewLShr, Ty);
10681068
}
10691069

1070-
if (match(Op0, m_SExt(m_Value(X))) &&
1071-
(!Ty->isIntegerTy() || shouldChangeType(Ty, X->getType()))) {
1072-
// Are we moving the sign bit to the low bit and widening with high zeros?
1070+
if (match(Op0, m_SExt(m_Value(X)))) {
10731071
unsigned SrcTyBitWidth = X->getType()->getScalarSizeInBits();
1074-
if (ShAmtC == BitWidth - 1) {
1075-
// lshr (sext i1 X to iN), N-1 --> zext X to iN
1076-
if (SrcTyBitWidth == 1)
1077-
return new ZExtInst(X, Ty);
1072+
// lshr (sext i1 X to iN), C --> select (X, -1 >> C, 0)
1073+
if (SrcTyBitWidth == 1) {
1074+
auto *NewC = ConstantInt::get(
1075+
Ty, APInt::getLowBitsSet(BitWidth, BitWidth - ShAmtC));
1076+
return SelectInst::Create(X, NewC, ConstantInt::getNullValue(Ty));
1077+
}
10781078

1079-
// lshr (sext iM X to iN), N-1 --> zext (lshr X, M-1) to iN
1080-
if (Op0->hasOneUse()) {
1079+
if ((!Ty->isIntegerTy() || shouldChangeType(Ty, X->getType())) &&
1080+
Op0->hasOneUse()) {
1081+
// Are we moving the sign bit to the low bit and widening with high
1082+
// zeros? lshr (sext iM X to iN), N-1 --> zext (lshr X, M-1) to iN
1083+
if (ShAmtC == BitWidth - 1) {
10811084
Value *NewLShr = Builder.CreateLShr(X, SrcTyBitWidth - 1);
10821085
return new ZExtInst(NewLShr, Ty);
10831086
}
1084-
}
10851087

1086-
// lshr (sext iM X to iN), N-M --> zext (ashr X, min(N-M, M-1)) to iN
1087-
if (ShAmtC == BitWidth - SrcTyBitWidth && Op0->hasOneUse()) {
1088-
// The new shift amount can't be more than the narrow source type.
1089-
unsigned NewShAmt = std::min(ShAmtC, SrcTyBitWidth - 1);
1090-
Value *AShr = Builder.CreateAShr(X, NewShAmt);
1091-
return new ZExtInst(AShr, Ty);
1088+
// lshr (sext iM X to iN), N-M --> zext (ashr X, min(N-M, M-1)) to iN
1089+
if (ShAmtC == BitWidth - SrcTyBitWidth) {
1090+
// The new shift amount can't be more than the narrow source type.
1091+
unsigned NewShAmt = std::min(ShAmtC, SrcTyBitWidth - 1);
1092+
Value *AShr = Builder.CreateAShr(X, NewShAmt);
1093+
return new ZExtInst(AShr, Ty);
1094+
}
10921095
}
10931096
}
10941097

llvm/test/Transforms/InstCombine/lshr.ll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -620,8 +620,7 @@ define i12 @trunc_sandwich_big_sum_shift2_use1(i32 %x) {
620620

621621
define i16 @lshr_sext_i1_to_i16(i1 %a) {
622622
; CHECK-LABEL: @lshr_sext_i1_to_i16(
623-
; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[A:%.*]] to i16
624-
; CHECK-NEXT: [[LSHR:%.*]] = lshr i16 [[SEXT]], 4
623+
; CHECK-NEXT: [[LSHR:%.*]] = select i1 [[A:%.*]], i16 4095, i16 0
625624
; CHECK-NEXT: ret i16 [[LSHR]]
626625
;
627626
%sext = sext i1 %a to i16
@@ -631,8 +630,7 @@ define i16 @lshr_sext_i1_to_i16(i1 %a) {
631630

632631
define i128 @lshr_sext_i1_to_i128(i1 %a) {
633632
; CHECK-LABEL: @lshr_sext_i1_to_i128(
634-
; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[A:%.*]] to i128
635-
; CHECK-NEXT: [[LSHR:%.*]] = lshr i128 [[SEXT]], 42
633+
; CHECK-NEXT: [[LSHR:%.*]] = select i1 [[A:%.*]], i128 77371252455336267181195263, i128 0
636634
; CHECK-NEXT: ret i128 [[LSHR]]
637635
;
638636
%sext = sext i1 %a to i128
@@ -644,7 +642,7 @@ define i32 @lshr_sext_i1_to_i32_use(i1 %a) {
644642
; CHECK-LABEL: @lshr_sext_i1_to_i32_use(
645643
; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[A:%.*]] to i32
646644
; CHECK-NEXT: call void @use(i32 [[SEXT]])
647-
; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[SEXT]], 14
645+
; CHECK-NEXT: [[LSHR:%.*]] = select i1 [[A]], i32 262143, i32 0
648646
; CHECK-NEXT: ret i32 [[LSHR]]
649647
;
650648
%sext = sext i1 %a to i32
@@ -657,7 +655,7 @@ define <3 x i14> @lshr_sext_i1_to_i14_splat_vec_use1(<3 x i1> %a) {
657655
; CHECK-LABEL: @lshr_sext_i1_to_i14_splat_vec_use1(
658656
; CHECK-NEXT: [[SEXT:%.*]] = sext <3 x i1> [[A:%.*]] to <3 x i14>
659657
; CHECK-NEXT: call void @usevec(<3 x i14> [[SEXT]])
660-
; CHECK-NEXT: [[LSHR:%.*]] = lshr <3 x i14> [[SEXT]], <i14 4, i14 4, i14 4>
658+
; CHECK-NEXT: [[LSHR:%.*]] = select <3 x i1> [[A]], <3 x i14> <i14 1023, i14 1023, i14 1023>, <3 x i14> zeroinitializer
661659
; CHECK-NEXT: ret <3 x i14> [[LSHR]]
662660
;
663661
%sext = sext <3 x i1> %a to <3 x i14>

llvm/test/Transforms/PhaseOrdering/X86/pr52078.ll

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ define i16 @foo(i1 %a) {
1616
; IC-NEXT: ret i16 [[TRUNC]]
1717
;
1818
; AIC_AND_IC-LABEL: @foo(
19-
; AIC_AND_IC-NEXT: [[SEXT:%.*]] = sext i1 [[A:%.*]] to i16
20-
; AIC_AND_IC-NEXT: [[LSHR:%.*]] = lshr i16 [[SEXT]], 1
19+
; AIC_AND_IC-NEXT: [[LSHR:%.*]] = select i1 [[A:%.*]], i16 32767, i16 0
2120
; AIC_AND_IC-NEXT: ret i16 [[LSHR]]
2221
;
2322
%sext = sext i1 %a to i16
@@ -29,18 +28,15 @@ define i16 @foo(i1 %a) {
2928

3029
define i16 @foo2(i1 %a) {
3130
; CHECK-LABEL: @foo2(
32-
; CHECK-NEXT: [[S:%.*]] = sext i1 [[A:%.*]] to i16
33-
; CHECK-NEXT: [[LSHR:%.*]] = lshr i16 [[S]], 1
31+
; CHECK-NEXT: [[LSHR:%.*]] = select i1 [[A:%.*]], i16 32767, i16 0
3432
; CHECK-NEXT: ret i16 [[LSHR]]
3533
;
3634
; IC-LABEL: @foo2(
37-
; IC-NEXT: [[S:%.*]] = sext i1 [[A:%.*]] to i16
38-
; IC-NEXT: [[LSHR:%.*]] = lshr i16 [[S]], 1
35+
; IC-NEXT: [[LSHR:%.*]] = select i1 [[A:%.*]], i16 32767, i16 0
3936
; IC-NEXT: ret i16 [[LSHR]]
4037
;
4138
; AIC_AND_IC-LABEL: @foo2(
42-
; AIC_AND_IC-NEXT: [[S:%.*]] = sext i1 [[A:%.*]] to i16
43-
; AIC_AND_IC-NEXT: [[LSHR:%.*]] = lshr i16 [[S]], 1
39+
; AIC_AND_IC-NEXT: [[LSHR:%.*]] = select i1 [[A:%.*]], i16 32767, i16 0
4440
; AIC_AND_IC-NEXT: ret i16 [[LSHR]]
4541
;
4642
%s = sext i1 %a to i16

0 commit comments

Comments
 (0)