Skip to content

Commit bd90b60

Browse files
committed
[InstCombine] Canonicalize switch(zext/sext(X)) to switch(X)
1 parent d3e89f1 commit bd90b60

File tree

4 files changed

+41
-37
lines changed

4 files changed

+41
-37
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3247,6 +3247,25 @@ Instruction *InstCombinerImpl::visitSwitchInst(SwitchInst &SI) {
32473247
}
32483248
}
32493249

3250+
// Fold switch(zext/sext(X)) into switch(X) if possible.
3251+
if (match(Cond, m_ZExtOrSExt(m_Value(Op0)))) {
3252+
bool IsZExt = isa<ZExtInst>(Cond);
3253+
Type *SrcTy = Op0->getType();
3254+
unsigned NewWidth = SrcTy->getScalarSizeInBits();
3255+
3256+
if (all_of(SI.cases(), [&](const auto &Case) {
3257+
const APInt &CaseVal = Case.getCaseValue()->getValue();
3258+
return IsZExt ? CaseVal.isIntN(NewWidth)
3259+
: CaseVal.isSignedIntN(NewWidth);
3260+
})) {
3261+
for (auto &Case : SI.cases()) {
3262+
APInt TruncatedCase = Case.getCaseValue()->getValue().trunc(NewWidth);
3263+
Case.setValue(ConstantInt::get(SI.getContext(), TruncatedCase));
3264+
}
3265+
return replaceOperand(SI, 0, Op0);
3266+
}
3267+
}
3268+
32503269
KnownBits Known = computeKnownBits(Cond, 0, &SI);
32513270
unsigned LeadingKnownZeros = Known.countMinLeadingZeros();
32523271
unsigned LeadingKnownOnes = Known.countMinLeadingOnes();

llvm/test/Transforms/InstCombine/phi.ll

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -996,10 +996,9 @@ done:
996996
define i1 @PR24766(i8 %x1, i8 %x2, i8 %condition) {
997997
; CHECK-LABEL: @PR24766(
998998
; CHECK-NEXT: entry:
999-
; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[CONDITION:%.*]] to i32
1000-
; CHECK-NEXT: switch i32 [[CONV]], label [[EPILOG:%.*]] [
1001-
; CHECK-NEXT: i32 0, label [[SW1:%.*]]
1002-
; CHECK-NEXT: i32 1, label [[SW2:%.*]]
999+
; CHECK-NEXT: switch i8 [[CONDITION:%.*]], label [[EPILOG:%.*]] [
1000+
; CHECK-NEXT: i8 0, label [[SW1:%.*]]
1001+
; CHECK-NEXT: i8 1, label [[SW2:%.*]]
10031002
; CHECK-NEXT: ]
10041003
; CHECK: sw1:
10051004
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]]
@@ -1040,10 +1039,9 @@ epilog:
10401039
define i1 @PR24766_no_constants(i8 %x1, i8 %x2, i8 %condition, i1 %another_condition) {
10411040
; CHECK-LABEL: @PR24766_no_constants(
10421041
; CHECK-NEXT: entry:
1043-
; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[CONDITION:%.*]] to i32
1044-
; CHECK-NEXT: switch i32 [[CONV]], label [[EPILOG:%.*]] [
1045-
; CHECK-NEXT: i32 0, label [[SW1:%.*]]
1046-
; CHECK-NEXT: i32 1, label [[SW2:%.*]]
1042+
; CHECK-NEXT: switch i8 [[CONDITION:%.*]], label [[EPILOG:%.*]] [
1043+
; CHECK-NEXT: i8 0, label [[SW1:%.*]]
1044+
; CHECK-NEXT: i8 1, label [[SW2:%.*]]
10471045
; CHECK-NEXT: ]
10481046
; CHECK: sw1:
10491047
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]]
@@ -1085,10 +1083,9 @@ epilog:
10851083
define i1 @PR24766_two_constants(i8 %x1, i8 %x2, i8 %condition) {
10861084
; CHECK-LABEL: @PR24766_two_constants(
10871085
; CHECK-NEXT: entry:
1088-
; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[CONDITION:%.*]] to i32
1089-
; CHECK-NEXT: switch i32 [[CONV]], label [[EPILOG:%.*]] [
1090-
; CHECK-NEXT: i32 0, label [[SW1:%.*]]
1091-
; CHECK-NEXT: i32 1, label [[SW2:%.*]]
1086+
; CHECK-NEXT: switch i8 [[CONDITION:%.*]], label [[EPILOG:%.*]] [
1087+
; CHECK-NEXT: i8 0, label [[SW1:%.*]]
1088+
; CHECK-NEXT: i8 1, label [[SW2:%.*]]
10921089
; CHECK-NEXT: ]
10931090
; CHECK: sw1:
10941091
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]]
@@ -1128,11 +1125,10 @@ epilog:
11281125
define i1 @PR24766_two_constants_two_var(i8 %x1, i8 %x2, i8 %condition) {
11291126
; CHECK-LABEL: @PR24766_two_constants_two_var(
11301127
; CHECK-NEXT: entry:
1131-
; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[CONDITION:%.*]] to i32
1132-
; CHECK-NEXT: switch i32 [[CONV]], label [[EPILOG:%.*]] [
1133-
; CHECK-NEXT: i32 0, label [[SW1:%.*]]
1134-
; CHECK-NEXT: i32 1, label [[SW2:%.*]]
1135-
; CHECK-NEXT: i32 2, label [[SW3:%.*]]
1128+
; CHECK-NEXT: switch i8 [[CONDITION:%.*]], label [[EPILOG:%.*]] [
1129+
; CHECK-NEXT: i8 0, label [[SW1:%.*]]
1130+
; CHECK-NEXT: i8 1, label [[SW2:%.*]]
1131+
; CHECK-NEXT: i8 2, label [[SW3:%.*]]
11361132
; CHECK-NEXT: ]
11371133
; CHECK: sw1:
11381134
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]]

