llvm-project/llvm/test/Transforms/SimplifyCFG/switch-transformations-no-lut.ll
Matthew Maurer 9e4dddcc12
[SimplifyCFG] Allow phi folding for boolean logic over non-equality (#185124)
Phi folding is suppressed over binary operation inputs in order to avoid
interfering with switch formation.

After #183692, code (for example, Rust's ASCII character classification)
may get an `or` hoisted up into it, which suppresses
`foldTwoEntryPHINode`. This then produces branching code where
previously we generated straightline code.

To maintain switch formation while preventing any binops from breaking
phi folding, restrict the scenario in which Phi folding is suppressed to
binops of *equality* ops. This should mesh with switch statements, which
require an explicit list of values, while not breaking optimization over
> / < etc. which would never have been promoted to switches in the first
place.

Fixes: rust-lang/rust#153504
2026-03-16 15:02:00 -07:00

517 lines
16 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes='simplifycfg<switch-to-arithmetic>' < %s | FileCheck %s --check-prefix=OPTNOLUT
; RUN: %if amdgpu-registered-target %{ opt -mtriple=amdgcn--amdpal -S -passes='simplifycfg<switch-to-lookup>' < %s | FileCheck %s --check-prefix=TTINOLUT %}
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define i32 @linear_transform_with_default(i32 %x) {
; OPTNOLUT-LABEL: define i32 @linear_transform_with_default(
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
; OPTNOLUT-NEXT: [[ENTRY:.*:]]
; OPTNOLUT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X]], 4
; OPTNOLUT-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul nsw i32 [[X]], 3
; OPTNOLUT-NEXT: [[SWITCH_OFFSET:%.*]] = add nsw i32 [[SWITCH_IDX_MULT]], 1
; OPTNOLUT-NEXT: [[IDX:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 13
; OPTNOLUT-NEXT: ret i32 [[IDX]]
;
; TTINOLUT-LABEL: define i32 @linear_transform_with_default(
; TTINOLUT-SAME: i32 [[X:%.*]]) {
; TTINOLUT-NEXT: [[ENTRY:.*]]:
; TTINOLUT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X]], 4
; TTINOLUT-NEXT: br i1 [[TMP0]], label %[[SWITCH_LOOKUP:.*]], label %[[END:.*]]
; TTINOLUT: [[SWITCH_LOOKUP]]:
; TTINOLUT-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul nsw i32 [[X]], 3
; TTINOLUT-NEXT: [[SWITCH_OFFSET:%.*]] = add nsw i32 [[SWITCH_IDX_MULT]], 1
; TTINOLUT-NEXT: br label %[[END]]
; TTINOLUT: [[END]]:
; TTINOLUT-NEXT: [[IDX:%.*]] = phi i32 [ [[SWITCH_OFFSET]], %[[SWITCH_LOOKUP]] ], [ 13, %[[ENTRY]] ]
; TTINOLUT-NEXT: ret i32 [[IDX]]
;
entry:
switch i32 %x, label %end [
i32 0, label %case0
i32 1, label %case1
i32 2, label %case2
i32 3, label %case3
]
case0:
br label %end
case1:
br label %end
case2:
br label %end
case3:
br label %end
end:
%idx = phi i32 [ 1, %case0 ], [ 4, %case1 ], [ 7, %case2 ], [ 10, %case3 ], [ 13, %entry ]
ret i32 %idx
}
define i32 @linear_transform_with_outlier(i32 %x) {
; OPTNOLUT-LABEL: define i32 @linear_transform_with_outlier(
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
; OPTNOLUT-NEXT: [[ENTRY:.*]]:
; OPTNOLUT-NEXT: switch i32 [[X]], label %[[END:.*]] [
; OPTNOLUT-NEXT: i32 0, label %[[CASE0:.*]]
; OPTNOLUT-NEXT: i32 1, label %[[CASE1:.*]]
; OPTNOLUT-NEXT: i32 2, label %[[CASE2:.*]]
; OPTNOLUT-NEXT: i32 3, label %[[CASE3:.*]]
; OPTNOLUT-NEXT: i32 4, label %[[CASE4:.*]]
; OPTNOLUT-NEXT: ]
; OPTNOLUT: [[CASE0]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[CASE1]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[CASE2]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[CASE3]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[CASE4]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[END]]:
; OPTNOLUT-NEXT: [[IDX:%.*]] = phi i32 [ 0, %[[CASE0]] ], [ 3, %[[CASE1]] ], [ 6, %[[CASE2]] ], [ 9, %[[CASE3]] ], [ 13, %[[CASE4]] ], [ 12, %[[ENTRY]] ]
; OPTNOLUT-NEXT: ret i32 [[IDX]]
;
; TTINOLUT-LABEL: define i32 @linear_transform_with_outlier(
; TTINOLUT-SAME: i32 [[X:%.*]]) {
; TTINOLUT-NEXT: [[ENTRY:.*]]:
; TTINOLUT-NEXT: switch i32 [[X]], label %[[END:.*]] [
; TTINOLUT-NEXT: i32 0, label %[[CASE0:.*]]
; TTINOLUT-NEXT: i32 1, label %[[CASE1:.*]]
; TTINOLUT-NEXT: i32 2, label %[[CASE2:.*]]
; TTINOLUT-NEXT: i32 3, label %[[CASE3:.*]]
; TTINOLUT-NEXT: i32 4, label %[[CASE4:.*]]
; TTINOLUT-NEXT: ]
; TTINOLUT: [[CASE0]]:
; TTINOLUT-NEXT: br label %[[END]]
; TTINOLUT: [[CASE1]]:
; TTINOLUT-NEXT: br label %[[END]]
; TTINOLUT: [[CASE2]]:
; TTINOLUT-NEXT: br label %[[END]]
; TTINOLUT: [[CASE3]]:
; TTINOLUT-NEXT: br label %[[END]]
; TTINOLUT: [[CASE4]]:
; TTINOLUT-NEXT: br label %[[END]]
; TTINOLUT: [[END]]:
; TTINOLUT-NEXT: [[IDX:%.*]] = phi i32 [ 0, %[[CASE0]] ], [ 3, %[[CASE1]] ], [ 6, %[[CASE2]] ], [ 9, %[[CASE3]] ], [ 13, %[[CASE4]] ], [ 12, %[[ENTRY]] ]
; TTINOLUT-NEXT: ret i32 [[IDX]]
;
entry:
switch i32 %x, label %end [
i32 0, label %case0
i32 1, label %case1
i32 2, label %case2
i32 3, label %case3
i32 4, label %case4
]
case0:
br label %end
case1:
br label %end
case2:
br label %end
case3:
br label %end
case4:
br label %end
end:
%idx = phi i32 [ 0, %case0 ], [ 3, %case1 ], [ 6, %case2 ], [ 9, %case3 ], [ 13, %case4 ], [ 12, %entry ]
ret i32 %idx
}
define i32 @linear_transform_no_default(i32 %x) {
; OPTNOLUT-LABEL: define i32 @linear_transform_no_default(
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
; OPTNOLUT-NEXT: [[ENTRY:.*:]]
; OPTNOLUT-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul nsw i32 [[X]], 3
; OPTNOLUT-NEXT: ret i32 [[SWITCH_IDX_MULT]]
;
; TTINOLUT-LABEL: define i32 @linear_transform_no_default(
; TTINOLUT-SAME: i32 [[X:%.*]]) {
; TTINOLUT-NEXT: [[ENTRY:.*:]]
; TTINOLUT-NEXT: [[IDX:%.*]] = mul nsw i32 [[X]], 3
; TTINOLUT-NEXT: ret i32 [[IDX]]
;
entry:
switch i32 %x, label %default [
i32 0, label %case0
i32 1, label %case1
i32 2, label %case2
i32 3, label %case3
i32 4, label %case4
]
case0:
br label %end
case1:
br label %end
case2:
br label %end
case3:
br label %end
case4:
br label %end
default:
unreachable
end:
%idx = phi i32 [ 0, %case0 ], [ 3, %case1 ], [ 6, %case2 ], [ 9, %case3 ], [ 12, %case4 ]
ret i32 %idx
}
define i4 @bitmap_no_default(i32 %x) {
; OPTNOLUT-LABEL: define i4 @bitmap_no_default(
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
; OPTNOLUT-NEXT: [[ENTRY:.*]]:
; OPTNOLUT-NEXT: switch i32 [[X]], label %[[DEFAULT:.*]] [
; OPTNOLUT-NEXT: i32 0, label %[[END:.*]]
; OPTNOLUT-NEXT: i32 1, label %[[CASE1:.*]]
; OPTNOLUT-NEXT: i32 2, label %[[CASE2:.*]]
; OPTNOLUT-NEXT: i32 3, label %[[CASE3:.*]]
; OPTNOLUT-NEXT: ]
; OPTNOLUT: [[CASE1]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[CASE2]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[CASE3]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[DEFAULT]]:
; OPTNOLUT-NEXT: unreachable
; OPTNOLUT: [[END]]:
; OPTNOLUT-NEXT: [[SWITCH_MASKED:%.*]] = phi i4 [ -8, %[[CASE3]] ], [ 2, %[[CASE1]] ], [ 4, %[[CASE2]] ], [ 0, %[[ENTRY]] ]
; OPTNOLUT-NEXT: ret i4 [[SWITCH_MASKED]]
;
; TTINOLUT-LABEL: define i4 @bitmap_no_default(
; TTINOLUT-SAME: i32 [[X:%.*]]) {
; TTINOLUT-NEXT: [[ENTRY:.*:]]
; TTINOLUT-NEXT: [[SWITCH_CAST:%.*]] = trunc i32 [[X]] to i16
; TTINOLUT-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i16 [[SWITCH_CAST]], 4
; TTINOLUT-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i16 -31712, [[SWITCH_SHIFTAMT]]
; TTINOLUT-NEXT: [[IDX:%.*]] = trunc i16 [[SWITCH_DOWNSHIFT]] to i4
; TTINOLUT-NEXT: ret i4 [[IDX]]
;
entry:
switch i32 %x, label %default [
i32 0, label %case0
i32 1, label %case1
i32 2, label %case2
i32 3, label %case3
]
case0:
br label %end
case1:
br label %end
case2:
br label %end
case3:
br label %end
default:
unreachable
end:
%idx = phi i4 [ 0, %case0 ], [ 2, %case1 ], [ 4, %case2 ], [ 8, %case3 ]
ret i4 %idx
}
define i4 @bitmap_with_default(i32 %x) {
; OPTNOLUT-LABEL: define i4 @bitmap_with_default(
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
; OPTNOLUT-NEXT: [[ENTRY:.*]]:
; OPTNOLUT-NEXT: switch i32 [[X]], label %[[DEFAULT:.*]] [
; OPTNOLUT-NEXT: i32 0, label %[[END:.*]]
; OPTNOLUT-NEXT: i32 1, label %[[CASE1:.*]]
; OPTNOLUT-NEXT: i32 2, label %[[CASE2:.*]]
; OPTNOLUT-NEXT: i32 3, label %[[CASE3:.*]]
; OPTNOLUT-NEXT: ]
; OPTNOLUT: [[CASE1]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[CASE2]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[CASE3]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[DEFAULT]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[END]]:
; OPTNOLUT-NEXT: [[IDX:%.*]] = phi i4 [ -1, %[[DEFAULT]] ], [ 2, %[[CASE1]] ], [ 4, %[[CASE2]] ], [ -8, %[[CASE3]] ], [ 0, %[[ENTRY]] ]
; OPTNOLUT-NEXT: ret i4 [[IDX]]
;
; TTINOLUT-LABEL: define i4 @bitmap_with_default(
; TTINOLUT-SAME: i32 [[X:%.*]]) {
; TTINOLUT-NEXT: [[ENTRY:.*]]:
; TTINOLUT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X]], 4
; TTINOLUT-NEXT: br i1 [[TMP0]], label %[[SWITCH_LOOKUP:.*]], label %[[END:.*]]
; TTINOLUT: [[SWITCH_LOOKUP]]:
; TTINOLUT-NEXT: [[SWITCH_CAST:%.*]] = trunc i32 [[X]] to i16
; TTINOLUT-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i16 [[SWITCH_CAST]], 4
; TTINOLUT-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i16 -31712, [[SWITCH_SHIFTAMT]]
; TTINOLUT-NEXT: [[SWITCH_MASKED:%.*]] = trunc i16 [[SWITCH_DOWNSHIFT]] to i4
; TTINOLUT-NEXT: br label %[[END]]
; TTINOLUT: [[END]]:
; TTINOLUT-NEXT: [[IDX:%.*]] = phi i4 [ [[SWITCH_MASKED]], %[[SWITCH_LOOKUP]] ], [ -1, %[[ENTRY]] ]
; TTINOLUT-NEXT: ret i4 [[IDX]]
;
entry:
switch i32 %x, label %default [
i32 0, label %case0
i32 1, label %case1
i32 2, label %case2
i32 3, label %case3
]
case0:
br label %end
case1:
br label %end
case2:
br label %end
case3:
br label %end
default:
br label %end
end:
%idx = phi i4 [ 0, %case0 ], [ 2, %case1 ], [ 4, %case2 ], [ 8, %case3 ], [15, %default]
ret i4 %idx
}
define i32 @single_value_no_default(i32 %x) {
; OPTNOLUT-LABEL: define i32 @single_value_no_default(
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
; OPTNOLUT-NEXT: [[ENTRY:.*:]]
; OPTNOLUT-NEXT: ret i32 2
;
; TTINOLUT-LABEL: define i32 @single_value_no_default(
; TTINOLUT-SAME: i32 [[X:%.*]]) {
; TTINOLUT-NEXT: [[ENTRY:.*:]]
; TTINOLUT-NEXT: ret i32 2
;
entry:
switch i32 %x, label %default [
i32 0, label %case0
i32 1, label %case1
i32 2, label %case2
i32 3, label %case3
i32 4, label %case4
]
case0:
br label %end
case1:
br label %end
case2:
br label %end
case3:
br label %end
case4:
br label %end
default:
unreachable
end:
%idx = phi i32 [ 2, %case0 ], [ 2, %case1 ], [ 2, %case2 ], [ 2, %case3 ], [ 2, %case4 ]
ret i32 %idx
}
define i32 @single_value_withdefault(i32 %x) {
; OPTNOLUT-LABEL: define i32 @single_value_withdefault(
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
; OPTNOLUT-NEXT: [[ENTRY:.*:]]
; OPTNOLUT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X]], 5
; OPTNOLUT-NEXT: [[DOT:%.*]] = select i1 [[TMP0]], i32 2, i32 3
; OPTNOLUT-NEXT: ret i32 [[DOT]]
;
; TTINOLUT-LABEL: define i32 @single_value_withdefault(
; TTINOLUT-SAME: i32 [[X:%.*]]) {
; TTINOLUT-NEXT: [[ENTRY:.*:]]
; TTINOLUT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X]], 5
; TTINOLUT-NEXT: [[IDX:%.*]] = select i1 [[TMP0]], i32 2, i32 3
; TTINOLUT-NEXT: ret i32 [[IDX]]
;
entry:
switch i32 %x, label %default [
i32 0, label %case0
i32 1, label %case1
i32 2, label %case2
i32 3, label %case3
i32 4, label %case4
]
case0:
br label %end
case1:
br label %end
case2:
br label %end
case3:
br label %end
case4:
br label %end
default:
br label %end
end:
%idx = phi i32 [ 2, %case0 ], [ 2, %case1 ], [ 2, %case2 ], [ 2, %case3 ], [ 2, %case4 ], [ 3, %default ]
ret i32 %idx
}
define i32 @single_value_no_jump_tables(i32 %x) "no-jump-tables"="true" {
; OPTNOLUT-LABEL: define i32 @single_value_no_jump_tables(
; OPTNOLUT-SAME: i32 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
; OPTNOLUT-NEXT: [[ENTRY:.*:]]
; OPTNOLUT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X]], 5
; OPTNOLUT-NEXT: [[IDX:%.*]] = select i1 [[TMP0]], i32 2, i32 3
; OPTNOLUT-NEXT: ret i32 [[IDX]]
;
; TTINOLUT-LABEL: define i32 @single_value_no_jump_tables(
; TTINOLUT-SAME: i32 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
; TTINOLUT-NEXT: [[ENTRY:.*:]]
; TTINOLUT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X]], 5
; TTINOLUT-NEXT: [[IDX:%.*]] = select i1 [[TMP0]], i32 2, i32 3
; TTINOLUT-NEXT: ret i32 [[IDX]]
;
entry:
switch i32 %x, label %default [
i32 0, label %case0
i32 1, label %case1
i32 2, label %case2
i32 3, label %case3
i32 4, label %case4
]
case0:
br label %end
case1:
br label %end
case2:
br label %end
case3:
br label %end
case4:
br label %end
default:
br label %end
end:
%idx = phi i32 [ 2, %case0 ], [ 2, %case1 ], [ 2, %case2 ], [ 2, %case3 ], [ 2, %case4 ], [ 3, %default ]
ret i32 %idx
}
define i1 @single_value_with_mask(i32 %x) {
; OPTNOLUT-LABEL: define i1 @single_value_with_mask(
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
; OPTNOLUT-NEXT: [[ENTRY:.*]]:
; OPTNOLUT-NEXT: switch i32 [[X]], label %[[DEFAULT:.*]] [
; OPTNOLUT-NEXT: i32 18, label %[[END:.*]]
; OPTNOLUT-NEXT: i32 21, label %[[END]]
; OPTNOLUT-NEXT: i32 48, label %[[END]]
; OPTNOLUT-NEXT: i32 16, label %[[END]]
; OPTNOLUT-NEXT: i32 80, label %[[END]]
; OPTNOLUT-NEXT: ]
; OPTNOLUT: [[DEFAULT]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[END]]:
; OPTNOLUT-NEXT: [[RES:%.*]] = phi i1 [ false, %[[ENTRY]] ], [ false, %[[ENTRY]] ], [ false, %[[ENTRY]] ], [ false, %[[ENTRY]] ], [ true, %[[DEFAULT]] ], [ false, %[[ENTRY]] ]
; OPTNOLUT-NEXT: ret i1 [[RES]]
;
; TTINOLUT-LABEL: define i1 @single_value_with_mask(
; TTINOLUT-SAME: i32 [[X:%.*]]) {
; TTINOLUT-NEXT: [[ENTRY:.*]]:
; TTINOLUT-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[X]], 16
; TTINOLUT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 33
; TTINOLUT-NEXT: [[SWITCH_MASKINDEX:%.*]] = zext i32 [[SWITCH_TABLEIDX]] to i64
; TTINOLUT-NEXT: [[SWITCH_SHIFTED:%.*]] = lshr i64 4294967333, [[SWITCH_MASKINDEX]]
; TTINOLUT-NEXT: [[SWITCH_LOBIT:%.*]] = trunc i64 [[SWITCH_SHIFTED]] to i1
; TTINOLUT-NEXT: [[OR_COND:%.*]] = select i1 [[TMP0]], i1 [[SWITCH_LOBIT]], i1 false
; TTINOLUT-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], 80
; TTINOLUT-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i1 false, i1 true
; TTINOLUT-NEXT: [[RES:%.*]] = select i1 [[OR_COND]], i1 false, i1 [[SEL]]
; TTINOLUT-NEXT: ret i1 [[RES]]
;
entry:
switch i32 %x, label %default [
i32 18, label %end
i32 21, label %end
i32 48, label %end
i32 16, label %end
]
default:
%cmp = icmp eq i32 %x, 80
%sel = select i1 %cmp, i1 false, i1 true
br label %end
end:
%res = phi i1 [ false, %entry ], [ false, %entry ], [ false, %entry ], [ false, %entry ], [ %sel, %default ]
ret i1 %res
}
define i32 @lookup_table(i32 %x) {
; OPTNOLUT-LABEL: define i32 @lookup_table(
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
; OPTNOLUT-NEXT: [[ENTRY:.*]]:
; OPTNOLUT-NEXT: switch i32 [[X]], label %[[END:.*]] [
; OPTNOLUT-NEXT: i32 0, label %[[CASE0:.*]]
; OPTNOLUT-NEXT: i32 1, label %[[CASE1:.*]]
; OPTNOLUT-NEXT: i32 2, label %[[CASE2:.*]]
; OPTNOLUT-NEXT: i32 3, label %[[CASE3:.*]]
; OPTNOLUT-NEXT: ]
; OPTNOLUT: [[CASE0]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[CASE1]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[CASE2]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[CASE3]]:
; OPTNOLUT-NEXT: br label %[[END]]
; OPTNOLUT: [[END]]:
; OPTNOLUT-NEXT: [[IDX:%.*]] = phi i32 [ 13, %[[CASE0]] ], [ 3, %[[CASE1]] ], [ 11, %[[CASE2]] ], [ 8, %[[CASE3]] ], [ 24, %[[ENTRY]] ]
; OPTNOLUT-NEXT: ret i32 [[IDX]]
;
; TTINOLUT-LABEL: define i32 @lookup_table(
; TTINOLUT-SAME: i32 [[X:%.*]]) {
; TTINOLUT-NEXT: [[ENTRY:.*]]:
; TTINOLUT-NEXT: switch i32 [[X]], label %[[END:.*]] [
; TTINOLUT-NEXT: i32 0, label %[[CASE0:.*]]
; TTINOLUT-NEXT: i32 1, label %[[CASE1:.*]]
; TTINOLUT-NEXT: i32 2, label %[[CASE2:.*]]
; TTINOLUT-NEXT: i32 3, label %[[CASE3:.*]]
; TTINOLUT-NEXT: ]
; TTINOLUT: [[CASE0]]:
; TTINOLUT-NEXT: br label %[[END]]
; TTINOLUT: [[CASE1]]:
; TTINOLUT-NEXT: br label %[[END]]
; TTINOLUT: [[CASE2]]:
; TTINOLUT-NEXT: br label %[[END]]
; TTINOLUT: [[CASE3]]:
; TTINOLUT-NEXT: br label %[[END]]
; TTINOLUT: [[END]]:
; TTINOLUT-NEXT: [[IDX:%.*]] = phi i32 [ 13, %[[CASE0]] ], [ 3, %[[CASE1]] ], [ 11, %[[CASE2]] ], [ 8, %[[CASE3]] ], [ 24, %[[ENTRY]] ]
; TTINOLUT-NEXT: ret i32 [[IDX]]
;
entry:
switch i32 %x, label %end [
i32 0, label %case0
i32 1, label %case1
i32 2, label %case2
i32 3, label %case3
]
case0:
br label %end
case1:
br label %end
case2:
br label %end
case3:
br label %end
end:
%idx = phi i32 [ 13, %case0 ], [ 3, %case1 ], [ 11, %case2 ], [ 8, %case3 ], [ 24, %entry ]
ret i32 %idx
}