CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
428 lines
10 KiB
LLVM
428 lines
10 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -switch-range-to-icmp -S | FileCheck %s
|
|
|
|
declare i32 @f(i32)
|
|
|
|
define i32 @basic(i32 %x) {
|
|
; CHECK-LABEL: @basic(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], -5
|
|
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[X_OFF]], 3
|
|
; CHECK-NEXT: br i1 [[SWITCH]], label [[A:%.*]], label [[DEFAULT:%.*]]
|
|
; CHECK: common.ret:
|
|
; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[TMP0:%.*]], [[DEFAULT]] ], [ [[TMP1:%.*]], [[A]] ]
|
|
; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
|
|
; CHECK: default:
|
|
; CHECK-NEXT: [[TMP0]] = call i32 @f(i32 0)
|
|
; CHECK-NEXT: br label [[COMMON_RET:%.*]]
|
|
; CHECK: a:
|
|
; CHECK-NEXT: [[TMP1]] = call i32 @f(i32 1)
|
|
; CHECK-NEXT: br label [[COMMON_RET]]
|
|
;
|
|
|
|
entry:
|
|
switch i32 %x, label %default [
|
|
i32 5, label %a
|
|
i32 6, label %a
|
|
i32 7, label %a
|
|
]
|
|
default:
|
|
%0 = call i32 @f(i32 0)
|
|
ret i32 %0
|
|
a:
|
|
%1 = call i32 @f(i32 1)
|
|
ret i32 %1
|
|
}
|
|
|
|
|
|
define i32 @unreachable(i32 %x) {
|
|
; CHECK-LABEL: @unreachable(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], -5
|
|
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[X_OFF]], 3
|
|
; CHECK-NEXT: br i1 [[SWITCH]], label [[A:%.*]], label [[B:%.*]]
|
|
; CHECK: common.ret:
|
|
; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[TMP0:%.*]], [[A]] ], [ [[TMP1:%.*]], [[B]] ]
|
|
; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
|
|
; CHECK: a:
|
|
; CHECK-NEXT: [[TMP0]] = call i32 @f(i32 0)
|
|
; CHECK-NEXT: br label [[COMMON_RET:%.*]]
|
|
; CHECK: b:
|
|
; CHECK-NEXT: [[TMP1]] = call i32 @f(i32 1)
|
|
; CHECK-NEXT: br label [[COMMON_RET]]
|
|
;
|
|
|
|
entry:
|
|
switch i32 %x, label %unreachable [
|
|
i32 5, label %a
|
|
i32 6, label %a
|
|
i32 7, label %a
|
|
i32 10, label %b
|
|
i32 20, label %b
|
|
i32 30, label %b
|
|
i32 40, label %b
|
|
]
|
|
unreachable:
|
|
unreachable
|
|
a:
|
|
%0 = call i32 @f(i32 0)
|
|
ret i32 %0
|
|
b:
|
|
%1 = call i32 @f(i32 1)
|
|
ret i32 %1
|
|
}
|
|
|
|
|
|
define i32 @unreachable2(i32 %x) {
|
|
; CHECK-LABEL: @unreachable2(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], -5
|
|
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[X_OFF]], 3
|
|
; CHECK-NEXT: br i1 [[SWITCH]], label [[A:%.*]], label [[B:%.*]]
|
|
; CHECK: common.ret:
|
|
; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[TMP0:%.*]], [[A]] ], [ [[TMP1:%.*]], [[B]] ]
|
|
; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
|
|
; CHECK: a:
|
|
; CHECK-NEXT: [[TMP0]] = call i32 @f(i32 0)
|
|
; CHECK-NEXT: br label [[COMMON_RET:%.*]]
|
|
; CHECK: b:
|
|
; CHECK-NEXT: [[TMP1]] = call i32 @f(i32 1)
|
|
; CHECK-NEXT: br label [[COMMON_RET]]
|
|
;
|
|
|
|
entry:
|
|
; Note: folding the most popular case destination into the default
|
|
; would prevent switch-to-icmp here.
|
|
switch i32 %x, label %unreachable [
|
|
i32 5, label %a
|
|
i32 6, label %a
|
|
i32 7, label %a
|
|
i32 10, label %b
|
|
i32 20, label %b
|
|
]
|
|
unreachable:
|
|
unreachable
|
|
a:
|
|
%0 = call i32 @f(i32 0)
|
|
ret i32 %0
|
|
b:
|
|
%1 = call i32 @f(i32 1)
|
|
ret i32 %1
|
|
}
|
|
|
|
; This would crash because we did not clean up the
|
|
; default block of the switch before removing the switch.
|
|
|
|
define void @PR42737(ptr %a, i1 %c) {
|
|
; CHECK-LABEL: @PR42737(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: unreachable
|
|
;
|
|
entry:
|
|
br i1 %c, label %switch, label %else
|
|
|
|
else:
|
|
store i32 2, ptr %a
|
|
br label %switch
|
|
|
|
switch:
|
|
%cleanup.dest1 = phi i32 [ 0, %else ], [ 3, %entry ]
|
|
switch i32 %cleanup.dest1, label %unreach1 [
|
|
i32 0, label %cleanup1
|
|
i32 3, label %cleanup2
|
|
]
|
|
|
|
cleanup1:
|
|
br label %unreach2
|
|
|
|
cleanup2:
|
|
br label %unreach2
|
|
|
|
unreach1:
|
|
%phi2 = phi i32 [ %cleanup.dest1, %switch ]
|
|
unreachable
|
|
|
|
unreach2:
|
|
unreachable
|
|
}
|
|
|
|
|
|
define void @pr53208_single_reachable_dest(i8 %sw, ptr %p0) {
|
|
; CHECK-LABEL: @pr53208_single_reachable_dest(
|
|
; CHECK-NEXT: exit:
|
|
; CHECK-NEXT: call void @bar(ptr [[P0:%.*]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
switch i8 %sw, label %group3 [
|
|
i8 0, label %group1
|
|
i8 1, label %group1
|
|
i8 2, label %group1
|
|
i8 3, label %group1
|
|
i8 11, label %group1
|
|
i8 12, label %group1
|
|
i8 13, label %group1
|
|
i8 7, label %group1
|
|
i8 17, label %group1
|
|
i8 14, label %group1
|
|
i8 15, label %group1
|
|
i8 4, label %group2
|
|
i8 5, label %group2
|
|
i8 6, label %group2
|
|
i8 8, label %group2
|
|
i8 9, label %group2
|
|
i8 10, label %group2
|
|
]
|
|
|
|
group1:
|
|
br label %exit
|
|
|
|
group2:
|
|
br label %exit
|
|
|
|
group3:
|
|
br label %exit
|
|
|
|
exit:
|
|
%phi = phi ptr [ null, %group3 ], [ %p0, %group2 ], [ null, %group1 ]
|
|
call void @bar(ptr %phi)
|
|
ret void
|
|
}
|
|
|
|
define i32 @wrapping_known_range(i8 range(i8 0, 6) %arg) {
|
|
; CHECK-LABEL: @wrapping_known_range(
|
|
; CHECK-NEXT: [[ARG_OFF:%.*]] = add i8 [[ARG:%.*]], -1
|
|
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i8 [[ARG_OFF]], 3
|
|
; CHECK-NEXT: br i1 [[SWITCH]], label [[ELSE:%.*]], label [[IF:%.*]]
|
|
; CHECK: common.ret:
|
|
; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[I0:%.*]], [[IF]] ], [ [[I1:%.*]], [[ELSE]] ]
|
|
; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
|
|
; CHECK: if:
|
|
; CHECK-NEXT: [[I0]] = call i32 @f(i32 0)
|
|
; CHECK-NEXT: br label [[COMMON_RET:%.*]]
|
|
; CHECK: else:
|
|
; CHECK-NEXT: [[I1]] = call i32 @f(i32 1)
|
|
; CHECK-NEXT: br label [[COMMON_RET]]
|
|
;
|
|
switch i8 %arg, label %else [
|
|
i8 0, label %if
|
|
i8 4, label %if
|
|
i8 5, label %if
|
|
]
|
|
|
|
if:
|
|
%i0 = call i32 @f(i32 0)
|
|
ret i32 %i0
|
|
|
|
else:
|
|
%i1 = call i32 @f(i32 1)
|
|
ret i32 %i1
|
|
}
|
|
|
|
define i32 @wrapping_known_range_2(i8 range(i8 0, 6) %arg) {
|
|
; CHECK-LABEL: @wrapping_known_range_2(
|
|
; CHECK-NEXT: [[SWITCH:%.*]] = icmp eq i8 [[ARG:%.*]], 1
|
|
; CHECK-NEXT: br i1 [[SWITCH]], label [[ELSE:%.*]], label [[IF:%.*]]
|
|
; CHECK: common.ret:
|
|
; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[I0:%.*]], [[IF]] ], [ [[I1:%.*]], [[ELSE]] ]
|
|
; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
|
|
; CHECK: if:
|
|
; CHECK-NEXT: [[I0]] = call i32 @f(i32 0)
|
|
; CHECK-NEXT: br label [[COMMON_RET:%.*]]
|
|
; CHECK: else:
|
|
; CHECK-NEXT: [[I1]] = call i32 @f(i32 1)
|
|
; CHECK-NEXT: br label [[COMMON_RET]]
|
|
;
|
|
switch i8 %arg, label %else [
|
|
i8 0, label %if
|
|
i8 2, label %if
|
|
i8 3, label %if
|
|
i8 4, label %if
|
|
i8 5, label %if
|
|
]
|
|
|
|
if:
|
|
%i0 = call i32 @f(i32 0)
|
|
ret i32 %i0
|
|
|
|
else:
|
|
%i1 = call i32 @f(i32 1)
|
|
ret i32 %i1
|
|
}
|
|
|
|
define i32 @wrapping_range(i8 %arg) {
|
|
; CHECK-LABEL: @wrapping_range(
|
|
; CHECK-NEXT: [[ARG_OFF:%.*]] = add i8 [[ARG:%.*]], -1
|
|
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i8 [[ARG_OFF]], -4
|
|
; CHECK-NEXT: br i1 [[SWITCH]], label [[ELSE:%.*]], label [[IF:%.*]]
|
|
; CHECK: common.ret:
|
|
; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[I0:%.*]], [[IF]] ], [ [[I1:%.*]], [[ELSE]] ]
|
|
; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
|
|
; CHECK: if:
|
|
; CHECK-NEXT: [[I0]] = call i32 @f(i32 0)
|
|
; CHECK-NEXT: br label [[COMMON_RET:%.*]]
|
|
; CHECK: else:
|
|
; CHECK-NEXT: [[I1]] = call i32 @f(i32 1)
|
|
; CHECK-NEXT: br label [[COMMON_RET]]
|
|
;
|
|
switch i8 %arg, label %else [
|
|
i8 0, label %if
|
|
i8 -3, label %if
|
|
i8 -2, label %if
|
|
i8 -1, label %if
|
|
]
|
|
|
|
if:
|
|
%i0 = call i32 @f(i32 0)
|
|
ret i32 %i0
|
|
|
|
else:
|
|
%i1 = call i32 @f(i32 1)
|
|
ret i32 %i1
|
|
}
|
|
|
|
define i8 @wrapping_range_phi(i8 %arg) {
|
|
; CHECK-LABEL: @wrapping_range_phi(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ARG_OFF:%.*]] = add i8 [[ARG:%.*]], -1
|
|
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i8 [[ARG_OFF]], -2
|
|
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i8 0, i8 1
|
|
; CHECK-NEXT: ret i8 [[SPEC_SELECT]]
|
|
;
|
|
entry:
|
|
switch i8 %arg, label %else [
|
|
i8 0, label %if
|
|
i8 -1, label %if
|
|
]
|
|
|
|
if:
|
|
%i = phi i8 [ 0, %else ], [ 1, %entry ], [ 1, %entry ]
|
|
ret i8 %i
|
|
|
|
else:
|
|
br label %if
|
|
}
|
|
|
|
define i32 @no_continuous_wrapping_range(i8 %arg) {
|
|
; CHECK-LABEL: @no_continuous_wrapping_range(
|
|
; CHECK-NEXT: switch i8 [[ARG:%.*]], label [[ELSE:%.*]] [
|
|
; CHECK-NEXT: i8 0, label [[IF:%.*]]
|
|
; CHECK-NEXT: i8 -3, label [[IF]]
|
|
; CHECK-NEXT: i8 -1, label [[IF]]
|
|
; CHECK-NEXT: ]
|
|
; CHECK: common.ret:
|
|
; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[I0:%.*]], [[IF]] ], [ [[I1:%.*]], [[ELSE]] ]
|
|
; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
|
|
; CHECK: if:
|
|
; CHECK-NEXT: [[I0]] = call i32 @f(i32 0)
|
|
; CHECK-NEXT: br label [[COMMON_RET:%.*]]
|
|
; CHECK: else:
|
|
; CHECK-NEXT: [[I1]] = call i32 @f(i32 1)
|
|
; CHECK-NEXT: br label [[COMMON_RET]]
|
|
;
|
|
switch i8 %arg, label %else [
|
|
i8 0, label %if
|
|
i8 -3, label %if
|
|
i8 -1, label %if
|
|
]
|
|
|
|
if:
|
|
%i0 = call i32 @f(i32 0)
|
|
ret i32 %i0
|
|
|
|
else:
|
|
%i1 = call i32 @f(i32 1)
|
|
ret i32 %i1
|
|
}
|
|
|
|
define i32 @one_case_1(i32 %x) {
|
|
; CHECK-LABEL: @one_case_1(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[SWITCH:%.*]] = icmp eq i32 [[X:%.*]], 10
|
|
; CHECK-NEXT: br i1 [[SWITCH]], label [[A:%.*]], label [[B:%.*]]
|
|
; CHECK: common.ret:
|
|
; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[TMP0:%.*]], [[B]] ], [ [[TMP1:%.*]], [[A]] ]
|
|
; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
|
|
; CHECK: a:
|
|
; CHECK-NEXT: [[TMP0]] = call i32 @f(i32 0)
|
|
; CHECK-NEXT: br label [[COMMON_RET:%.*]]
|
|
; CHECK: b:
|
|
; CHECK-NEXT: [[TMP1]] = call i32 @f(i32 1)
|
|
; CHECK-NEXT: br label [[COMMON_RET]]
|
|
;
|
|
entry:
|
|
switch i32 %x, label %unreachable [
|
|
i32 5, label %a
|
|
i32 6, label %a
|
|
i32 7, label %a
|
|
i32 10, label %b
|
|
]
|
|
|
|
unreachable:
|
|
unreachable
|
|
a:
|
|
%0 = call i32 @f(i32 0)
|
|
ret i32 %0
|
|
b:
|
|
%1 = call i32 @f(i32 1)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @one_case_2(i32 %x) {
|
|
; CHECK-LABEL: @one_case_2(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[SWITCH:%.*]] = icmp eq i32 [[X:%.*]], 5
|
|
; CHECK-NEXT: br i1 [[SWITCH]], label [[A:%.*]], label [[B:%.*]]
|
|
; CHECK: common.ret:
|
|
; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[TMP0:%.*]], [[A]] ], [ [[TMP1:%.*]], [[B]] ]
|
|
; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
|
|
; CHECK: a:
|
|
; CHECK-NEXT: [[TMP0]] = call i32 @f(i32 0)
|
|
; CHECK-NEXT: br label [[COMMON_RET:%.*]]
|
|
; CHECK: b:
|
|
; CHECK-NEXT: [[TMP1]] = call i32 @f(i32 1)
|
|
; CHECK-NEXT: br label [[COMMON_RET]]
|
|
;
|
|
entry:
|
|
switch i32 %x, label %unreachable [
|
|
i32 5, label %a
|
|
i32 10, label %b
|
|
i32 11, label %b
|
|
i32 12, label %b
|
|
i32 13, label %b
|
|
]
|
|
|
|
unreachable:
|
|
unreachable
|
|
a:
|
|
%0 = call i32 @f(i32 0)
|
|
ret i32 %0
|
|
b:
|
|
%1 = call i32 @f(i32 1)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @else_will_be_unreachable(i1 %arg) {
|
|
; CHECK-LABEL: @else_will_be_unreachable(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[I:%.*]] = select i1 [[ARG:%.*]], i32 0, i32 1
|
|
; CHECK-NEXT: ret i32 [[I]]
|
|
;
|
|
entry:
|
|
switch i1 %arg, label %else [
|
|
i1 false, label %if
|
|
i1 true, label %if
|
|
]
|
|
|
|
if:
|
|
br i1 %arg, label %else, label %bb
|
|
|
|
bb:
|
|
br label %else
|
|
|
|
else:
|
|
%i = phi i32 [ 0, %entry ], [ 0, %if ], [ 1, %bb ]
|
|
ret i32 %i
|
|
}
|
|
|
|
declare void @bar(ptr nonnull dereferenceable(4))
|