llvm/test/Transforms/InstCombine/switch-zext-sext.ll

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,10 @@ define i1 @test_switch_with_sext(i16 %a, i1 %b, i1 %c) {
3333
; CHECK-LABEL: define i1 @test_switch_with_sext(
3434
; CHECK-SAME: i16 [[A:%.*]], i1 [[B:%.*]], i1 [[C:%.*]]) {
3535
; CHECK-NEXT: entry:
36-
; CHECK-NEXT: [[A_EXT:%.*]] = sext i16 [[A]] to i32
37-
; CHECK-NEXT: switch i32 [[A_EXT]], label [[SW_DEFAULT:%.*]] [
38-
; CHECK-NEXT: i32 37, label [[SW_BB:%.*]]
39-
; CHECK-NEXT: i32 38, label [[SW_BB]]
40-
; CHECK-NEXT: i32 39, label [[SW_BB]]
36+
; CHECK-NEXT: switch i16 [[A]], label [[SW_DEFAULT:%.*]] [
37+
; CHECK-NEXT: i16 37, label [[SW_BB:%.*]]
38+
; CHECK-NEXT: i16 38, label [[SW_BB]]
39+
; CHECK-NEXT: i16 39, label [[SW_BB]]
4140
; CHECK-NEXT: ]
4241
; CHECK: sw.bb:
4342
; CHECK-NEXT: ret i1 [[B]]

llvm/test/Transforms/PhaseOrdering/switch-sext.ll

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,19 @@
22
; RUN: opt -S -passes='default<O3>' < %s | FileCheck %s
33

44
define i8 @test_switch_with_sext_phi(i8 %code) {
5-
; CHECK-LABEL: define i8 @test_switch_with_sext_phi(
5+
; CHECK-LABEL: define noundef i8 @test_switch_with_sext_phi(
66
; CHECK-SAME: i8 [[CODE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
77
; CHECK-NEXT: entry:
8-
; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[CODE]] to i32
9-
; CHECK-NEXT: switch i32 [[CONV]], label [[SW_DEFAULT:%.*]] [
10-
; CHECK-NEXT: i32 105, label [[SW_EPILOG:%.*]]
11-
; CHECK-NEXT: i32 73, label [[SW_BB1:%.*]]
12-
; CHECK-NEXT: i32 108, label [[SW_BB2:%.*]]
13-
; CHECK-NEXT: i32 76, label [[SW_BB3:%.*]]
14-
; CHECK-NEXT: i32 63, label [[SW_BB4:%.*]]
8+
; CHECK-NEXT: switch i8 [[CODE]], label [[SW_EPILOG:%.*]] [
9+
; CHECK-NEXT: i8 76, label [[SW_BB3:%.*]]
10+
; CHECK-NEXT: i8 108, label [[SW_BB2:%.*]]
1511
; CHECK-NEXT: ]
16-
; CHECK: sw.bb1:
17-
; CHECK-NEXT: br label [[SW_EPILOG]]
1812
; CHECK: sw.bb2:
1913
; CHECK-NEXT: br label [[SW_EPILOG]]
2014
; CHECK: sw.bb3:
2115
; CHECK-NEXT: br label [[SW_EPILOG]]
22-
; CHECK: sw.bb4:
23-
; CHECK-NEXT: br label [[SW_EPILOG]]
24-
; CHECK: sw.default:
25-
; CHECK-NEXT: br label [[SW_EPILOG]]
2616
; CHECK: sw.epilog:
27-
; CHECK-NEXT: [[PEP_CODE:%.*]] = phi i8 [ [[CODE]], [[SW_DEFAULT]] ], [ 63, [[SW_BB4]] ], [ 81, [[SW_BB3]] ], [ 113, [[SW_BB2]] ], [ 73, [[SW_BB1]] ], [ 105, [[ENTRY:%.*]] ]
17+
; CHECK-NEXT: [[PEP_CODE:%.*]] = phi i8 [ 81, [[SW_BB3]] ], [ 113, [[SW_BB2]] ], [ [[CODE]], [[ENTRY:%.*]] ]
2818
; CHECK-NEXT: ret i8 [[PEP_CODE]]
2919
;
3020
entry:

0 commit comments

Comments
 (0)