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
404 lines
12 KiB
LLVM
404 lines
12 KiB
LLVM
; 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
|
|
|
|
; SimplifyCFG should eliminate redundant indirectbr edges.
|
|
|
|
declare void @foo()
|
|
declare void @A()
|
|
declare void @B(i32)
|
|
declare void @C()
|
|
|
|
;.
|
|
; CHECK: @anchor = constant [13 x ptr] [ptr blockaddress(@indbrtest3, %L1), ptr blockaddress(@indbrtest3, %L2), ptr inttoptr (i32 1 to ptr), ptr blockaddress(@indbrtest4, %L1), ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr)]
|
|
; CHECK: @xblkx.bbs = internal unnamed_addr constant [9 x ptr] [ptr blockaddress(@indbrtest7, %xlab4x), ptr blockaddress(@indbrtest7, %xlab4x), ptr blockaddress(@indbrtest7, %v2j), ptr blockaddress(@indbrtest7, %xlab4x), ptr blockaddress(@indbrtest7, %xlab4x), ptr blockaddress(@indbrtest7, %xlab4x), ptr blockaddress(@indbrtest7, %xlab4x), ptr blockaddress(@indbrtest7, %xlab4x), ptr blockaddress(@indbrtest7, %v2j)]
|
|
;.
|
|
define void @indbrtest0(ptr %P, ptr %Q) !prof !0 {
|
|
; CHECK-LABEL: @indbrtest0(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: store ptr blockaddress(@indbrtest0, [[BB0:%.*]]), ptr [[P:%.*]], align 8
|
|
; CHECK-NEXT: store ptr blockaddress(@indbrtest0, [[BB1:%.*]]), ptr [[P]], align 8
|
|
; CHECK-NEXT: store ptr blockaddress(@indbrtest0, [[BB2:%.*]]), ptr [[P]], align 8
|
|
; CHECK-NEXT: call void @foo()
|
|
; CHECK-NEXT: [[T:%.*]] = load ptr, ptr [[Q:%.*]], align 8
|
|
; CHECK-NEXT: indirectbr ptr [[T]], [label [[BB0]], label [[BB1]], label %BB2], !prof [[PROF1:![0-9]+]]
|
|
; CHECK: BB0:
|
|
; CHECK-NEXT: call void @A()
|
|
; CHECK-NEXT: br label [[BB1]]
|
|
; CHECK: common.ret:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: BB1:
|
|
; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, [[BB0]] ], [ 1, [[ENTRY:%.*]] ]
|
|
; CHECK-NEXT: call void @B(i32 [[X]])
|
|
; CHECK-NEXT: br label [[COMMON_RET:%.*]]
|
|
; CHECK: BB2:
|
|
; CHECK-NEXT: call void @C()
|
|
; CHECK-NEXT: br label [[COMMON_RET]]
|
|
;
|
|
entry:
|
|
store ptr blockaddress(@indbrtest0, %BB0), ptr %P
|
|
store ptr blockaddress(@indbrtest0, %BB1), ptr %P
|
|
store ptr blockaddress(@indbrtest0, %BB2), ptr %P
|
|
call void @foo()
|
|
%t = load ptr, ptr %Q
|
|
indirectbr ptr %t, [label %BB0, label %BB1, label %BB2, label %BB0, label %BB1, label %BB2], !prof !1
|
|
BB0:
|
|
call void @A()
|
|
br label %BB1
|
|
BB1:
|
|
%x = phi i32 [ 0, %BB0 ], [ 1, %entry ], [ 1, %entry ]
|
|
call void @B(i32 %x)
|
|
ret void
|
|
BB2:
|
|
call void @C()
|
|
ret void
|
|
}
|
|
|
|
; SimplifyCFG should convert the indirectbr into a directbr. It would be even
|
|
; better if it removed the branch altogether, but simplifycfdg currently misses
|
|
; that because the predecessor is the entry block.
|
|
|
|
|
|
define void @indbrtest1(ptr %P, ptr %Q) {
|
|
; CHECK-LABEL: @indbrtest1(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: store ptr blockaddress(@indbrtest1, [[BB0:%.*]]), ptr [[P:%.*]], align 8
|
|
; CHECK-NEXT: call void @foo()
|
|
; CHECK-NEXT: br label [[BB0]]
|
|
; CHECK: BB0:
|
|
; CHECK-NEXT: call void @A()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
store ptr blockaddress(@indbrtest1, %BB0), ptr %P
|
|
call void @foo()
|
|
%t = load ptr, ptr %Q
|
|
indirectbr ptr %t, [label %BB0, label %BB0]
|
|
BB0:
|
|
call void @A()
|
|
ret void
|
|
}
|
|
|
|
; SimplifyCFG should notice that BB0 does not have its address taken and
|
|
; remove it from entry's successor list.
|
|
|
|
|
|
define void @indbrtest2(ptr %t) {
|
|
; CHECK-LABEL: @indbrtest2(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: unreachable
|
|
;
|
|
entry:
|
|
indirectbr ptr %t, [label %BB0, label %BB0]
|
|
BB0:
|
|
ret void
|
|
}
|
|
|
|
|
|
; Make sure the blocks in the next few tests aren't trivially removable as
|
|
; successors by taking their addresses.
|
|
|
|
@anchor = constant [13 x ptr] [
|
|
ptr blockaddress(@indbrtest3, %L1), ptr blockaddress(@indbrtest3, %L2), ptr blockaddress(@indbrtest3, %L3),
|
|
ptr blockaddress(@indbrtest4, %L1), ptr blockaddress(@indbrtest4, %L2), ptr blockaddress(@indbrtest4, %L3),
|
|
ptr blockaddress(@indbrtest5, %L1), ptr blockaddress(@indbrtest5, %L2), ptr blockaddress(@indbrtest5, %L3), ptr blockaddress(@indbrtest5, %L4),
|
|
ptr blockaddress(@indbrtest6, %L1), ptr blockaddress(@indbrtest6, %L2), ptr blockaddress(@indbrtest6, %L3)
|
|
]
|
|
|
|
; SimplifyCFG should turn the indirectbr into a conditional branch on the
|
|
; condition of the select.
|
|
|
|
define void @indbrtest3(i1 %cond, ptr %address) nounwind !prof !0 {
|
|
; CHECK-LABEL: @indbrtest3(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br i1 [[COND:%.*]], label [[L1:%.*]], label [[L2:%.*]], !prof [[PROF2:![0-9]+]]
|
|
; CHECK: common.ret:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: L1:
|
|
; CHECK-NEXT: call void @A()
|
|
; CHECK-NEXT: br label [[COMMON_RET:%.*]]
|
|
; CHECK: L2:
|
|
; CHECK-NEXT: call void @C()
|
|
; CHECK-NEXT: br label [[COMMON_RET]]
|
|
;
|
|
entry:
|
|
%indirect.goto.dest = select i1 %cond, ptr blockaddress(@indbrtest3, %L1), ptr blockaddress(@indbrtest3, %L2), !prof !2
|
|
indirectbr ptr %indirect.goto.dest, [label %L1, label %L2, label %L3], !prof !3
|
|
|
|
L1:
|
|
call void @A()
|
|
ret void
|
|
L2:
|
|
call void @C()
|
|
ret void
|
|
L3:
|
|
call void @foo()
|
|
ret void
|
|
}
|
|
|
|
; SimplifyCFG should turn the indirectbr into an unconditional branch to the
|
|
; only possible destination.
|
|
; As in @indbrtest1, it should really remove the branch entirely, but it doesn't
|
|
; because it's in the entry block.
|
|
|
|
define void @indbrtest4(i1 %cond) nounwind {
|
|
; CHECK-LABEL: @indbrtest4(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[L1:%.*]]
|
|
; CHECK: L1:
|
|
; CHECK-NEXT: call void @A()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%indirect.goto.dest = select i1 %cond, ptr blockaddress(@indbrtest4, %L1), ptr blockaddress(@indbrtest4, %L1)
|
|
indirectbr ptr %indirect.goto.dest, [label %L1, label %L2, label %L3]
|
|
|
|
L1:
|
|
call void @A()
|
|
ret void
|
|
L2:
|
|
call void @C()
|
|
ret void
|
|
L3:
|
|
call void @foo()
|
|
ret void
|
|
}
|
|
|
|
; SimplifyCFG should turn the indirectbr into an unreachable because neither
|
|
; destination is listed as a successor.
|
|
|
|
define void @indbrtest5(i1 %cond, ptr %anchor) nounwind {
|
|
; CHECK-LABEL: @indbrtest5(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: unreachable
|
|
;
|
|
entry:
|
|
%indirect.goto.dest = select i1 %cond, ptr blockaddress(@indbrtest5, %L1), ptr blockaddress(@indbrtest5, %L2)
|
|
; This needs to have more than one successor for this test, otherwise it gets
|
|
; replaced with an unconditional branch to the single successor.
|
|
indirectbr ptr %indirect.goto.dest, [label %L3, label %L4]
|
|
|
|
L1:
|
|
call void @A()
|
|
ret void
|
|
L2:
|
|
call void @C()
|
|
ret void
|
|
L3:
|
|
call void @foo()
|
|
ret void
|
|
L4:
|
|
call void @foo()
|
|
|
|
; This keeps blockaddresses not otherwise listed as successors from being zapped
|
|
; before SimplifyCFG even looks at the indirectbr.
|
|
indirectbr ptr %anchor, [label %L1, label %L2]
|
|
}
|
|
|
|
; The same as above, except the selected addresses are equal.
|
|
|
|
define void @indbrtest6(i1 %cond, ptr %anchor) nounwind {
|
|
; CHECK-LABEL: @indbrtest6(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: unreachable
|
|
;
|
|
entry:
|
|
%indirect.goto.dest = select i1 %cond, ptr blockaddress(@indbrtest6, %L1), ptr blockaddress(@indbrtest6, %L1)
|
|
; This needs to have more than one successor for this test, otherwise it gets
|
|
; replaced with an unconditional branch to the single successor.
|
|
indirectbr ptr %indirect.goto.dest, [label %L2, label %L3]
|
|
|
|
L1:
|
|
call void @A()
|
|
ret void
|
|
L2:
|
|
call void @C()
|
|
ret void
|
|
L3:
|
|
call void @foo()
|
|
|
|
; This keeps blockaddresses not otherwise listed as successors from being zapped
|
|
; before SimplifyCFG even looks at the indirectbr.
|
|
indirectbr ptr %anchor, [label %L1, label %L2]
|
|
}
|
|
|
|
; PR10072
|
|
|
|
@xblkx.bbs = internal unnamed_addr constant [9 x ptr] [ptr blockaddress(@indbrtest7, %xblkx.begin), ptr blockaddress(@indbrtest7, %xblkx.begin3), ptr blockaddress(@indbrtest7, %xblkx.begin4), ptr blockaddress(@indbrtest7, %xblkx.begin5), ptr blockaddress(@indbrtest7, %xblkx.begin6), ptr blockaddress(@indbrtest7, %xblkx.begin7), ptr blockaddress(@indbrtest7, %xblkx.begin8), ptr blockaddress(@indbrtest7, %xblkx.begin9), ptr blockaddress(@indbrtest7, %xblkx.end)]
|
|
|
|
define void @indbrtest7() {
|
|
; CHECK-LABEL: @indbrtest7(
|
|
; CHECK-NEXT: escape-string.top:
|
|
; CHECK-NEXT: [[XVAL202X:%.*]] = call i32 @xfunc5x()
|
|
; CHECK-NEXT: br label [[XLAB5X:%.*]]
|
|
; CHECK: xlab8x:
|
|
; CHECK-NEXT: [[XVALUEX:%.*]] = call i32 @xselectorx()
|
|
; CHECK-NEXT: [[XBLKX_X:%.*]] = getelementptr [9 x ptr], ptr @xblkx.bbs, i32 0, i32 [[XVALUEX]]
|
|
; CHECK-NEXT: [[XBLKX_LOAD:%.*]] = load ptr, ptr [[XBLKX_X]], align 8
|
|
; CHECK-NEXT: indirectbr ptr [[XBLKX_LOAD]], [label [[XLAB4X:%.*]], label %v2j]
|
|
; CHECK: v2j:
|
|
; CHECK-NEXT: [[XUNUSEDX:%.*]] = call i32 @xactionx()
|
|
; CHECK-NEXT: br label [[XLAB4X]]
|
|
; CHECK: xlab4x:
|
|
; CHECK-NEXT: [[INCR19:%.*]] = add i32 [[XVAL704X_0:%.*]], 1
|
|
; CHECK-NEXT: br label [[XLAB5X]]
|
|
; CHECK: xlab5x:
|
|
; CHECK-NEXT: [[XVAL704X_0]] = phi i32 [ 0, [[ESCAPE_STRING_TOP:%.*]] ], [ [[INCR19]], [[XLAB4X]] ]
|
|
; CHECK-NEXT: [[XVAL10X:%.*]] = icmp ult i32 [[XVAL704X_0]], [[XVAL202X]]
|
|
; CHECK-NEXT: br i1 [[XVAL10X]], label [[XLAB8X:%.*]], label [[XLAB9X:%.*]]
|
|
; CHECK: xlab9x:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
escape-string.top:
|
|
%xval202x = call i32 @xfunc5x()
|
|
br label %xlab5x
|
|
|
|
xlab8x: ; preds = %xlab5x
|
|
%xvaluex = call i32 @xselectorx()
|
|
%xblkx.x = getelementptr [9 x ptr], ptr @xblkx.bbs, i32 0, i32 %xvaluex
|
|
%xblkx.load = load ptr, ptr %xblkx.x
|
|
indirectbr ptr %xblkx.load, [label %xblkx.begin, label %xblkx.begin3, label %xblkx.begin4, label %xblkx.begin5, label %xblkx.begin6, label %xblkx.begin7, label %xblkx.begin8, label %xblkx.begin9, label %xblkx.end]
|
|
|
|
xblkx.begin:
|
|
br label %xblkx.end
|
|
|
|
xblkx.begin3:
|
|
br label %xblkx.end
|
|
|
|
xblkx.begin4:
|
|
br label %xblkx.end
|
|
|
|
xblkx.begin5:
|
|
br label %xblkx.end
|
|
|
|
xblkx.begin6:
|
|
br label %xblkx.end
|
|
|
|
xblkx.begin7:
|
|
br label %xblkx.end
|
|
|
|
xblkx.begin8:
|
|
br label %xblkx.end
|
|
|
|
xblkx.begin9:
|
|
br label %xblkx.end
|
|
|
|
xblkx.end:
|
|
%yes.0 = phi i1 [ false, %xblkx.begin ], [ true, %xlab8x ], [ false, %xblkx.begin9 ], [ false, %xblkx.begin8 ], [ false, %xblkx.begin7 ], [ false, %xblkx.begin6 ], [ false, %xblkx.begin5 ], [ true, %xblkx.begin4 ], [ false, %xblkx.begin3 ]
|
|
br i1 %yes.0, label %v2j, label %xlab17x
|
|
|
|
v2j:
|
|
%xunusedx = call i32 @xactionx()
|
|
br label %xlab4x
|
|
|
|
xlab17x:
|
|
br label %xlab4x
|
|
|
|
xlab4x:
|
|
%incr19 = add i32 %xval704x.0, 1
|
|
br label %xlab5x
|
|
|
|
xlab5x:
|
|
%xval704x.0 = phi i32 [ 0, %escape-string.top ], [ %incr19, %xlab4x ]
|
|
%xval10x = icmp ult i32 %xval704x.0, %xval202x
|
|
br i1 %xval10x, label %xlab8x, label %xlab9x
|
|
|
|
xlab9x:
|
|
ret void
|
|
}
|
|
|
|
define void @indbrtest8() {
|
|
; CHECK-LABEL: @indbrtest8(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: call void @B(i32 undef)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
indirectbr ptr blockaddress(@indbrtest8, %BB1), [label %BB0, label %BB1]
|
|
BB0:
|
|
call void @A()
|
|
ret void
|
|
BB1:
|
|
call void @B(i32 undef)
|
|
ret void
|
|
}
|
|
|
|
define void @indbrtest9() {
|
|
; CHECK-LABEL: @indbrtest9(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: unreachable
|
|
;
|
|
entry:
|
|
indirectbr ptr blockaddress(@indbrtest9, %BB1), [label %BB0]
|
|
BB0:
|
|
call void @A()
|
|
ret void
|
|
BB1:
|
|
call void @B(i32 undef)
|
|
ret void
|
|
}
|
|
|
|
define void @indbrtest10() {
|
|
; CHECK-LABEL: @indbrtest10(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: call void @B(i32 undef)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
indirectbr ptr blockaddress(@indbrtest10, %BB1), [label %BB1]
|
|
BB0:
|
|
call void @A()
|
|
ret void
|
|
BB1:
|
|
call void @B(i32 undef)
|
|
ret void
|
|
}
|
|
|
|
define void @indbrtest11() {
|
|
; CHECK-LABEL: @indbrtest11(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: call void @A()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
indirectbr ptr blockaddress(@indbrtest11, %BB0), [label %BB0, label %BB1, label %BB1]
|
|
BB0:
|
|
call void @A()
|
|
ret void
|
|
BB1:
|
|
call void @B(i32 undef)
|
|
ret void
|
|
}
|
|
|
|
define void @indbrtest12() {
|
|
; CHECK-LABEL: @indbrtest12(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: call void @B(i32 undef)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
indirectbr ptr blockaddress(@indbrtest12, %BB1), [label %BB0, label %BB1, label %BB1]
|
|
BB0:
|
|
call void @A()
|
|
ret void
|
|
BB1:
|
|
call void @B(i32 undef)
|
|
ret void
|
|
}
|
|
|
|
declare i32 @xfunc5x()
|
|
declare i8 @xfunc7x()
|
|
declare i32 @xselectorx()
|
|
declare i32 @xactionx()
|
|
|
|
!0 = !{!"function_entry_count", i32 10}
|
|
!1 = !{!"branch_weights", i32 3, i32 5, i32 7, i32 11, i32 13, i32 17}
|
|
!2 = !{!"branch_weights", i32 3, i32 5}
|
|
!3 = !{!"branch_weights", i32 3, i32 5, i32 7}
|
|
;.
|
|
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind }
|
|
;.
|
|
; CHECK: [[META0:![0-9]+]] = !{!"function_entry_count", i32 10}
|
|
; CHECK: [[PROF1]] = !{!"branch_weights", i32 14, i32 18, i32 24}
|
|
; CHECK: [[PROF2]] = !{!"branch_weights", i32 3, i32 5}
|
|
;.
|