blob: 9d78b97c204a82358f509e3621094dc0b9b403b6 [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
; int foo1_with_default(int a) {
; switch(a) {
; case 10:
; return 10;
; case 20:
; return 2;
; }
; return 4;
; }
define i32 @foo1_with_default(i32 %a) !prof !0 {
; CHECK-LABEL: @foo1_with_default(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[A:%.*]], 20
; CHECK-NEXT: [[SWITCH_SELECT:%.*]] = select i1 [[SWITCH_SELECTCMP]], i32 2, i32 4, !prof [[PROF1:![0-9]+]]
; CHECK-NEXT: [[SWITCH_SELECTCMP1:%.*]] = icmp eq i32 [[A]], 10
; CHECK-NEXT: [[SWITCH_SELECT2:%.*]] = select i1 [[SWITCH_SELECTCMP1]], i32 10, i32 [[SWITCH_SELECT]], !prof [[PROF2:![0-9]+]]
; CHECK-NEXT: ret i32 [[SWITCH_SELECT2]]
;
entry:
switch i32 %a, label %sw.epilog [
i32 10, label %sw.bb
i32 20, label %sw.bb1
], !prof !1
sw.bb:
br label %return
sw.bb1:
br label %return
sw.epilog:
br label %return
return:
%retval.0 = phi i32 [ 4, %sw.epilog ], [ 2, %sw.bb1 ], [ 10, %sw.bb ]
ret i32 %retval.0
}
; Same as above, but both cases have the same value.
define i32 @same_value(i32 %a) !prof !0 {
; CHECK-LABEL: @same_value(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SWITCH_SELECTCMP_CASE1:%.*]] = icmp eq i32 [[A:%.*]], 10
; CHECK-NEXT: [[SWITCH_SELECTCMP_CASE2:%.*]] = icmp eq i32 [[A]], 20
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = or i1 [[SWITCH_SELECTCMP_CASE1]], [[SWITCH_SELECTCMP_CASE2]]
; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[SWITCH_SELECTCMP]], i32 10, i32 4, !prof [[PROF3:![0-9]+]]
; CHECK-NEXT: ret i32 [[TMP0]]
;
entry:
switch i32 %a, label %sw.epilog [
i32 10, label %sw.bb
i32 20, label %sw.bb
], !prof !1
sw.bb:
br label %return
sw.epilog:
br label %return
return:
%retval.0 = phi i32 [ 4, %sw.epilog ], [ 10, %sw.bb ]
ret i32 %retval.0
}
define i1 @switch_to_select_same2_case_results_different_default(i8 %0) !prof !0 {
; CHECK-LABEL: @switch_to_select_same2_case_results_different_default(
; CHECK-NEXT: [[SWITCH_AND:%.*]] = and i8 [[TMP0:%.*]], -5
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i8 [[SWITCH_AND]], 0
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false, !prof [[PROF3]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
switch i8 %0, label %2 [
i8 4, label %3
i8 0, label %3
], !prof !1
2:
br label %3
3:
%4 = phi i1 [ false, %2 ], [ true, %1 ], [ true, %1 ]
ret i1 %4
}
define i1 @switch_to_select_same2_case_results_different_default_and_positive_offset_for_case(i8 %0) !prof !0 {
; CHECK-LABEL: @switch_to_select_same2_case_results_different_default_and_positive_offset_for_case(
; CHECK-NEXT: [[TMP2:%.*]] = sub i8 [[TMP0:%.*]], 43
; CHECK-NEXT: [[SWITCH_AND:%.*]] = and i8 [[TMP2]], -3
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i8 [[SWITCH_AND]], 0
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false, !prof [[PROF3]]
; CHECK-NEXT: ret i1 [[TMP3]]
;
switch i8 %0, label %2 [
i8 43, label %3
i8 45, label %3
], !prof !1
2:
br label %3
3:
%4 = phi i1 [ false, %2 ], [ true, %1 ], [ true, %1 ]
ret i1 %4
}
define i8 @switch_to_select_same2_case_results_different_default_and_negative_offset_for_case(i32 %i) !prof !0 {
; CHECK-LABEL: @switch_to_select_same2_case_results_different_default_and_negative_offset_for_case(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = sub i32 [[I:%.*]], -5
; CHECK-NEXT: [[SWITCH_AND:%.*]] = and i32 [[TMP0]], -3
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[SWITCH_AND]], 0
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[SWITCH_SELECTCMP]], i8 3, i8 42, !prof [[PROF3]]
; CHECK-NEXT: ret i8 [[TMP1]]
;
entry:
switch i32 %i, label %default [
i32 -3, label %end
i32 -5, label %end
], !prof !1
default:
br label %end
end:
%t0 = phi i8 [ 42, %default ], [ 3, %entry ], [ 3, %entry ]
ret i8 %t0
}
define i1 @switch_to_select_same4_case_results_different_default(i32 %i) !prof !0 {
; CHECK-LABEL: @switch_to_select_same4_case_results_different_default(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SWITCH_AND:%.*]] = and i32 [[I:%.*]], -7
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[SWITCH_AND]], 0
; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false, !prof [[PROF4:![0-9]+]]
; CHECK-NEXT: ret i1 [[TMP0]]
;
entry:
switch i32 %i, label %lor.rhs [
i32 0, label %lor.end
i32 2, label %lor.end
i32 4, label %lor.end
i32 6, label %lor.end
], !prof !2
lor.rhs:
br label %lor.end
lor.end:
%0 = phi i1 [ true, %entry ], [ false, %lor.rhs ], [ true, %entry ], [ true, %entry ], [ true, %entry ]
ret i1 %0
}
define i1 @switch_to_select_same4_case_results_different_default_alt_bitmask(i32 %i) !prof !0 {
; CHECK-LABEL: @switch_to_select_same4_case_results_different_default_alt_bitmask(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SWITCH_AND:%.*]] = and i32 [[I:%.*]], -11
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[SWITCH_AND]], 0
; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false, !prof [[PROF4]]
; CHECK-NEXT: ret i1 [[TMP0]]
;
entry:
switch i32 %i, label %lor.rhs [
i32 0, label %lor.end
i32 2, label %lor.end
i32 8, label %lor.end
i32 10, label %lor.end
], !prof !2
lor.rhs:
br label %lor.end
lor.end:
%0 = phi i1 [ true, %entry ], [ false, %lor.rhs ], [ true, %entry ], [ true, %entry ], [ true, %entry ]
ret i1 %0
}
define i1 @switch_to_select_same4_case_results_different_default_positive_offset(i32 %i) !prof !0 {
; CHECK-LABEL: @switch_to_select_same4_case_results_different_default_positive_offset(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = sub i32 [[I:%.*]], 2
; CHECK-NEXT: [[SWITCH_AND:%.*]] = and i32 [[TMP0]], -11
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[SWITCH_AND]], 0
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false, !prof [[PROF4]]
; CHECK-NEXT: ret i1 [[TMP1]]
;
entry:
switch i32 %i, label %lor.rhs [
i32 2, label %lor.end
i32 4, label %lor.end
i32 10, label %lor.end
i32 12, label %lor.end
], !prof !2
lor.rhs:
br label %lor.end
lor.end:
%0 = phi i1 [ true, %entry ], [ false, %lor.rhs ], [ true, %entry ], [ true, %entry ], [ true, %entry ]
ret i1 %0
}
define i1 @switch_to_select_invalid_mask(i32 %i) !prof !0 {
; CHECK-LABEL: @switch_to_select_invalid_mask(
; CHECK-NEXT: entry:
; CHECK-NEXT: switch i32 [[I:%.*]], label [[LOR_RHS:%.*]] [
; CHECK-NEXT: i32 1, label [[LOR_END:%.*]]
; CHECK-NEXT: i32 4, label [[LOR_END]]
; CHECK-NEXT: i32 10, label [[LOR_END]]
; CHECK-NEXT: i32 12, label [[LOR_END]]
; CHECK-NEXT: ], !prof [[PROF5:![0-9]+]]
; CHECK: lor.rhs:
; CHECK-NEXT: br label [[LOR_END]]
; CHECK: lor.end:
; CHECK-NEXT: [[TMP0:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ]
; CHECK-NEXT: ret i1 [[TMP0]]
;
entry:
switch i32 %i, label %lor.rhs [
i32 1, label %lor.end
i32 4, label %lor.end
i32 10, label %lor.end
i32 12, label %lor.end
], !prof !2
lor.rhs:
br label %lor.end
lor.end:
%0 = phi i1 [ true, %entry ], [ false, %lor.rhs ], [ true, %entry ], [ true, %entry ], [ true, %entry ]
ret i1 %0
}
define i1 @switch_to_select_nonpow2_cases(i32 %i) !prof !0 {
; CHECK-LABEL: @switch_to_select_nonpow2_cases(
; CHECK-NEXT: entry:
; CHECK-NEXT: switch i32 [[I:%.*]], label [[LOR_RHS:%.*]] [
; CHECK-NEXT: i32 0, label [[LOR_END:%.*]]
; CHECK-NEXT: i32 2, label [[LOR_END]]
; CHECK-NEXT: i32 4, label [[LOR_END]]
; CHECK-NEXT: ], !prof [[PROF6:![0-9]+]]
; CHECK: lor.rhs:
; CHECK-NEXT: br label [[LOR_END]]
; CHECK: lor.end:
; CHECK-NEXT: [[TMP0:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ]
; CHECK-NEXT: ret i1 [[TMP0]]
;
entry:
switch i32 %i, label %lor.rhs [
i32 0, label %lor.end
i32 2, label %lor.end
i32 4, label %lor.end
], !prof !3
lor.rhs:
br label %lor.end
lor.end:
%0 = phi i1 [ true, %entry ], [ false, %lor.rhs ], [ true, %entry ], [ true, %entry ]
ret i1 %0
}
; TODO: we can produce the optimal code when there is no default also
define i8 @switch_to_select_two_case_results_no_default(i32 %i) !prof !0 {
; CHECK-LABEL: @switch_to_select_two_case_results_no_default(
; CHECK-NEXT: entry:
; CHECK-NEXT: switch i32 [[I:%.*]], label [[DEFAULT:%.*]] [
; CHECK-NEXT: i32 0, label [[END:%.*]]
; CHECK-NEXT: i32 2, label [[END]]
; CHECK-NEXT: i32 4, label [[CASE3:%.*]]
; CHECK-NEXT: i32 6, label [[CASE3]]
; CHECK-NEXT: ], !prof [[PROF5]]
; CHECK: case3:
; CHECK-NEXT: br label [[END]]
; CHECK: default:
; CHECK-NEXT: unreachable
; CHECK: end:
; CHECK-NEXT: [[T0:%.*]] = phi i8 [ 44, [[CASE3]] ], [ 42, [[ENTRY:%.*]] ], [ 42, [[ENTRY]] ]
; CHECK-NEXT: ret i8 [[T0]]
;
entry:
switch i32 %i, label %default [
i32 0, label %case1
i32 2, label %case2
i32 4, label %case3
i32 6, label %case4
], !prof !2
case1:
br label %end
case2:
br label %end
case3:
br label %end
case4:
br label %end
default:
unreachable
end:
%t0 = phi i8 [ 42, %case1 ], [ 42, %case2 ], [ 44, %case3 ], [ 44, %case4 ]
ret i8 %t0
}
define i1 @no_range(i8 %f) !prof !0 {
; CHECK-LABEL: @no_range(
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 60
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 60
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false, !prof [[PROF7:![0-9]+]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
switch i8 %f, label %bb1 [
i8 60, label %bb2
i8 61, label %bb2
i8 62, label %bb2
i8 63, label %bb2
i8 124, label %bb2
i8 188, label %bb2
i8 252, label %bb2
i8 189, label %bb2
i8 190, label %bb2
i8 191, label %bb2
i8 125, label %bb2
i8 126, label %bb2
i8 127, label %bb2
i8 253, label %bb2
i8 254, label %bb2
i8 255, label %bb2
], !prof !4
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
define i1 @negative_no_range(i8 %f) !prof !0 {
; CHECK-LABEL: @negative_no_range(
; CHECK-NEXT: switch i8 [[F:%.*]], label [[BB3:%.*]] [
; CHECK-NEXT: i8 52, label [[BB2:%.*]]
; CHECK-NEXT: i8 61, label [[BB2]]
; CHECK-NEXT: i8 62, label [[BB2]]
; CHECK-NEXT: i8 63, label [[BB2]]
; CHECK-NEXT: i8 124, label [[BB2]]
; CHECK-NEXT: i8 -68, label [[BB2]]
; CHECK-NEXT: i8 -4, label [[BB2]]
; CHECK-NEXT: i8 -67, label [[BB2]]
; CHECK-NEXT: i8 -66, label [[BB2]]
; CHECK-NEXT: i8 -65, label [[BB2]]
; CHECK-NEXT: i8 125, label [[BB2]]
; CHECK-NEXT: i8 126, label [[BB2]]
; CHECK-NEXT: i8 127, label [[BB2]]
; CHECK-NEXT: i8 -3, label [[BB2]]
; CHECK-NEXT: i8 -2, label [[BB2]]
; CHECK-NEXT: i8 -1, label [[BB2]]
; CHECK-NEXT: ], !prof [[PROF8:![0-9]+]]
; CHECK: bb2:
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ true, [[BB2]] ], [ false, [[TMP0:%.*]] ]
; CHECK-NEXT: ret i1 [[PHI]]
;
switch i8 %f, label %bb1 [
i8 52, label %bb2
i8 61, label %bb2
i8 62, label %bb2
i8 63, label %bb2
i8 124, label %bb2
i8 188, label %bb2
i8 252, label %bb2
i8 189, label %bb2
i8 190, label %bb2
i8 191, label %bb2
i8 125, label %bb2
i8 126, label %bb2
i8 127, label %bb2
i8 253, label %bb2
i8 254, label %bb2
i8 255, label %bb2
], !prof !4
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
; Using ranges.
define i1 @range0to4odd(i8 range(i8 0, 4) %f) !prof !0 {
; CHECK-LABEL: @range0to4odd(
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 1
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 1
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false, !prof [[PROF3]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
switch i8 %f, label %bb1 [
i8 1, label %bb2
i8 3, label %bb2
], !prof !1
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
define i1 @range1to4odd(i8 range(i8 1, 4) %f) !prof !0 {
; CHECK-LABEL: @range1to4odd(
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 1
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 1
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false, !prof [[PROF3]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
switch i8 %f, label %bb1 [
i8 1, label %bb2
i8 3, label %bb2
], !prof !1
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
define i1 @range0to8odd(i8 range(i8 0, 8) %f) !prof !0 {
; CHECK-LABEL: @range0to8odd(
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 1
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 1
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false, !prof [[PROF4]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
switch i8 %f, label %bb1 [
i8 1, label %bb2
i8 3, label %bb2
i8 5, label %bb2
i8 7, label %bb2
], !prof !2
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
define i1 @range0to8most_significant_bit(i8 range(i8 0, 8) %f) !prof !0 {
; CHECK-LABEL: @range0to8most_significant_bit(
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 4
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 4
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false, !prof [[PROF4]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
switch i8 %f, label %bb1 [
i8 4, label %bb2
i8 5, label %bb2
i8 6, label %bb2
i8 7, label %bb2
], !prof !2
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
define i1 @range0to15_middle_two_bits(i8 range(i8 0, 16) %f) !prof !0 {
; CHECK-LABEL: @range0to15_middle_two_bits(
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 6
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 6
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false, !prof [[PROF4]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
switch i8 %f, label %bb1 [
i8 6, label %bb2
i8 7, label %bb2
i8 14, label %bb2
i8 15, label %bb2
], !prof !2
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
define i1 @negative_range0to15(i8 range(i8 0, 16) %f) !prof !0 {
; CHECK-LABEL: @negative_range0to15(
; CHECK-NEXT: switch i8 [[F:%.*]], label [[BB3:%.*]] [
; CHECK-NEXT: i8 6, label [[BB2:%.*]]
; CHECK-NEXT: i8 7, label [[BB2]]
; CHECK-NEXT: i8 14, label [[BB2]]
; CHECK-NEXT: ], !prof [[PROF6]]
; CHECK: bb2:
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ true, [[BB2]] ], [ false, [[TMP0:%.*]] ]
; CHECK-NEXT: ret i1 [[PHI]]
;
switch i8 %f, label %bb1 [
i8 6, label %bb2
i8 7, label %bb2
i8 14, label %bb2
], !prof !3
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
define i1 @negative_range0to15_pow_2(i8 range(i8 0, 16) %f) !prof !0 {
; CHECK-LABEL: @negative_range0to15_pow_2(
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[TMP0:%.*]] = sub i8 [[F:%.*]], 6
; CHECK-NEXT: [[SWITCH_AND:%.*]] = and i8 [[TMP0]], -2
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i8 [[SWITCH_AND]], 0
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false, !prof [[PROF3]]
; CHECK-NEXT: ret i1 [[TMP1]]
;
switch i8 %f, label %bb1 [
i8 6, label %bb2
i8 7, label %bb2
], !prof !1
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
define i1 @negative_range0to5even(i8 range(i8 0, 5) %f) !prof !0 {
; CHECK-LABEL: @negative_range0to5even(
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[TMP0:%.*]] = sub i8 [[F:%.*]], 2
; CHECK-NEXT: [[SWITCH_AND:%.*]] = and i8 [[TMP0]], -3
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i8 [[SWITCH_AND]], 0
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false, !prof [[PROF3]]
; CHECK-NEXT: ret i1 [[TMP1]]
;
switch i8 %f, label %bb1 [
i8 2, label %bb2
i8 4, label %bb2
], !prof !1
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
define i1 @range0to15_corner_case(i8 range(i8 0, 16) %f) !prof !0 {
; CHECK-LABEL: @range0to15_corner_case(
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[F:%.*]], 15
; CHECK-NEXT: [[DOT:%.*]] = select i1 [[COND]], i1 true, i1 false, !prof [[PROF9:![0-9]+]]
; CHECK-NEXT: ret i1 [[DOT]]
;
switch i8 %f, label %bb1 [
i8 15, label %bb2
], !prof !5
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
define i1 @negative_range0to15_corner_case(i8 range(i8 0, 16) %f) !prof !0 {
; CHECK-LABEL: @negative_range0to15_corner_case(
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[SWITCH_SELECTCMP_CASE1:%.*]] = icmp eq i8 [[F:%.*]], 15
; CHECK-NEXT: [[SWITCH_SELECTCMP_CASE2:%.*]] = icmp eq i8 [[F]], 8
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = or i1 [[SWITCH_SELECTCMP_CASE1]], [[SWITCH_SELECTCMP_CASE2]]
; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false, !prof [[PROF3]]
; CHECK-NEXT: ret i1 [[TMP0]]
;
switch i8 %f, label %bb1 [
i8 15, label %bb2
i8 8, label %bb2
], !prof !1
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
; Out of range scenarios. Check if the cases, that have a value out of range
; are eliminated and the optimization is performed.
define i1 @range0to15_out_of_range_non_prime(i8 range(i8 0, 16) %f) !prof !0 {
; CHECK-LABEL: @range0to15_out_of_range_non_prime(
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 6
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 6
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false, !prof [[PROF4]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
switch i8 %f, label %bb1 [
i8 6, label %bb2
i8 7, label %bb2
i8 14, label %bb2
i8 15, label %bb2
i8 22, label %bb2
], !prof !6
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
define i1 @range0to15_out_of_range_non_prime_more(i8 range(i8 0, 16) %f) !prof !0 {
; CHECK-LABEL: @range0to15_out_of_range_non_prime_more(
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 6
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 6
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false, !prof [[PROF4]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
switch i8 %f, label %bb1 [
i8 6, label %bb2
i8 7, label %bb2
i8 14, label %bb2
i8 15, label %bb2
i8 22, label %bb2
i8 23, label %bb2
], !prof !7
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
define i1 @negative_range0to15_out_of_range_non_prime(i8 range(i8 0, 16) %f) !prof !0 {
; CHECK-LABEL: @negative_range0to15_out_of_range_non_prime(
; CHECK-NEXT: switch i8 [[F:%.*]], label [[BB3:%.*]] [
; CHECK-NEXT: i8 6, label [[BB2:%.*]]
; CHECK-NEXT: i8 14, label [[BB2]]
; CHECK-NEXT: i8 15, label [[BB2]]
; CHECK-NEXT: ], !prof [[PROF6]]
; CHECK: bb2:
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ true, [[BB2]] ], [ false, [[TMP0:%.*]] ]
; CHECK-NEXT: ret i1 [[PHI]]
;
switch i8 %f, label %bb1 [
i8 6, label %bb2
i8 14, label %bb2
i8 15, label %bb2
i8 23, label %bb2
], !prof !2
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
define i1 @negative_range0to15_out_of_range(i8 range(i8 0, 16) %f) !prof !0 {
; CHECK-LABEL: @negative_range0to15_out_of_range(
; CHECK-NEXT: switch i8 [[F:%.*]], label [[BB3:%.*]] [
; CHECK-NEXT: i8 6, label [[BB2:%.*]]
; CHECK-NEXT: i8 7, label [[BB2]]
; CHECK-NEXT: i8 14, label [[BB2]]
; CHECK-NEXT: ], !prof [[PROF6]]
; CHECK: bb2:
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ true, [[BB2]] ], [ false, [[TMP0:%.*]] ]
; CHECK-NEXT: ret i1 [[PHI]]
;
switch i8 %f, label %bb1 [
i8 6, label %bb2
i8 7, label %bb2
i8 14, label %bb2
i8 -106, label %bb2
], !prof !2
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
define i1 @negative_range0to15_all_out_of_range(i8 range(i8 0, 16) %f) !prof !0 {
; CHECK-LABEL: @negative_range0to15_all_out_of_range(
; CHECK-NEXT: bb1:
; CHECK-NEXT: ret i1 false
;
switch i8 %f, label %bb1 [
i8 22, label %bb2
i8 23, label %bb2
i8 30, label %bb2
i8 31, label %bb2
], !prof !2
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %phi
}
define i32 @negative_constfold_select() {
; CHECK-LABEL: @negative_constfold_select(
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 poison
;
entry:
switch i32 poison, label %default [
i32 0, label %bb
i32 2, label %bb
]
bb:
br label %default
default:
%ret = phi i32 [ poison, %entry ], [ poison, %bb ]
ret i32 %ret
}
!0 = !{!"function_entry_count", i64 1000}
!1 = !{!"branch_weights", i32 3, i32 5, i32 7}
!2 = !{!"branch_weights", i32 3, i32 5, i32 7, i32 11, i32 13}
!3 = !{!"branch_weights", i32 3, i32 5, i32 7, i32 11}
!4 = !{!"branch_weights", i32 3, i32 5, i32 7, i32 11, i32 13, i32 17, i32 19, i32 23, i32 29, i32 31, i32 37, i32 41, i32 43, i32 47, i32 53, i32 59, i32 61}
!5 = !{!"branch_weights", i32 3, i32 5}
!6 = !{!"branch_weights", i32 3, i32 5, i32 7, i32 11, i32 13, i32 17}
!7 = !{!"branch_weights", i32 3, i32 5, i32 7, i32 11, i32 13, i32 17, i32 19}
;.
; CHECK: [[META0:![0-9]+]] = !{!"function_entry_count", i64 1000}
; CHECK: [[PROF1]] = !{!"branch_weights", i32 7, i32 8}
; CHECK: [[PROF2]] = !{!"branch_weights", i32 5, i32 10}
; CHECK: [[PROF3]] = !{!"branch_weights", i32 12, i32 3}
; CHECK: [[PROF4]] = !{!"branch_weights", i32 36, i32 3}
; CHECK: [[PROF5]] = !{!"branch_weights", i32 3, i32 5, i32 7, i32 11, i32 13}
; CHECK: [[PROF6]] = !{!"branch_weights", i32 3, i32 5, i32 7, i32 11}
; CHECK: [[PROF7]] = !{!"branch_weights", i32 496, i32 3}
; CHECK: [[PROF8]] = !{!"branch_weights", i32 3, i32 5, i32 7, i32 11, i32 13, i32 17, i32 19, i32 23, i32 29, i32 31, i32 37, i32 41, i32 43, i32 47, i32 53, i32 59, i32 61}
; CHECK: [[PROF9]] = !{!"branch_weights", i32 5, i32 3}
;.