Skip to content

Commit

Permalink
[InstCombine] Don't change switch table from desirable to illegal types
Browse files Browse the repository at this point in the history
In InstCombine we treat i8/i16 as desirable, even if they are not legal.
The current logic in shouldChangeType will decide to convert from an
illegal but desirable type (such as an i8) to an illegal and undesirable
type (such as i3). This patch prevents changing the switch conditions to
an irregular type on like Arm/AArch64 where i8/i16 are not legal.

This is the same issue as https://reviews.llvm.org/D54115. In the case I
was looking it is was converting an i32 switch to an i8 switch, which
then became a i3 switch.

Differential Revision: https://reviews.llvm.org/D136763
  • Loading branch information
davemgreen committed Oct 28, 2022
1 parent beb9977 commit 5dd7d2c
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 24 deletions.
17 changes: 9 additions & 8 deletions llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
Expand Up @@ -223,11 +223,12 @@ bool InstCombinerImpl::isDesirableIntType(unsigned BitWidth) const {

/// Return true if it is desirable to convert an integer computation from a
/// given bit width to a new bit width.
/// We don't want to convert from a legal to an illegal type or from a smaller
/// to a larger illegal type. A width of '1' is always treated as a desirable
/// type because i1 is a fundamental type in IR, and there are many specialized
/// optimizations for i1 types. Common/desirable widths are equally treated as
/// legal to convert to, in order to open up more combining opportunities.
/// We don't want to convert from a legal or desirable type (like i8) to an
/// illegal type or from a smaller to a larger illegal type. A width of '1'
/// is always treated as a desirable type because i1 is a fundamental type in
/// IR, and there are many specialized optimizations for i1 types.
/// Common/desirable widths are equally treated as legal to convert to, in
/// order to open up more combining opportunities.
bool InstCombinerImpl::shouldChangeType(unsigned FromWidth,
unsigned ToWidth) const {
bool FromLegal = FromWidth == 1 || DL.isLegalInteger(FromWidth);
Expand All @@ -238,9 +239,9 @@ bool InstCombinerImpl::shouldChangeType(unsigned FromWidth,
if (ToWidth < FromWidth && isDesirableIntType(ToWidth))
return true;

// If this is a legal integer from type, and the result would be an illegal
// type, don't do the transformation.
if (FromLegal && !ToLegal)
// If this is a legal or desiable integer from type, and the result would be
// an illegal type, don't do the transformation.
if ((FromLegal || isDesirableIntType(FromWidth)) && !ToLegal)
return false;

// Otherwise, if both are illegal, do not increase the size of the result. We
Expand Down
11 changes: 5 additions & 6 deletions llvm/test/Transforms/InstCombine/known-phi-recurse.ll
Expand Up @@ -92,12 +92,11 @@ define i32 @neg_many_branches(i64 %x) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[Y:%.*]] = call i64 @llvm.ctpop.i64(i64 [[X:%.*]]), !range [[RNG0]]
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 [[Y]] to i32
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i64 [[Y]] to i7
; CHECK-NEXT: switch i7 [[TRUNC1]], label [[END:%.*]] [
; CHECK-NEXT: i7 1, label [[ONE:%.*]]
; CHECK-NEXT: i7 2, label [[TWO:%.*]]
; CHECK-NEXT: i7 3, label [[THREE:%.*]]
; CHECK-NEXT: i7 4, label [[FOUR:%.*]]
; CHECK-NEXT: switch i32 [[TRUNC]], label [[END:%.*]] [
; CHECK-NEXT: i32 1, label [[ONE:%.*]]
; CHECK-NEXT: i32 2, label [[TWO:%.*]]
; CHECK-NEXT: i32 3, label [[THREE:%.*]]
; CHECK-NEXT: i32 4, label [[FOUR:%.*]]
; CHECK-NEXT: ]
; CHECK: one:
; CHECK-NEXT: [[A:%.*]] = add nuw nsw i32 [[TRUNC]], 1
Expand Down
9 changes: 4 additions & 5 deletions llvm/test/Transforms/InstCombine/narrow-switch.ll
Expand Up @@ -138,11 +138,10 @@ sw.default:
define i8 @PR31260(i8 %x) {
; ALL-LABEL: @PR31260(
; ALL-NEXT: entry:
; ALL-NEXT: [[TMP0:%.*]] = trunc i8 %x to i2
; ALL-NEXT: [[TRUNC:%.*]] = and i2 [[TMP0]], -2
; ALL-NEXT: switch i2 [[TRUNC]], label %exit [
; ALL-NEXT: i2 0, label %case126
; ALL-NEXT: i2 -2, label %case124
; ALL-NEXT: [[T4:%.*]] = and i8 [[X:%.*]], 2
; ALL-NEXT: switch i8 [[T4]], label [[EXIT:%.*]] [
; ALL-NEXT: i8 0, label [[CASE126:%.*]]
; ALL-NEXT: i8 2, label [[CASE124:%.*]]
; ALL-NEXT: ]
; ALL: exit:
; ALL-NEXT: ret i8 1
Expand Down
Expand Up @@ -10,15 +10,15 @@ define i64 @test() {
; CHECK-NEXT: br label [[BB10:%.*]]
; CHECK: bb10:
; CHECK-NEXT: [[ITER1_SROA_5_0:%.*]] = phi i64 [ 100000, [[START:%.*]] ], [ [[SPEC_SELECT:%.*]], [[BB3_I_I:%.*]] ]
; CHECK-NEXT: [[ITER1_SROA_9_0:%.*]] = phi i2 [ -2, [[START]] ], [ [[TMP3:%.*]], [[BB3_I_I]] ]
; CHECK-NEXT: [[ITER1_SROA_9_0:%.*]] = phi i8 [ 2, [[START]] ], [ [[TMP3:%.*]], [[BB3_I_I]] ]
; CHECK-NEXT: [[COUNT_1:%.*]] = phi i64 [ 0, [[START]] ], [ [[TMP4:%.*]], [[BB3_I_I]] ]
; CHECK-NEXT: switch i2 [[ITER1_SROA_9_0]], label [[BB12:%.*]] [
; CHECK-NEXT: i2 -2, label [[BB3_I_I]]
; CHECK-NEXT: i2 0, label [[BB3_I_I]]
; CHECK-NEXT: switch i8 [[ITER1_SROA_9_0]], label [[BB12:%.*]] [
; CHECK-NEXT: i8 2, label [[BB3_I_I]]
; CHECK-NEXT: i8 0, label [[BB3_I_I]]
; CHECK-NEXT: ]
; CHECK: bb3.i.i:
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[ITER1_SROA_5_0]], 0
; CHECK-NEXT: [[TMP3]] = zext i1 [[TMP2]] to i2
; CHECK-NEXT: [[TMP3]] = zext i1 [[TMP2]] to i8
; CHECK-NEXT: [[_5_0_I_I_I_I:%.*]] = add i64 [[ITER1_SROA_5_0]], -1
; CHECK-NEXT: [[SPEC_SELECT]] = select i1 [[TMP2]], i64 0, i64 [[_5_0_I_I_I_I]]
; CHECK-NEXT: [[TMP4]] = add i64 [[COUNT_1]], [[ITER1_SROA_5_0]]
Expand Down

0 comments on commit 5dd7d2c

Please sign in to comment.