Skip to content

Commit 146d548

Browse files
committed
[InstCombine] Fold A pred C ? (A >> BW - 1) : 1 --> ZExt(A pred C ? A < 0 : 1)
1 parent dd694fd commit 146d548

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3409,6 +3409,25 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
34093409
return replaceOperand(SI, 2, S);
34103410
}
34113411

3412+
{
3413+
// A pred C ? (A >> BW - 1) : 1 --> ZExt(A pred C ? A < 0 : 1)
3414+
CmpInst::Predicate Pred;
3415+
Value *A;
3416+
const APInt *C;
3417+
if (match(CondVal, m_ICmp(Pred, m_Value(A), m_APInt(C))) &&
3418+
match(TrueVal,
3419+
m_LShr(m_Specific(A),
3420+
m_SpecificInt(A->getType()->getScalarSizeInBits() - 1))) &&
3421+
match(FalseVal, m_One()) && TrueVal->hasOneUse()) {
3422+
auto *NewTrue =
3423+
Builder.CreateICmpSLT(A, ConstantInt::getNullValue(A->getType()));
3424+
auto *NewFalse = ConstantInt::get(NewTrue->getType(), 1);
3425+
auto *NewSelect = Builder.CreateSelect(CondVal, NewTrue, NewFalse);
3426+
auto *ZExt = Builder.CreateZExt(NewSelect, A->getType());
3427+
return replaceInstUsesWith(SI, ZExt);
3428+
}
3429+
}
3430+
34123431
if (Instruction *R = foldSelectOfBools(SI))
34133432
return R;
34143433

llvm/test/Transforms/InstCombine/icmp-select.ll

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ declare i8 @llvm.umin.i8(i8, i8)
77

88
define i32 @test_icmp_select_lte(i32 %x) {
99
; CHECK-LABEL: @test_icmp_select_lte(
10-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1234
11-
; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[X]], 31
12-
; CHECK-NEXT: [[RE:%.*]] = select i1 [[CMP]], i32 [[LSHR]], i32 1
10+
; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X:%.*]], 1233
11+
; CHECK-NEXT: [[RE:%.*]] = zext i1 [[TMP1]] to i32
1312
; CHECK-NEXT: ret i32 [[RE]]
1413
;
1514
%cmp = icmp slt i32 %x, 1234
@@ -20,9 +19,8 @@ define i32 @test_icmp_select_lte(i32 %x) {
2019

2120
define i16 @test_icmp_select_sgt(i16 %x) {
2221
; CHECK-LABEL: @test_icmp_select_sgt(
23-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[X:%.*]], 123
24-
; CHECK-NEXT: [[LSHR:%.*]] = lshr i16 [[X]], 15
25-
; CHECK-NEXT: [[RE:%.*]] = select i1 [[CMP]], i16 [[LSHR]], i16 1
22+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[X:%.*]], 124
23+
; CHECK-NEXT: [[RE:%.*]] = zext i1 [[CMP]] to i16
2624
; CHECK-NEXT: ret i16 [[RE]]
2725
;
2826
%cmp = icmp sgt i16 %x, 123
@@ -33,9 +31,8 @@ define i16 @test_icmp_select_sgt(i16 %x) {
3331

3432
define i8 @test_icmp_select_ugt(i8 %x) {
3533
; CHECK-LABEL: @test_icmp_select_ugt(
36-
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], 10
37-
; CHECK-NEXT: [[LSHR:%.*]] = lshr i8 [[X]], 7
38-
; CHECK-NEXT: [[RE:%.*]] = select i1 [[CMP]], i8 [[LSHR]], i8 1
34+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], 11
35+
; CHECK-NEXT: [[RE:%.*]] = zext i1 [[TMP1]] to i8
3936
; CHECK-NEXT: ret i8 [[RE]]
4037
;
4138
%cmp = icmp ugt i8 %x, 10
@@ -46,9 +43,8 @@ define i8 @test_icmp_select_ugt(i8 %x) {
4643

4744
define <2 x i32> @test_icmp_select_sge_vector(<2 x i32> %x) {
4845
; CHECK-LABEL: @test_icmp_select_sge_vector(
49-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 511, i32 511>
50-
; CHECK-NEXT: [[LSHR:%.*]] = lshr <2 x i32> [[X]], <i32 31, i32 31>
51-
; CHECK-NEXT: [[RE:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[LSHR]], <2 x i32> <i32 1, i32 1>
46+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 512, i32 512>
47+
; CHECK-NEXT: [[RE:%.*]] = zext <2 x i1> [[CMP]] to <2 x i32>
5248
; CHECK-NEXT: ret <2 x i32> [[RE]]
5349
;
5450
%cmp = icmp sge <2 x i32> %x, <i32 512, i32 512>

0 commit comments

Comments
 (0)