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
517 lines
16 KiB
LLVM
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
|
|
}
|