Skip to content

[SPIR-V] Fix block sorting with irreducible CFG #116996

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions llvm/lib/Target/SPIRV/SPIRVUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,15 +635,12 @@ bool sortBlocks(Function &F) {
return false;

bool Modified = false;

std::vector<BasicBlock *> Order;
Order.reserve(F.size());

PartialOrderingVisitor Visitor(F);
Visitor.partialOrderVisit(*F.begin(), [&Order](BasicBlock *Block) {
Order.push_back(Block);
return true;
});
ReversePostOrderTraversal<Function *> RPOT(&F);
for (BasicBlock *BB : RPOT)
Order.push_back(BB);

assert(&*F.begin() == Order[0]);
BasicBlock *LastBlock = &*F.begin();
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/CodeGen/SPIRV/branching/OpSwitchBranches.ll
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,16 @@ end:
%result = load i32, ptr %alloc
ret i32 %result

; CHECK-SPIRV: %[[#DEFAULT]] = OpLabel
; CHECK-SPIRV: %[[#CASE3]] = OpLabel
; CHECK-SPIRV: OpBranch %[[#END:]]

; CHECK-SPIRV: %[[#CASE1]] = OpLabel
; CHECK-SPIRV: %[[#CASE2]] = OpLabel
; CHECK-SPIRV: OpBranch %[[#END]]

; CHECK-SPIRV: %[[#CASE2]] = OpLabel
; CHECK-SPIRV: %[[#CASE1]] = OpLabel
; CHECK-SPIRV: OpBranch %[[#END]]

; CHECK-SPIRV: %[[#CASE3]] = OpLabel
; CHECK-SPIRV: %[[#DEFAULT]] = OpLabel
; CHECK-SPIRV: OpBranch %[[#END]]

; CHECK-SPIRV: %[[#END]] = OpLabel
Expand Down
5 changes: 2 additions & 3 deletions llvm/test/CodeGen/SPIRV/branching/OpSwitchUnreachable.ll
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ define void @test_switch_with_unreachable_block(i1 %a) {
i32 1, label %reachable
]

; CHECK-SPIRV: %[[#UNREACHABLE]] = OpLabel
; CHECK-SPIRV-NEXT: OpUnreachable

; CHECK-SPIRV-NEXT: %[[#REACHABLE]] = OpLabel
reachable:
; CHECK-SPIRV-NEXT: OpReturn
ret void

; CHECK-SPIRV: %[[#UNREACHABLE]] = OpLabel
; CHECK-SPIRV-NEXT: OpUnreachable
unreachable:
unreachable
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,19 @@ case4:
default2:
ret void

; CHECK-SPIRV: %[[#CASE1]] = OpLabel
; CHECK-SPIRV: %[[#CASE2]] = OpLabel
; CHECK-SPIRV-NEXT: OpBranch %[[#DEFAULT1]]

; CHECK-SPIRV: %[[#CASE2]] = OpLabel
; CHECK-SPIRV: %[[#CASE1]] = OpLabel
; CHECK-SPIRV-NEXT: OpBranch %[[#DEFAULT1]]

; CHECK-SPIRV: %[[#DEFAULT1]] = OpLabel
; CHECK-SPIRV-NEXT: OpSwitch %[[#REGISTER]] %[[#DEFAULT2:]] 0 %[[#CASE3:]] 1 %[[#CASE4:]]

; CHECK-SPIRV: %[[#CASE3]] = OpLabel
; CHECK-SPIRV: %[[#CASE4]] = OpLabel
; CHECK-SPIRV-NEXT: OpBranch %[[#DEFAULT2]]

; CHECK-SPIRV: %[[#CASE4:]] = OpLabel
; CHECK-SPIRV: %[[#CASE3]] = OpLabel
; CHECK-SPIRV-NEXT: OpBranch %[[#DEFAULT2]]

; CHECK-SPIRV: %[[#DEFAULT2]] = OpLabel
Expand Down
31 changes: 16 additions & 15 deletions llvm/test/CodeGen/SPIRV/branching/if-merging.ll
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
; CHECK-DAG: OpName [[FOO:%.+]] "foo"
; CHECK-DAG: OpName [[BAR:%.+]] "bar"

; CHECK-DAG: [[I32:%.+]] = OpTypeInt 32
; CHECK-DAG: [[BOOL:%.+]] = OpTypeBool
; CHECK-DAG: %[[#I32:]] = OpTypeInt 32
; CHECK-DAG: %[[#BOOL:]] = OpTypeBool

declare i32 @foo()
declare i32 @bar()
Expand All @@ -30,23 +30,24 @@ merge_label:
}

; CHECK: OpFunction
; CHECK: [[A:%.+]] = OpFunctionParameter [[I32]]
; CHECK: [[B:%.+]] = OpFunctionParameter [[I32]]
; CHECK: %[[#A:]] = OpFunctionParameter %[[#I32]]
; CHECK: %[[#B:]] = OpFunctionParameter %[[#I32]]

; CHECK: [[ENTRY:%.+]] = OpLabel
; CHECK: [[COND:%.+]] = OpIEqual [[BOOL]] [[A]] [[B]]
; CHECK: OpBranchConditional [[COND]] [[TRUE_LABEL:%.+]] [[FALSE_LABEL:%.+]]
; CHECK: %[[#ENTRY:]] = OpLabel
; CHECK: %[[#COND:]] = OpIEqual %[[#BOOL]] %[[#A]] %[[#B]]
; CHECK: OpBranchConditional %[[#COND]] %[[#TRUE_LABEL:]] %[[#FALSE_LABEL:]]

; CHECK: [[TRUE_LABEL]] = OpLabel
; CHECK: [[V1:%.+]] = OpFunctionCall [[I32]] [[FOO]]
; CHECK: OpBranch [[MERGE_LABEL:%.+]]
; CHECK: %[[#FALSE_LABEL]] = OpLabel
; CHECK: %[[#V2:]] = OpFunctionCall %[[#I32]] [[BAR]]
; CHECK: OpBranch %[[#MERGE_LABEL:]]

; CHECK: [[FALSE_LABEL]] = OpLabel
; CHECK: [[V2:%.+]] = OpFunctionCall [[I32]] [[BAR]]
; CHECK: OpBranch [[MERGE_LABEL]]
; CHECK: %[[#TRUE_LABEL]] = OpLabel
; CHECK: %[[#V1:]] = OpFunctionCall %[[#I32]] [[FOO]]
; CHECK: OpBranch %[[#MERGE_LABEL]]

; CHECK: [[MERGE_LABEL]] = OpLabel
; CHECK-NEXT: [[V:%.+]] = OpPhi [[I32]] [[V1]] [[TRUE_LABEL]] [[V2]] [[FALSE_LABEL]]

; CHECK: %[[#MERGE_LABEL]] = OpLabel
; CHECK-NEXT: [[V:%.+]] = OpPhi %[[#I32]] %[[#V1]] %[[#TRUE_LABEL]] %[[#V2]] %[[#FALSE_LABEL]]
; CHECK: OpReturnValue [[V]]

; CHECK-NEXT: OpFunctionEnd
6 changes: 4 additions & 2 deletions llvm/test/CodeGen/SPIRV/branching/if-non-merging.ll
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ false_label:
; CHECK: [[ENTRY:%.+]] = OpLabel
; CHECK: [[COND:%.+]] = OpIEqual [[BOOL]] [[A]] [[B]]
; CHECK: OpBranchConditional [[COND]] [[TRUE_LABEL:%.+]] [[FALSE_LABEL:%.+]]
; CHECK: [[TRUE_LABEL]] = OpLabel
; CHECK: OpReturnValue [[TRUE]]

; CHECK: [[FALSE_LABEL]] = OpLabel
; CHECK: OpReturnValue [[FALSE]]

; CHECK: [[TRUE_LABEL]] = OpLabel
; CHECK: OpReturnValue [[TRUE]]
4 changes: 0 additions & 4 deletions llvm/test/CodeGen/SPIRV/instructions/ret-type.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown --translator-compatibility-mode %s -o - -filetype=obj | spirv-val %}
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}

; Modifying the block ordering prevents the pointer types to correctly be deduced. Not sure why, but looks
; orthogonal to the block sorting.
; XFAIL: *

; CHECK-DAG: OpName %[[Test1:.*]] "test1"
; CHECK-DAG: OpName %[[Foo:.*]] "foo"
; CHECK-DAG: OpName %[[Bar:.*]] "bar"
Expand Down
12 changes: 6 additions & 6 deletions llvm/test/CodeGen/SPIRV/structurizer/basic-if.ll
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ entry:
%1 = alloca i32, align 4
br i1 true, label %left, label %right

; CHECK: %[[#left]] = OpLabel
; CHECK: OpBranch %[[#merge]]
left:
store i32 0, ptr %1
br label %end

; CHECK: %[[#right]] = OpLabel
; CHECK: OpBranch %[[#merge]]
right:
store i32 0, ptr %1
br label %end

; CHECK: %[[#left]] = OpLabel
; CHECK: OpBranch %[[#merge]]
left:
store i32 0, ptr %1
br label %end

; CHECK: %[[#merge]] = OpLabel
; CHECK: OpReturnValue %[[#]]
end:
Expand Down
10 changes: 5 additions & 5 deletions llvm/test/CodeGen/SPIRV/structurizer/basic-loop.ll
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ header:
%2 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ]
br i1 true, label %body, label %merge

; CHECK: %[[#merge]] = OpLabel
; CHECK: OpReturnValue %[[#]]
merge:
ret i32 0

; CHECK: %[[#body]] = OpLabel
; CHECK: OpBranch %[[#continue]]
body:
Expand All @@ -31,11 +36,6 @@ continue:
br label %header
; CHECK: %[[#continue]] = OpLabel
; CHECK: OpBranch %[[#header]]

; CHECK: %[[#merge]] = OpLabel
; CHECK: OpReturnValue %[[#]]
merge:
ret i32 0
}

; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none)
Expand Down
12 changes: 6 additions & 6 deletions llvm/test/CodeGen/SPIRV/structurizer/basic-phi.ll
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ entry:
%0 = call token @llvm.experimental.convergence.entry()
br i1 true, label %left, label %right

; CHECK: %[[#left]] = OpLabel
; CHECK-NEXT: OpStore %[[#var]] %[[#int_0]]
; CHECK-NEXT: OpBranch %[[#merge]]
left:
br label %end

; CHECK: %[[#right]] = OpLabel
; CHECK-NEXT: OpStore %[[#var]] %[[#int_1]]
; CHECK-NEXT: OpBranch %[[#merge]]
right:
br label %end

; CHECK: %[[#left]] = OpLabel
; CHECK-NEXT: OpStore %[[#var]] %[[#int_0]]
; CHECK-NEXT: OpBranch %[[#merge]]
left:
br label %end

; CHECK: %[[#merge]] = OpLabel
; CHECK: %[[#tmp:]] = OpLoad %[[#]] %[[#var]]
; CHECK: OpReturnValue %[[#tmp]]
Expand Down
27 changes: 14 additions & 13 deletions llvm/test/CodeGen/SPIRV/structurizer/cf.cond-op.ll
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,18 @@ entry:
%var = alloca i32
br i1 true, label %a_true, label %a_false

; CHECK: %[[#a_true]] = OpLabel
; CHECK: OpStore %[[#r2m_a]] %[[#true]]
; CHECK: OpBranch %[[#a_merge]]
a_true:
br label %a_merge

; CHECK: %[[#a_false]] = OpLabel
; CHECK: OpStore %[[#r2m_a]] %[[#false]]
; CHECK: OpBranch %[[#a_merge]]
a_false:
br label %a_merge

; CHECK: %[[#a_true]] = OpLabel
; CHECK: OpStore %[[#r2m_a]] %[[#true]]
; CHECK: OpBranch %[[#a_merge]]
a_true:
br label %a_merge

; CHECK: %[[#a_merge]] = OpLabel
; CHECK: %[[#tmp:]] = OpLoad %[[#]] %[[#r2m_a]]
; CHECK: OpSelectionMerge %[[#b_merge:]]
Expand All @@ -89,6 +89,14 @@ b_merge:
%f1 = call spir_func noundef i32 @_Z2fnv() #4 [ "convergencectrl"(token %0) ]
br i1 true, label %c_true, label %c_false

; CHECK: %[[#c_false]] = OpLabel
; CHECK: %[[#]] = OpFunctionCall
; CHECK: OpStore %[[#r2m_b]] %[[#]]
; CHECK: OpBranch %[[#c_merge]]
c_false:
%f3 = call spir_func noundef i32 @_Z3fn2v() #4 [ "convergencectrl"(token %0) ]
br label %c_merge

; CHECK: %[[#c_true]] = OpLabel
; CHECK: %[[#]] = OpFunctionCall
; CHECK: OpStore %[[#r2m_b]] %[[#]]
Expand All @@ -97,13 +105,6 @@ c_true:
%f2 = call spir_func noundef i32 @_Z3fn1v() #4 [ "convergencectrl"(token %0) ]
br label %c_merge

; CHECK: %[[#c_false]] = OpLabel
; CHECK: %[[#]] = OpFunctionCall
; CHECK: OpStore %[[#r2m_b]] %[[#]]
; CHECK: OpBranch %[[#c_merge]]
c_false:
%f3 = call spir_func noundef i32 @_Z3fn2v() #4 [ "convergencectrl"(token %0) ]
br label %c_merge

; CHECK: %[[#c_merge]] = OpLabel
; CHECK: %[[#tmp:]] = OpLoad %[[#]] %[[#r2m_b]]
Expand Down
66 changes: 36 additions & 30 deletions llvm/test/CodeGen/SPIRV/structurizer/cf.for.continue.ll
Original file line number Diff line number Diff line change
Expand Up @@ -50,43 +50,49 @@
; CHECK: %[[#func_12:]] = OpFunction %[[#uint:]] DontInline %[[#]]
; CHECK: %[[#bb44:]] = OpLabel
; CHECK: OpBranch %[[#bb45:]]
; CHECK: %[[#bb45:]] = OpLabel
; CHECK: %[[#bb45]] = OpLabel
; CHECK: OpLoopMerge %[[#bb46:]] %[[#bb47:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb48:]] %[[#bb46:]]
; CHECK: %[[#bb48:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb49:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb49:]] %[[#bb50:]]
; CHECK: %[[#bb50:]] = OpLabel
; CHECK: OpBranch %[[#bb49:]]
; CHECK: %[[#bb49:]] = OpLabel
; CHECK: OpBranch %[[#bb47:]]
; CHECK: %[[#bb47:]] = OpLabel
; CHECK: OpBranch %[[#bb45:]]
; CHECK: %[[#bb46:]] = OpLabel
; CHECK: OpBranch %[[#bb51:]]
; CHECK: %[[#bb51:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb52:]] %[[#bb53:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb54:]] %[[#bb52:]]
; CHECK: %[[#bb54:]] = OpLabel
; CHECK: OpBranch %[[#bb55:]]
; CHECK: %[[#bb55:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb56:]] %[[#bb57:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb58:]] %[[#bb56:]]
; CHECK: %[[#bb58:]] = OpLabel
; CHECK: OpBranch %[[#bb57:]]
; CHECK: %[[#bb57:]] = OpLabel
; CHECK: OpBranch %[[#bb55:]]
; CHECK: %[[#bb56:]] = OpLabel
; CHECK: OpBranch %[[#bb53:]]
; CHECK: %[[#bb53:]] = OpLabel
; CHECK: OpBranch %[[#bb51:]]
; CHECK: %[[#bb52:]] = OpLabel
; CHECK: OpReturnValue %[[#]]
; CHECK: %[[#bb46]] = OpLabel
; CHECK: OpBranch %[[#bb51:]]
; CHECK: %[[#bb51]] = OpLabel
; CHECK: OpLoopMerge %[[#bb52:]] %[[#bb53:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb54:]] %[[#bb52]]
; CHECK: %[[#bb52]] = OpLabel
; CHECK: OpReturnValue %[[#]]

; CHECK: %[[#bb54]] = OpLabel
; CHECK: OpBranch %[[#bb55:]]
; CHECK: %[[#bb55]] = OpLabel
; CHECK: OpLoopMerge %[[#bb56:]] %[[#bb57:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb58:]] %[[#bb56]]
; CHECK: %[[#bb56]] = OpLabel
; CHECK: OpBranch %[[#bb53]]
; CHECK: %[[#bb53]] = OpLabel
; CHECK: OpBranch %[[#bb51]]

; CHECK: %[[#bb58]] = OpLabel
; CHECK: OpBranch %[[#bb57]]
; CHECK: %[[#bb57]] = OpLabel
; CHECK: OpBranch %[[#bb55]]
; CHECK: %[[#bb48]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb49:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb49]] %[[#bb50:]]
; CHECK: %[[#bb50]] = OpLabel
; CHECK: OpBranch %[[#bb49]]

; CHECK: %[[#bb49]] = OpLabel
; CHECK: OpBranch %[[#bb47]]

; CHECK: %[[#bb47]] = OpLabel
; CHECK: OpBranch %[[#bb45]]
; CHECK: OpFunctionEnd

; CHECK: %[[#func_40:]] = OpFunction %[[#void:]] DontInline %[[#]]
; CHECK: %[[#bb59:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd

; CHECK: %[[#func_42:]] = OpFunction %[[#void:]] None %[[#]]
; CHECK: %[[#bb60:]] = OpLabel
; CHECK: OpReturn
Expand Down
Loading
Loading