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

Block sorting was assuming reducible CFG. Meaning we always had a best
node to continue with. Irreducible CFG makes breaks this assumption, so
the algorithm looped indefinitely because no node was a valid candidate.

Fixes #116692

---------

Signed-off-by: Nathan Gauër <brioche@google.com>
This commit is contained in:
Nathan Gauër
2024-11-28 13:42:57 +01:00
committed by GitHub
parent c952f0ee54
commit 53326ee0cf
33 changed files with 1243 additions and 814 deletions

View File

@@ -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();

View File

@@ -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: OpBranch %[[#END]]
; CHECK-SPIRV: %[[#CASE2]] = OpLabel
; CHECK-SPIRV: OpBranch %[[#END]]
; CHECK-SPIRV: %[[#CASE3]] = OpLabel
; CHECK-SPIRV: %[[#CASE1]] = OpLabel
; CHECK-SPIRV: OpBranch %[[#END]]
; CHECK-SPIRV: %[[#DEFAULT]] = OpLabel
; CHECK-SPIRV: OpBranch %[[#END]]
; CHECK-SPIRV: %[[#END]] = OpLabel

View File

@@ -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
}

View File

@@ -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

View File

@@ -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()
@@ -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

View File

@@ -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]]

View File

@@ -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"

View File

@@ -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:

View File

@@ -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:
@@ -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)

View File

@@ -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]]

View File

@@ -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:]]
@@ -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]] %[[#]]
@@ -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]]

View File

@@ -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

View File

@@ -28,38 +28,43 @@
; CHECK: %[[#func_11:]] = OpFunction %[[#uint:]] DontInline %[[#]]
; CHECK: %[[#bb41:]] = OpLabel
; CHECK: OpBranch %[[#bb42:]]
; CHECK: %[[#bb42:]] = OpLabel
; CHECK: %[[#bb42]] = OpLabel
; CHECK: OpLoopMerge %[[#bb43:]] %[[#bb44:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb45:]] %[[#bb43:]]
; CHECK: %[[#bb45:]] = OpLabel
; CHECK: OpBranch %[[#bb46:]]
; CHECK: %[[#bb46:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb47:]] %[[#bb48:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb49:]] %[[#bb47:]]
; CHECK: %[[#bb49:]] = OpLabel
; CHECK: OpBranch %[[#bb50:]]
; CHECK: %[[#bb50:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb51:]] %[[#bb52:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb53:]] %[[#bb51:]]
; CHECK: %[[#bb53:]] = OpLabel
; CHECK: OpBranch %[[#bb52:]]
; CHECK: %[[#bb52:]] = OpLabel
; CHECK: OpBranch %[[#bb50:]]
; CHECK: %[[#bb51:]] = OpLabel
; CHECK: OpBranch %[[#bb48:]]
; CHECK: %[[#bb48:]] = OpLabel
; CHECK: OpBranch %[[#bb46:]]
; CHECK: %[[#bb47:]] = OpLabel
; CHECK: OpBranch %[[#bb44:]]
; CHECK: %[[#bb44:]] = OpLabel
; CHECK: OpBranch %[[#bb42:]]
; CHECK: %[[#bb43:]] = OpLabel
; CHECK: OpReturnValue %[[#]]
; CHECK: OpBranchConditional %[[#]] %[[#bb45:]] %[[#bb43]]
; CHECK: %[[#bb43]] = OpLabel
; CHECK: OpReturnValue %[[#]]
; CHECK: %[[#bb45]] = OpLabel
; CHECK: OpBranch %[[#bb46:]]
; CHECK: %[[#bb46]] = OpLabel
; CHECK: OpLoopMerge %[[#bb47:]] %[[#bb48:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb49:]] %[[#bb47]]
; CHECK: %[[#bb47]] = OpLabel
; CHECK: OpBranch %[[#bb44]]
; CHECK: %[[#bb44]] = OpLabel
; CHECK: OpBranch %[[#bb42]]
; CHECK: %[[#bb49]] = OpLabel
; CHECK: OpBranch %[[#bb50:]]
; CHECK: %[[#bb50]] = OpLabel
; CHECK: OpLoopMerge %[[#bb51:]] %[[#bb52:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb53:]] %[[#bb51]]
; CHECK: %[[#bb51]] = OpLabel
; CHECK: OpBranch %[[#bb48]]
; CHECK: %[[#bb48]] = OpLabel
; CHECK: OpBranch %[[#bb46]]
; CHECK: %[[#bb53]] = OpLabel
; CHECK: OpBranch %[[#bb52]]
; CHECK: %[[#bb52]] = OpLabel
; CHECK: OpBranch %[[#bb50]]
; CHECK: OpFunctionEnd
; CHECK: %[[#func_37:]] = OpFunction %[[#void:]] DontInline %[[#]]
; CHECK: %[[#bb54:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd
; CHECK: %[[#func_39:]] = OpFunction %[[#void:]] None %[[#]]
; CHECK: %[[#bb55:]] = OpLabel
; CHECK: OpReturn

View File

@@ -37,28 +37,13 @@ for.cond: ; preds = %for.inc, %entry
; CHECK: OpBranchConditional %[[#]] %[[#for_body:]] %[[#for_end]]
br i1 %cmp, label %for.body, label %for.end
for.body: ; preds = %for.cond
%3 = load i32, ptr %i, align 4
store i32 %3, ptr %val, align 4
br label %for.inc
; CHECK: %[[#for_body]] = OpLabel
; CHECK: OpBranch %[[#for_inc]]
for.inc: ; preds = %for.body
%4 = load i32, ptr %i, align 4
%inc = add nsw i32 %4, 1
store i32 %inc, ptr %i, align 4
br label %for.cond
; CHECK: %[[#for_inc]] = OpLabel
; CHECK: OpBranch %[[#for_cond]]
for.end: ; preds = %for.cond
br label %for.cond1
; CHECK: %[[#for_end]] = OpLabel
; CHECK: OpBranch %[[#for_cond1:]]
for.cond1: ; preds = %for.cond1, %for.end
%5 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ]
%3 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ]
store i32 0, ptr %val, align 4
br label %for.cond1
; CHECK: %[[#for_cond1]] = OpLabel
@@ -67,6 +52,23 @@ for.cond1: ; preds = %for.cond1, %for.end
; CHECK: %[[#unreachable]] = OpLabel
; CHECK-NEXT: OpUnreachable
for.body: ; preds = %for.cond
%4 = load i32, ptr %i, align 4
store i32 %4, ptr %val, align 4
br label %for.inc
; CHECK: %[[#for_body]] = OpLabel
; CHECK: OpBranch %[[#for_inc]]
for.inc: ; preds = %for.body
%5 = load i32, ptr %i, align 4
%inc = add nsw i32 %5, 1
store i32 %inc, ptr %i, align 4
br label %for.cond
; CHECK: %[[#for_inc]] = OpLabel
; CHECK: OpBranch %[[#for_cond]]
}
; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none)

View File

@@ -42,115 +42,146 @@
; process();
; }
; CHECK: %[[#func_14:]] = OpFunction %[[#uint:]] DontInline %[[#]]
; CHECK: %[[#bb87:]] = OpLabel
; CHECK: OpBranch %[[#bb88:]]
; CHECK: %[[#bb88:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb89:]] %[[#bb90:]] None
; CHECK: OpBranch %[[#bb91:]]
; CHECK: %[[#bb91:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb92:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb93:]] %[[#bb92:]]
; CHECK: %[[#bb93:]] = OpLabel
; CHECK: OpBranch %[[#bb92:]]
; CHECK: %[[#bb92:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb94:]] %[[#bb89:]]
; CHECK: %[[#bb94:]] = OpLabel
; CHECK: OpBranch %[[#bb90:]]
; CHECK: %[[#bb89:]] = OpLabel
; CHECK: OpBranch %[[#bb95:]]
; CHECK: %[[#bb90:]] = OpLabel
; CHECK: OpBranch %[[#bb88:]]
; CHECK: %[[#bb95:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb96:]] %[[#bb97:]] None
; CHECK: OpBranch %[[#bb98:]]
; CHECK: %[[#bb98:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb99:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb99:]] %[[#bb100:]]
; CHECK: %[[#bb100:]] = OpLabel
; CHECK: OpBranch %[[#bb99:]]
; CHECK: %[[#bb99:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb101:]] %[[#bb96:]]
; CHECK: %[[#bb101:]] = OpLabel
; CHECK: OpBranch %[[#bb97:]]
; CHECK: %[[#bb96:]] = OpLabel
; CHECK: OpBranch %[[#bb102:]]
; CHECK: %[[#bb97:]] = OpLabel
; CHECK: OpBranch %[[#bb95:]]
; CHECK: %[[#bb102:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb103:]] %[[#bb104:]] None
; CHECK: OpBranch %[[#bb105:]]
; CHECK: %[[#bb105:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb106:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb107:]] %[[#bb106:]]
; CHECK: %[[#bb107:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb108:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb109:]] %[[#bb110:]]
; CHECK: %[[#bb109:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb111:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb111:]] %[[#bb112:]]
; CHECK: %[[#bb110:]] = OpLabel
; CHECK: %[[#bb112:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb111:]] %[[#bb113:]]
; CHECK: %[[#bb113:]] = OpLabel
; CHECK: OpBranch %[[#bb111:]]
; CHECK: %[[#bb111:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb114:]] %[[#bb108:]]
; CHECK: %[[#bb114:]] = OpLabel
; CHECK: OpBranch %[[#bb108:]]
; CHECK: %[[#bb108:]] = OpLabel
; CHECK: OpBranch %[[#bb106:]]
; CHECK: %[[#bb106:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb115:]] %[[#bb103:]]
; CHECK: %[[#bb115:]] = OpLabel
; CHECK: OpBranch %[[#bb104:]]
; CHECK: %[[#bb103:]] = OpLabel
; CHECK: OpBranch %[[#bb116:]]
; CHECK: %[[#bb104:]] = OpLabel
; CHECK: OpBranch %[[#bb102:]]
; CHECK: %[[#bb116:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb117:]] %[[#bb118:]] None
; CHECK: OpBranch %[[#bb119:]]
; CHECK: %[[#bb119:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb120:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb121:]] %[[#bb122:]]
; CHECK: %[[#bb121:]] = OpLabel
; CHECK: OpBranch %[[#bb120:]]
; CHECK: %[[#bb122:]] = OpLabel
; CHECK: OpBranch %[[#bb120:]]
; CHECK: %[[#bb120:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb123:]] %[[#bb117:]]
; CHECK: %[[#bb123:]] = OpLabel
; CHECK: OpBranch %[[#bb118:]]
; CHECK: %[[#bb117:]] = OpLabel
; CHECK: OpBranch %[[#bb124:]]
; CHECK: %[[#bb118:]] = OpLabel
; CHECK: OpBranch %[[#bb116:]]
; CHECK: %[[#bb124:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb125:]] %[[#bb126:]] None
; CHECK: OpBranch %[[#bb127:]]
; CHECK: %[[#bb127:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb128:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb129:]] %[[#bb128:]]
; CHECK: %[[#bb129:]] = OpLabel
; CHECK: OpBranch %[[#bb128:]]
; CHECK: %[[#bb128:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb130:]] %[[#bb125:]]
; CHECK: %[[#bb130:]] = OpLabel
; CHECK: OpBranch %[[#bb126:]]
; CHECK: %[[#bb126:]] = OpLabel
; CHECK: OpBranch %[[#bb124:]]
; CHECK: %[[#bb125:]] = OpLabel
; CHECK: OpReturnValue %[[#]]
; CHECK: OpFunctionEnd
; CHECK: %[[#func_83:]] = OpFunction %[[#void:]] DontInline %[[#]]
; CHECK: %[[#bb131:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd
; CHECK: %[[#func_85:]] = OpFunction %[[#void:]] None %[[#]]
; CHECK: %[[#bb132:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd
; CHECK: %[[#process:]] = OpFunction %[[#uint:]] DontInline %[[#]]
; CHECK: %[[#bb86:]] = OpLabel
; CHECK: OpBranch %[[#bb87:]]
; CHECK: %[[#bb87]] = OpLabel
; CHECK: OpLoopMerge %[[#bb89:]] %[[#bb90:]] None
; CHECK: OpBranch %[[#bb91:]]
; CHECK: %[[#bb91]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb92:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb93:]] %[[#bb94:]]
; CHECK: %[[#bb94]] = OpLabel
; CHECK: OpBranch %[[#bb92]]
; CHECK: %[[#bb93]] = OpLabel
; CHECK: OpBranch %[[#bb92]]
; CHECK: %[[#bb92]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb96:]] %[[#bb89]]
; CHECK: %[[#bb89]] = OpLabel
; CHECK: OpBranch %[[#bb97:]]
; CHECK: %[[#bb97]] = OpLabel
; CHECK: OpLoopMerge %[[#bb99:]] %[[#bb100:]] None
; CHECK: OpBranch %[[#bb101:]]
; CHECK: %[[#bb101]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb102:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb103:]] %[[#bb104:]]
; CHECK: %[[#bb104]] = OpLabel
; CHECK: OpBranch %[[#bb102]]
; CHECK: %[[#bb103]] = OpLabel
; CHECK: OpBranch %[[#bb102]]
; CHECK: %[[#bb102]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb106:]] %[[#bb99]]
; CHECK: %[[#bb99]] = OpLabel
; CHECK: OpBranch %[[#bb107:]]
; CHECK: %[[#bb107]] = OpLabel
; CHECK: OpLoopMerge %[[#bb109:]] %[[#bb110:]] None
; CHECK: OpBranch %[[#bb111:]]
; CHECK: %[[#bb111]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb112:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb113:]] %[[#bb114:]]
; CHECK: %[[#bb114]] = OpLabel
; CHECK: OpBranch %[[#bb112]]
; CHECK: %[[#bb113]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb116:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb117:]] %[[#bb116]]
; CHECK: %[[#bb117]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb118:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb119:]] %[[#bb120:]]
; CHECK: %[[#bb120]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb122:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb122]] %[[#bb123:]]
; CHECK: %[[#bb123]] = OpLabel
; CHECK: OpBranch %[[#bb122]]
; CHECK: %[[#bb122]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb126:]] %[[#bb118]]
; CHECK: %[[#bb126]] = OpLabel
; CHECK: OpBranch %[[#bb118]]
; CHECK: %[[#bb119]] = OpLabel
; CHECK: OpBranch %[[#bb118]]
; CHECK: %[[#bb118]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb116]] %[[#bb129:]]
; CHECK: %[[#bb129]] = OpLabel
; CHECK: OpBranch %[[#bb116]]
; CHECK: %[[#bb116]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb112]] %[[#bb133:]]
; CHECK: %[[#bb133]] = OpLabel
; CHECK: OpBranch %[[#bb112]]
; CHECK: %[[#bb112]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb136:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb136]] %[[#bb137:]]
; CHECK: %[[#bb137]] = OpLabel
; CHECK-NEXT: OpUnreachable
; CHECK: %[[#bb136]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb138:]] %[[#bb109]]
; CHECK: %[[#bb109]] = OpLabel
; CHECK: OpBranch %[[#bb139:]]
; CHECK: %[[#bb139]] = OpLabel
; CHECK: OpLoopMerge %[[#bb141:]] %[[#bb142:]] None
; CHECK: OpBranch %[[#bb143:]]
; CHECK: %[[#bb143]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb144:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb145:]] %[[#bb146:]]
; CHECK: %[[#bb146]] = OpLabel
; CHECK: OpBranch %[[#bb144]]
; CHECK: %[[#bb145]] = OpLabel
; CHECK: OpBranch %[[#bb144]]
; CHECK: %[[#bb144]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb149:]] %[[#bb141]]
; CHECK: %[[#bb141]] = OpLabel
; CHECK: OpBranch %[[#bb150:]]
; CHECK: %[[#bb150]] = OpLabel
; CHECK: OpLoopMerge %[[#bb153:]] %[[#bb154:]] None
; CHECK: OpBranch %[[#bb155:]]
; CHECK: %[[#bb155]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb156:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb157:]] %[[#bb158:]]
; CHECK: %[[#bb158]] = OpLabel
; CHECK: OpBranch %[[#bb156]]
; CHECK: %[[#bb157]] = OpLabel
; CHECK: OpBranch %[[#bb156]]
; CHECK: %[[#bb156]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb160:]] %[[#bb153]]
; CHECK: %[[#bb153]] = OpLabel
; CHECK: OpReturnValue %[[#]]
; CHECK: %[[#bb160]] = OpLabel
; CHECK: OpBranch %[[#bb154]]
; CHECK: %[[#bb154]] = OpLabel
; CHECK: OpBranch %[[#bb150]]
; CHECK: %[[#bb149]] = OpLabel
; CHECK: OpBranch %[[#bb142]]
; CHECK: %[[#bb142]] = OpLabel
; CHECK: OpBranch %[[#bb139]]
; CHECK: %[[#bb138]] = OpLabel
; CHECK: OpBranch %[[#bb110]]
; CHECK: %[[#bb110]] = OpLabel
; CHECK: OpBranch %[[#bb107]]
; CHECK: %[[#bb106]] = OpLabel
; CHECK: OpBranch %[[#bb100]]
; CHECK: %[[#bb100]] = OpLabel
; CHECK: OpBranch %[[#bb97]]
; CHECK: %[[#bb96]] = OpLabel
; CHECK: OpBranch %[[#bb90]]
; CHECK: %[[#bb90]] = OpLabel
; CHECK: OpBranch %[[#bb87]]
; CHECK: OpFunctionEnd
; CHECK: %[[#func_main:]] = OpFunction %[[#void:]] DontInline %[[#]]
; CHECK: %[[#bb172:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd
; CHECK: %[[#func_main_1:]] = OpFunction %[[#void]] None %[[#]]
; CHECK: %[[#bb173:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
target triple = "spirv-unknown-vulkan1.3-compute"

View File

@@ -49,72 +49,73 @@
; CHECK: %[[#func_18:]] = OpFunction %[[#uint:]] DontInline %[[#]]
; CHECK: %[[#bb65:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb66:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb67:]] %[[#bb66:]]
; CHECK: %[[#bb67:]] = OpLabel
; CHECK: OpBranch %[[#bb66:]]
; CHECK: %[[#bb66:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb67:]] %[[#bb66]]
; CHECK: %[[#bb67]] = OpLabel
; CHECK: OpBranch %[[#bb66]]
; CHECK: %[[#bb66]] = OpLabel
; CHECK: OpBranch %[[#bb68:]]
; CHECK: %[[#bb68:]] = OpLabel
; CHECK: %[[#bb68]] = OpLabel
; CHECK: OpLoopMerge %[[#bb69:]] %[[#bb70:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb71:]] %[[#bb69:]]
; CHECK: %[[#bb71:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb71:]] %[[#bb69]]
; CHECK: %[[#bb69]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb72:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb73:]] %[[#bb72:]]
; CHECK: %[[#bb73:]] = OpLabel
; CHECK: OpBranch %[[#bb74:]]
; CHECK: %[[#bb74:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb75:]] %[[#bb76:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb77:]] %[[#bb75:]]
; CHECK: %[[#bb77:]] = OpLabel
; CHECK: OpBranch %[[#bb76:]]
; CHECK: %[[#bb76:]] = OpLabel
; CHECK: OpBranch %[[#bb74:]]
; CHECK: %[[#bb75:]] = OpLabel
; CHECK: OpBranch %[[#bb72:]]
; CHECK: %[[#bb72:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb78:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb79:]] %[[#bb80:]]
; CHECK: %[[#bb79:]] = OpLabel
; CHECK: OpBranch %[[#bb78:]]
; CHECK: %[[#bb80:]] = OpLabel
; CHECK: OpBranch %[[#bb81:]]
; CHECK: %[[#bb81:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb82:]] %[[#bb83:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb84:]] %[[#bb82:]]
; CHECK: %[[#bb84:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb85:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb86:]] %[[#bb85:]]
; CHECK: %[[#bb86:]] = OpLabel
; CHECK: OpBranch %[[#bb85:]]
; CHECK: %[[#bb85:]] = OpLabel
; CHECK: OpBranch %[[#bb83:]]
; CHECK: %[[#bb83:]] = OpLabel
; CHECK: OpBranch %[[#bb81:]]
; CHECK: %[[#bb82:]] = OpLabel
; CHECK: OpBranch %[[#bb78:]]
; CHECK: %[[#bb78:]] = OpLabel
; CHECK: OpBranch %[[#bb70:]]
; CHECK: %[[#bb70:]] = OpLabel
; CHECK: OpBranch %[[#bb68:]]
; CHECK: %[[#bb69:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb87:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb88:]] %[[#bb87:]]
; CHECK: %[[#bb88:]] = OpLabel
; CHECK: OpBranch %[[#bb87:]]
; CHECK: %[[#bb87:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb73:]] %[[#bb72]]
; CHECK: %[[#bb73]] = OpLabel
; CHECK: OpBranch %[[#bb72]]
; CHECK: %[[#bb72]] = OpLabel
; CHECK: OpReturnValue %[[#]]
; CHECK: %[[#bb71]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb74:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb75:]] %[[#bb74]]
; CHECK: %[[#bb75]] = OpLabel
; CHECK: OpBranch %[[#bb76:]]
; CHECK: %[[#bb76]] = OpLabel
; CHECK: OpLoopMerge %[[#bb77:]] %[[#bb78:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb79:]] %[[#bb77]]
; CHECK: %[[#bb77]] = OpLabel
; CHECK: OpBranch %[[#bb74]]
; CHECK: %[[#bb74]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb80:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb81:]] %[[#bb82:]]
; CHECK: %[[#bb82]] = OpLabel
; CHECK: OpBranch %[[#bb83:]]
; CHECK: %[[#bb83]] = OpLabel
; CHECK: OpLoopMerge %[[#bb84:]] %[[#bb85:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb86:]] %[[#bb84]]
; CHECK: %[[#bb84]] = OpLabel
; CHECK: OpBranch %[[#bb80]]
; CHECK: %[[#bb86]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb87:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb88:]] %[[#bb87]]
; CHECK: %[[#bb88]] = OpLabel
; CHECK: OpBranch %[[#bb87]]
; CHECK: %[[#bb87]] = OpLabel
; CHECK: OpBranch %[[#bb85]]
; CHECK: %[[#bb85]] = OpLabel
; CHECK: OpBranch %[[#bb83]]
; CHECK: %[[#bb81]] = OpLabel
; CHECK: OpBranch %[[#bb80]]
; CHECK: %[[#bb80]] = OpLabel
; CHECK: OpBranch %[[#bb70]]
; CHECK: %[[#bb70]] = OpLabel
; CHECK: OpBranch %[[#bb68]]
; CHECK: %[[#bb79]] = OpLabel
; CHECK: OpBranch %[[#bb78]]
; CHECK: %[[#bb78]] = OpLabel
; CHECK: OpBranch %[[#bb76]]
; CHECK: OpFunctionEnd
; CHECK: %[[#func_61:]] = OpFunction %[[#void:]] DontInline %[[#]]
; CHECK: %[[#bb89:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd
; CHECK: %[[#func_63:]] = OpFunction %[[#void:]] None %[[#]]
; CHECK: %[[#func_63:]] = OpFunction %[[#void]] None %[[#]]
; CHECK: %[[#bb90:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
target triple = "spirv-unknown-vulkan1.3-compute"

View File

@@ -34,35 +34,35 @@
; CHECK: %[[#bb30:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb31:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb32:]] %[[#bb33:]]
; CHECK: %[[#bb32:]] = OpLabel
; CHECK: %[[#bb33]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb34:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb35:]] %[[#bb34:]]
; CHECK: %[[#bb33:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb36:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb37:]] %[[#bb38:]]
; CHECK: %[[#bb35:]] = OpLabel
; CHECK: OpBranch %[[#bb34:]]
; CHECK: %[[#bb37:]] = OpLabel
; CHECK: OpBranch %[[#bb36:]]
; CHECK: %[[#bb38:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb35:]] %[[#bb36:]]
; CHECK: %[[#bb36]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb37:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb38:]] %[[#bb37]]
; CHECK: %[[#bb38]] = OpLabel
; CHECK: OpBranch %[[#bb37]]
; CHECK: %[[#bb37]] = OpLabel
; CHECK: OpBranch %[[#bb34]]
; CHECK: %[[#bb35]] = OpLabel
; CHECK: OpBranch %[[#bb34]]
; CHECK: %[[#bb34]] = OpLabel
; CHECK: OpBranch %[[#bb31]]
; CHECK: %[[#bb32]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb39:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb40:]] %[[#bb39:]]
; CHECK: %[[#bb34:]] = OpLabel
; CHECK: OpBranch %[[#bb31:]]
; CHECK: %[[#bb40:]] = OpLabel
; CHECK: OpBranch %[[#bb39:]]
; CHECK: %[[#bb39:]] = OpLabel
; CHECK: OpBranch %[[#bb36:]]
; CHECK: %[[#bb36:]] = OpLabel
; CHECK: OpBranch %[[#bb31:]]
; CHECK: %[[#bb31:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb40:]] %[[#bb39]]
; CHECK: %[[#bb40]] = OpLabel
; CHECK: OpBranch %[[#bb39]]
; CHECK: %[[#bb39]] = OpLabel
; CHECK: OpBranch %[[#bb31]]
; CHECK: %[[#bb31]] = OpLabel
; CHECK: OpReturnValue %[[#]]
; CHECK: OpFunctionEnd
; CHECK: %[[#func_26:]] = OpFunction %[[#void:]] DontInline %[[#]]
; CHECK: %[[#bb41:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd
; CHECK: %[[#func_28:]] = OpFunction %[[#void:]] None %[[#]]
; CHECK: %[[#func_28:]] = OpFunction %[[#void]] None %[[#]]
; CHECK: %[[#bb42:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd

View File

@@ -59,51 +59,53 @@
; }
; CHECK: %[[#func_13:]] = OpFunction %[[#uint:]] DontInline %[[#]]
; CHECK: %[[#bb43:]] = OpLabel
; CHECK: OpBranch %[[#bb44:]]
; CHECK: %[[#bb44:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb45:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb46:]] %[[#bb47:]]
; CHECK: %[[#bb46:]] = OpLabel
; CHECK: OpBranch %[[#bb47:]]
; CHECK: %[[#bb47]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb48:]] None
; CHECK: OpSwitch %[[#]] %[[#bb48:]] 1 %[[#bb49:]] 2 %[[#bb50:]] 5 %[[#bb51:]]
; CHECK: %[[#bb47:]] = OpLabel
; CHECK: OpBranch %[[#bb45:]]
; CHECK: %[[#bb49:]] = OpLabel
; CHECK: OpBranch %[[#bb48:]]
; CHECK: %[[#bb50:]] = OpLabel
; CHECK: OpBranch %[[#bb48:]]
; CHECK: %[[#bb51:]] = OpLabel
; CHECK: OpBranch %[[#bb48:]]
; CHECK: %[[#bb48:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb52:]] %[[#bb45:]]
; CHECK: %[[#bb52:]] = OpLabel
; CHECK: OpBranch %[[#bb53:]]
; CHECK: %[[#bb53:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb54:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb54:]] %[[#bb55:]]
; CHECK: %[[#bb55:]] = OpLabel
; CHECK: OpBranch %[[#bb54:]]
; CHECK: %[[#bb54:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb56:]] %[[#bb45:]]
; CHECK: %[[#bb56:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb49:]] %[[#bb50:]]
; CHECK: %[[#bb50]] = OpLabel
; CHECK: OpBranch %[[#bb48]]
; CHECK: %[[#bb49]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb51:]] None
; CHECK: OpSwitch %[[#]] %[[#bb51]] 1 %[[#bb52:]] 2 %[[#bb53:]] 5 %[[#bb54:]]
; CHECK: %[[#bb54]] = OpLabel
; CHECK: OpBranch %[[#bb51]]
; CHECK: %[[#bb53]] = OpLabel
; CHECK: OpBranch %[[#bb51]]
; CHECK: %[[#bb52]] = OpLabel
; CHECK: OpBranch %[[#bb51]]
; CHECK: %[[#bb51]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb55:]] %[[#bb48]]
; CHECK: %[[#bb55]] = OpLabel
; CHECK: OpBranch %[[#bb56:]]
; CHECK: %[[#bb56]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb57:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb57:]] %[[#bb58:]]
; CHECK: %[[#bb58:]] = OpLabel
; CHECK: OpBranch %[[#bb57:]]
; CHECK: %[[#bb57:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb59:]] %[[#bb45:]]
; CHECK: %[[#bb59:]] = OpLabel
; CHECK: OpBranch %[[#bb45:]]
; CHECK: %[[#bb45:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb57]] %[[#bb58:]]
; CHECK: %[[#bb58]] = OpLabel
; CHECK: OpBranch %[[#bb57]]
; CHECK: %[[#bb57]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb59:]] %[[#bb48]]
; CHECK: %[[#bb59]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb60:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb60]] %[[#bb61:]]
; CHECK: %[[#bb61]] = OpLabel
; CHECK: OpBranch %[[#bb60]]
; CHECK: %[[#bb60]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb62:]] %[[#bb48]]
; CHECK: %[[#bb62]] = OpLabel
; CHECK: OpBranch %[[#bb48]]
; CHECK: %[[#bb48]] = OpLabel
; CHECK: OpReturnValue %[[#]]
; CHECK: OpFunctionEnd
; CHECK: %[[#func_39:]] = OpFunction %[[#void:]] DontInline %[[#]]
; CHECK: %[[#bb60:]] = OpLabel
; CHECK: %[[#func_42:]] = OpFunction %[[#void:]] DontInline %[[#]]
; CHECK: %[[#bb63:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd
; CHECK: %[[#func_41:]] = OpFunction %[[#void:]] None %[[#]]
; CHECK: %[[#bb61:]] = OpLabel
; CHECK: %[[#func_44:]] = OpFunction %[[#void]] None %[[#]]
; CHECK: %[[#bb64:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd

View File

@@ -1,10 +1,9 @@
; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan-compute %s -o - -filetype=obj | spirv-val %}
; static int foo() { return 200; }
;
; int foo() { return 200; }
;
; int process() {
; static int process() {
; int a = 0;
; int b = 0;
; int c = 0;
@@ -20,10 +19,10 @@
; b += 2;
; break;
; case 3:
; {
; b += 3;
; break;
; }
; {
; b += 3;
; break;
; }
; case t:
; b += t;
; case 4:
@@ -31,10 +30,10 @@
; b += 5;
; break;
; case 6: {
; case 7:
; break;}
; case 7:
; break;}
; default:
; break;
; break;
; }
;
; return a + b + c;
@@ -45,198 +44,167 @@
; process();
; }
; CHECK: %[[#func_18:]] = OpFunction %[[#uint:]] DontInline %[[#]]
; CHECK: %[[#bb52:]] = OpLabel
; CHECK: OpReturnValue %[[#]]
; CHECK: OpFunctionEnd
; CHECK: %[[#func_19:]] = OpFunction %[[#uint:]] DontInline %[[#]]
; CHECK: %[[#bb53:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb54:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb55:]] %[[#bb56:]]
; CHECK: %[[#bb55:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb57:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb58:]] %[[#bb59:]]
; CHECK: %[[#bb56:]] = OpLabel
; CHECK: %[[#bb58:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb60:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb61:]] %[[#bb62:]]
; CHECK: %[[#bb59:]] = OpLabel
; CHECK: %[[#bb61:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb63:]] None
; CHECK: OpSwitch %[[#]] %[[#bb64:]] 1 %[[#bb65:]] 2 %[[#bb63:]] 3 %[[#bb66:]] 140 %[[#bb67:]] 4 %[[#bb68:]] 5 %[[#bb69:]] 6 %[[#bb70:]] 7 %[[#bb71:]]
; CHECK: %[[#bb62:]] = OpLabel
; CHECK: %[[#bb64:]] = OpLabel
; CHECK: OpBranch %[[#bb63:]]
; CHECK: %[[#bb65:]] = OpLabel
; CHECK: OpBranch %[[#bb63:]]
; CHECK: %[[#bb66:]] = OpLabel
; CHECK: OpBranch %[[#bb63:]]
; CHECK: %[[#bb67:]] = OpLabel
; CHECK: OpBranch %[[#bb63:]]
; CHECK: %[[#bb68:]] = OpLabel
; CHECK: OpBranch %[[#bb63:]]
; CHECK: %[[#bb69:]] = OpLabel
; CHECK: OpBranch %[[#bb63:]]
; CHECK: %[[#bb70:]] = OpLabel
; CHECK: OpBranch %[[#bb63:]]
; CHECK: %[[#bb71:]] = OpLabel
; CHECK: OpBranch %[[#bb63:]]
; CHECK: %[[#bb63:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb72:]] None
; CHECK: OpSwitch %[[#]] %[[#bb73:]] 1 %[[#bb72:]] 2 %[[#bb74:]] 3 %[[#bb75:]]
; CHECK: %[[#bb73:]] = OpLabel
; CHECK: OpBranch %[[#bb72:]]
; CHECK: %[[#bb74:]] = OpLabel
; CHECK: OpBranch %[[#bb72:]]
; CHECK: %[[#bb75:]] = OpLabel
; CHECK: OpBranch %[[#bb72:]]
; CHECK: %[[#bb72:]] = OpLabel
; CHECK: OpBranch %[[#bb60:]]
; CHECK: %[[#bb60:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb76:]] None
; CHECK: OpSwitch %[[#]] %[[#bb77:]] 1 %[[#bb76:]] 2 %[[#bb78:]]
; CHECK: %[[#bb77:]] = OpLabel
; CHECK: OpBranch %[[#bb76:]]
; CHECK: %[[#bb78:]] = OpLabel
; CHECK: OpBranch %[[#bb76:]]
; CHECK: %[[#bb76:]] = OpLabel
; CHECK: OpBranch %[[#bb57:]]
; CHECK: %[[#bb57:]] = OpLabel
; CHECK: OpBranch %[[#bb54:]]
; CHECK: %[[#bb54:]] = OpLabel
; CHECK: OpReturnValue %[[#]]
; CHECK: OpFunctionEnd
; CHECK: %[[#func_48:]] = OpFunction %[[#void:]] DontInline %[[#]]
; CHECK: %[[#bb79:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd
; CHECK: %[[#func_50:]] = OpFunction %[[#void:]] None %[[#]]
; CHECK: %[[#bb80:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd
; CHECK: %[[#func:]] = OpFunction %[[#]] DontInline %[[#]]
; CHECK: %[[#bb30:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb31:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb32:]] %[[#bb33:]]
; CHECK: %[[#bb33]] = OpLabel
; CHECK: OpUnreachable
; CHECK: %[[#bb32]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb34:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb35:]] %[[#bb36:]]
; CHECK: %[[#bb36]] = OpLabel
; CHECK: OpUnreachable
; CHECK: %[[#bb35]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb37:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb38:]] %[[#bb39:]]
; CHECK: %[[#bb39]] = OpLabel
; CHECK: OpUnreachable
; CHECK: %[[#bb38]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb40:]] None
; CHECK: OpSwitch %[[#]] %[[#bb41:]] 1 %[[#bb42:]] 2 %[[#bb43:]] 3 %[[#bb44:]] 140 %[[#bb45:]] 4 %[[#bb46:]] 5 %[[#bb47:]] 6 %[[#bb48:]] 7 %[[#bb49:]]
; CHECK: %[[#bb49]] = OpLabel
; CHECK: OpBranch %[[#bb40]]
; CHECK: %[[#bb48]] = OpLabel
; CHECK: OpBranch %[[#bb40]]
; CHECK: %[[#bb47]] = OpLabel
; CHECK: OpBranch %[[#bb40]]
; CHECK: %[[#bb46]] = OpLabel
; CHECK: OpBranch %[[#bb40]]
; CHECK: %[[#bb45]] = OpLabel
; CHECK: OpBranch %[[#bb40]]
; CHECK: %[[#bb44]] = OpLabel
; CHECK: OpBranch %[[#bb40]]
; CHECK: %[[#bb43]] = OpLabel
; CHECK: OpBranch %[[#bb40]]
; CHECK: %[[#bb42]] = OpLabel
; CHECK: OpBranch %[[#bb40]]
; CHECK: %[[#bb41]] = OpLabel
; CHECK: OpBranch %[[#bb40]]
; CHECK: %[[#bb40]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb50:]] None
; CHECK: OpSwitch %[[#]] %[[#bb50]] 1 %[[#bb51:]] 2 %[[#bb52:]] 3 %[[#bb53:]]
; CHECK: %[[#bb53]] = OpLabel
; CHECK: OpBranch %[[#bb50]]
; CHECK: %[[#bb52]] = OpLabel
; CHECK: OpBranch %[[#bb50]]
; CHECK: %[[#bb51]] = OpLabel
; CHECK: OpBranch %[[#bb50]]
; CHECK: %[[#bb50]] = OpLabel
; CHECK: OpBranch %[[#bb37]]
; CHECK: %[[#bb37]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb54:]] None
; CHECK: OpSwitch %[[#]] %[[#bb54]] 1 %[[#bb55:]] 2 %[[#bb56:]]
; CHECK: %[[#bb56]] = OpLabel
; CHECK: OpBranch %[[#bb54]]
; CHECK: %[[#bb55]] = OpLabel
; CHECK: OpBranch %[[#bb54]]
; CHECK: %[[#bb54]] = OpLabel
; CHECK: OpBranch %[[#bb34]]
; CHECK: %[[#bb34]] = OpLabel
; CHECK: OpBranch %[[#bb31]]
; CHECK: %[[#bb31]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
target triple = "spirv-unknown-vulkan1.3-compute"
; Function Attrs: convergent noinline norecurse nounwind optnone
define spir_func noundef i32 @_Z3foov() #0 {
; Function Attrs: convergent noinline norecurse
define void @main() #0 {
entry:
%a.i = alloca i32, align 4
%b.i = alloca i32, align 4
%c.i = alloca i32, align 4
%r.i = alloca i32, align 4
%s.i = alloca i32, align 4
%t.i = alloca i32, align 4
%d.i = alloca i32, align 4
%0 = call token @llvm.experimental.convergence.entry()
ret i32 200
}
; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none)
declare token @llvm.experimental.convergence.entry() #1
; Function Attrs: convergent noinline norecurse nounwind optnone
define spir_func noundef i32 @_Z7processv() #0 {
entry:
%0 = call token @llvm.experimental.convergence.entry()
%a = alloca i32, align 4
%b = alloca i32, align 4
%c = alloca i32, align 4
%r = alloca i32, align 4
%s = alloca i32, align 4
%t = alloca i32, align 4
%d = alloca i32, align 4
store i32 0, ptr %a, align 4
store i32 0, ptr %b, align 4
store i32 0, ptr %c, align 4
store i32 20, ptr %r, align 4
store i32 40, ptr %s, align 4
store i32 140, ptr %t, align 4
store i32 5, ptr %d, align 4
%1 = load i32, ptr %d, align 4
switch i32 %1, label %sw.default [
i32 1, label %sw.bb
i32 2, label %sw.bb3
i32 3, label %sw.bb5
i32 140, label %sw.bb7
i32 4, label %sw.bb9
i32 5, label %sw.bb9
i32 6, label %sw.bb11
i32 7, label %sw.bb12
store i32 0, ptr %a.i, align 4
store i32 0, ptr %b.i, align 4
store i32 0, ptr %c.i, align 4
store i32 20, ptr %r.i, align 4
store i32 40, ptr %s.i, align 4
store i32 140, ptr %t.i, align 4
store i32 5, ptr %d.i, align 4
%1 = load i32, ptr %d.i, align 4
switch i32 %1, label %sw.default.i [
i32 1, label %sw.bb.i
i32 2, label %sw.bb3.i
i32 3, label %sw.bb5.i
i32 140, label %sw.bb7.i
i32 4, label %sw.bb9.i
i32 5, label %sw.bb9.i
i32 6, label %sw.bb11.i
i32 7, label %sw.bb12.i
]
sw.bb: ; preds = %entry
%2 = load i32, ptr %b, align 4
%add = add nsw i32 %2, 1
store i32 %add, ptr %b, align 4
%call1 = call spir_func noundef i32 @_Z3foov() #3 [ "convergencectrl"(token %0) ]
%3 = load i32, ptr %c, align 4
%add2 = add nsw i32 %3, %call1
store i32 %add2, ptr %c, align 4
br label %sw.bb3
sw.bb.i:
%2 = load i32, ptr %b.i, align 4
%add.i = add nsw i32 %2, 1
store i32 %add.i, ptr %b.i, align 4
%3 = load i32, ptr %c.i, align 4
%add2.i = add nsw i32 %3, 200
store i32 %add2.i, ptr %c.i, align 4
br label %sw.bb3.i
sw.bb3: ; preds = %entry, %sw.bb
%4 = load i32, ptr %b, align 4
%add4 = add nsw i32 %4, 2
store i32 %add4, ptr %b, align 4
br label %sw.epilog
sw.bb3.i:
%4 = load i32, ptr %b.i, align 4
%add4.i = add nsw i32 %4, 2
store i32 %add4.i, ptr %b.i, align 4
br label %_ZL7processv.exit
sw.bb5: ; preds = %entry
%5 = load i32, ptr %b, align 4
%add6 = add nsw i32 %5, 3
store i32 %add6, ptr %b, align 4
br label %sw.epilog
sw.bb5.i:
%5 = load i32, ptr %b.i, align 4
%add6.i = add nsw i32 %5, 3
store i32 %add6.i, ptr %b.i, align 4
br label %_ZL7processv.exit
sw.bb7: ; preds = %entry
%6 = load i32, ptr %b, align 4
%add8 = add nsw i32 %6, 140
store i32 %add8, ptr %b, align 4
br label %sw.bb9
sw.bb7.i:
%6 = load i32, ptr %b.i, align 4
%add8.i = add nsw i32 %6, 140
store i32 %add8.i, ptr %b.i, align 4
br label %sw.bb9.i
sw.bb9: ; preds = %entry, %entry, %sw.bb7
%7 = load i32, ptr %b, align 4
%add10 = add nsw i32 %7, 5
store i32 %add10, ptr %b, align 4
br label %sw.epilog
sw.bb9.i:
%7 = load i32, ptr %b.i, align 4
%add10.i = add nsw i32 %7, 5
store i32 %add10.i, ptr %b.i, align 4
br label %_ZL7processv.exit
sw.bb11: ; preds = %entry
br label %sw.bb12
sw.bb11.i:
br label %sw.bb12.i
sw.bb12: ; preds = %entry, %sw.bb11
br label %sw.epilog
sw.bb12.i:
br label %_ZL7processv.exit
sw.default: ; preds = %entry
br label %sw.epilog
sw.default.i:
br label %_ZL7processv.exit
sw.epilog: ; preds = %sw.default, %sw.bb12, %sw.bb9, %sw.bb5, %sw.bb3
%8 = load i32, ptr %a, align 4
%9 = load i32, ptr %b, align 4
%add13 = add nsw i32 %8, %9
%10 = load i32, ptr %c, align 4
%add14 = add nsw i32 %add13, %10
ret i32 %add14
}
; Function Attrs: convergent noinline norecurse nounwind optnone
define internal spir_func void @main() #0 {
entry:
%0 = call token @llvm.experimental.convergence.entry()
%call1 = call spir_func noundef i32 @_Z7processv() #3 [ "convergencectrl"(token %0) ]
_ZL7processv.exit:
%8 = load i32, ptr %a.i, align 4
%9 = load i32, ptr %b.i, align 4
%add13.i = add nsw i32 %8, %9
%10 = load i32, ptr %c.i, align 4
%add14.i = add nsw i32 %add13.i, %10
ret void
}
; Function Attrs: convergent norecurse
define void @main.1() #2 {
entry:
call void @main()
ret void
}
declare token @llvm.experimental.convergence.entry() #1
attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
attributes #0 = { convergent noinline norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
attributes #1 = { convergent nocallback nofree nosync nounwind willreturn memory(none) }
attributes #2 = { convergent norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
attributes #3 = { convergent }
!llvm.module.flags = !{!0, !1, !2}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 4, !"dx.disable_optimizations", i32 1}
!2 = !{i32 7, !"frame-pointer", i32 2}

View File

@@ -45,54 +45,54 @@
; }
; CHECK: %[[#func_15:]] = OpFunction %[[#uint:]] DontInline %[[#]]
; CHECK: %[[#bb35:]] = OpLabel
; CHECK: %[[#bb36:]] = OpLabel
; CHECK: OpReturnValue %[[#]]
; CHECK: OpFunctionEnd
; CHECK: %[[#func_16:]] = OpFunction %[[#void:]] DontInline %[[#]]
; CHECK: %[[#bb36:]] = OpLabel
; CHECK: OpBranch %[[#bb37:]]
; CHECK: %[[#bb37:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb38:]] %[[#bb39:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb40:]] %[[#bb38:]]
; CHECK: %[[#bb40:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb41:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb41:]] %[[#bb42:]]
; CHECK: %[[#bb42:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb43:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb43:]] %[[#bb44:]]
; CHECK: %[[#bb44:]] = OpLabel
; CHECK: OpBranch %[[#bb43:]]
; CHECK: %[[#bb43:]] = OpLabel
; CHECK: OpBranch %[[#bb41:]]
; CHECK: %[[#bb41:]] = OpLabel
; CHECK: OpBranch %[[#bb39:]]
; CHECK: %[[#bb39:]] = OpLabel
; CHECK: OpBranch %[[#bb37:]]
; CHECK: %[[#bb38:]] = OpLabel
; CHECK: OpBranch %[[#bb45:]]
; CHECK: %[[#bb45:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb46:]] %[[#bb47:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb46:]] %[[#bb48:]]
; CHECK: %[[#bb48:]] = OpLabel
; CHECK: OpBranch %[[#bb49:]]
; CHECK: %[[#bb49:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb50:]] %[[#bb51:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb51:]] %[[#bb50:]]
; CHECK: %[[#bb51:]] = OpLabel
; CHECK: OpBranch %[[#bb49:]]
; CHECK: %[[#bb50:]] = OpLabel
; CHECK: OpBranch %[[#bb47:]]
; CHECK: %[[#bb47:]] = OpLabel
; CHECK: OpBranch %[[#bb45:]]
; CHECK: %[[#bb46:]] = OpLabel
; CHECK: OpBranch %[[#bb38:]]
; CHECK: %[[#bb38]] = OpLabel
; CHECK: OpLoopMerge %[[#bb39:]] %[[#bb40:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb41:]] %[[#bb39]]
; CHECK: %[[#bb39]] = OpLabel
; CHECK: OpBranch %[[#bb42:]]
; CHECK: %[[#bb42]] = OpLabel
; CHECK: OpLoopMerge %[[#bb43:]] %[[#bb44:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb43]] %[[#bb45:]]
; CHECK: %[[#bb45]] = OpLabel
; CHECK: OpBranch %[[#bb46:]]
; CHECK: %[[#bb46]] = OpLabel
; CHECK: OpLoopMerge %[[#bb47:]] %[[#bb48:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb48]] %[[#bb47]]
; CHECK: %[[#bb47]] = OpLabel
; CHECK: OpBranch %[[#bb44]]
; CHECK: %[[#bb44]] = OpLabel
; CHECK: OpBranch %[[#bb42]]
; CHECK: %[[#bb48]] = OpLabel
; CHECK: OpBranch %[[#bb46]]
; CHECK: %[[#bb43]] = OpLabel
; CHECK: %[[#bb41]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb49:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb49]] %[[#bb50:]]
; CHECK: %[[#bb50]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb51:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb51]] %[[#bb52:]]
; CHECK: %[[#bb52]] = OpLabel
; CHECK: OpBranch %[[#bb51]]
; CHECK: %[[#bb51]] = OpLabel
; CHECK: OpBranch %[[#bb49]]
; CHECK: %[[#bb49]] = OpLabel
; CHECK: OpBranch %[[#bb40]]
; CHECK: %[[#bb40]] = OpLabel
; CHECK: OpBranch %[[#bb38]]
; CHECK: OpFunctionEnd
; CHECK: %[[#func_33:]] = OpFunction %[[#void:]] None %[[#]]
; CHECK: %[[#bb52:]] = OpLabel
; CHECK: %[[#func_34:]] = OpFunction %[[#void]] None %[[#]]
; CHECK: %[[#bb53:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
target triple = "spirv-unknown-vulkan1.3-compute"

View File

@@ -25,29 +25,29 @@
; CHECK: %[[#func_12:]] = OpFunction %[[#void:]] DontInline %[[#]]
; CHECK: %[[#bb39:]] = OpLabel
; CHECK: OpBranch %[[#bb40:]]
; CHECK: %[[#bb40:]] = OpLabel
; CHECK: %[[#bb40]] = OpLabel
; CHECK: OpLoopMerge %[[#bb41:]] %[[#bb42:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb43:]] %[[#bb41:]]
; CHECK: %[[#bb43:]] = OpLabel
; CHECK: OpBranch %[[#bb44:]]
; CHECK: %[[#bb44:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb45:]] %[[#bb46:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb47:]] %[[#bb45:]]
; CHECK: %[[#bb47:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb48:]] %[[#bb49:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb49:]] %[[#bb48:]]
; CHECK: %[[#bb49:]] = OpLabel
; CHECK: OpBranch %[[#bb47:]]
; CHECK: %[[#bb48:]] = OpLabel
; CHECK: OpBranch %[[#bb46:]]
; CHECK: %[[#bb46:]] = OpLabel
; CHECK: OpBranch %[[#bb44:]]
; CHECK: %[[#bb45:]] = OpLabel
; CHECK: OpBranch %[[#bb42:]]
; CHECK: %[[#bb42:]] = OpLabel
; CHECK: OpBranch %[[#bb40:]]
; CHECK: %[[#bb41:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb43:]] %[[#bb41]]
; CHECK: %[[#bb41]] = OpLabel
; CHECK: OpReturn
; CHECK: %[[#bb43]] = OpLabel
; CHECK: OpBranch %[[#bb44:]]
; CHECK: %[[#bb44]] = OpLabel
; CHECK: OpLoopMerge %[[#bb45:]] %[[#bb46:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb47:]] %[[#bb45]]
; CHECK: %[[#bb45]] = OpLabel
; CHECK: OpBranch %[[#bb42]]
; CHECK: %[[#bb42]] = OpLabel
; CHECK: OpBranch %[[#bb40]]
; CHECK: %[[#bb47]] = OpLabel
; CHECK: OpLoopMerge %[[#bb48:]] %[[#bb49:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb49]] %[[#bb48]]
; CHECK: %[[#bb48]] = OpLabel
; CHECK: OpBranch %[[#bb46]]
; CHECK: %[[#bb46]] = OpLabel
; CHECK: OpBranch %[[#bb44]]
; CHECK: %[[#bb49]] = OpLabel
; CHECK: OpBranch %[[#bb47]]
; CHECK: OpFunctionEnd
; CHECK: %[[#func_37:]] = OpFunction %[[#void:]] None %[[#]]
; CHECK: %[[#bb50:]] = OpLabel

View File

@@ -43,23 +43,26 @@
; CHECK: %[[#bb20:]] = OpLabel
; CHECK: OpReturnValue %[[#]]
; CHECK: OpFunctionEnd
; CHECK: %[[#func_12:]] = OpFunction %[[#void:]] DontInline %[[#]]
; CHECK: %[[#bb21:]] = OpLabel
; CHECK: OpBranch %[[#bb22:]]
; CHECK: %[[#bb22:]] = OpLabel
; CHECK: %[[#bb22]] = OpLabel
; CHECK: OpLoopMerge %[[#bb23:]] %[[#bb24:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb24:]] %[[#bb23:]]
; CHECK: %[[#bb24:]] = OpLabel
; CHECK: OpBranch %[[#bb22:]]
; CHECK: %[[#bb23:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb24]] %[[#bb23]]
; CHECK: %[[#bb23]] = OpLabel
; CHECK: OpBranch %[[#bb25:]]
; CHECK: %[[#bb25:]] = OpLabel
; CHECK: %[[#bb25]] = OpLabel
; CHECK: OpLoopMerge %[[#bb26:]] %[[#bb27:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb26:]] %[[#bb27:]]
; CHECK: %[[#bb27:]] = OpLabel
; CHECK: OpBranch %[[#bb25:]]
; CHECK: %[[#bb26:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb26]] %[[#bb27]]
; CHECK: %[[#bb27]] = OpLabel
; CHECK: OpBranch %[[#bb25]]
; CHECK: %[[#bb26]] = OpLabel
; CHECK-NEXT: OpUnreachable
; CHECK: %[[#bb24]] = OpLabel
; CHECK: OpBranch %[[#bb22]]
; CHECK: OpFunctionEnd
; CHECK: %[[#func_18:]] = OpFunction %[[#void:]] None %[[#]]
; CHECK: %[[#bb28:]] = OpLabel
; CHECK: OpReturn

View File

@@ -21,103 +21,122 @@
; }
; }
; CHECK: %[[#func_10:]] = OpFunction %[[#void:]] DontInline %[[#]]
; CHECK: %[[#bb54:]] = OpLabel
; CHECK: OpBranch %[[#bb55:]]
; CHECK: %[[#bb55:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb56:]] %[[#bb57:]] None
; CHECK: OpBranch %[[#bb58:]]
; CHECK: %[[#bb58:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb59:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb60:]] %[[#bb59:]]
; CHECK: %[[#bb60:]] = OpLabel
; CHECK: OpBranch %[[#bb59:]]
; CHECK: %[[#bb59:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb57:]] %[[#bb56:]]
; CHECK: %[[#bb57:]] = OpLabel
; CHECK: OpBranch %[[#bb55:]]
; CHECK: %[[#bb56:]] = OpLabel
; CHECK: OpBranch %[[#bb61:]]
; CHECK: %[[#bb61:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb62:]] %[[#bb63:]] None
; CHECK: OpBranch %[[#bb64:]]
; CHECK: %[[#bb64:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb65:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb65:]] %[[#bb66:]]
; CHECK: %[[#bb66:]] = OpLabel
; CHECK: OpBranch %[[#bb65:]]
; CHECK: %[[#bb65:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb63:]] %[[#bb62:]]
; CHECK: %[[#bb63:]] = OpLabel
; CHECK: OpBranch %[[#bb61:]]
; CHECK: %[[#bb62:]] = OpLabel
; CHECK: OpBranch %[[#bb67:]]
; CHECK: %[[#bb67:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb68:]] %[[#bb69:]] None
; CHECK: OpBranch %[[#bb70:]]
; CHECK: %[[#bb70:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb71:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb72:]] %[[#bb71:]]
; CHECK: %[[#bb72:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb73:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb74:]] %[[#bb75:]]
; CHECK: %[[#bb74:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb76:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb76:]] %[[#bb77:]]
; CHECK: %[[#bb75:]] = OpLabel
; CHECK: %[[#bb77:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb76:]] %[[#bb78:]]
; CHECK: %[[#bb78:]] = OpLabel
; CHECK: OpBranch %[[#bb76:]]
; CHECK: %[[#bb76:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb79:]] %[[#bb73:]]
; CHECK: %[[#bb79:]] = OpLabel
; CHECK: OpBranch %[[#bb73:]]
; CHECK: %[[#bb73:]] = OpLabel
; CHECK: OpBranch %[[#bb71:]]
; CHECK: %[[#bb71:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb69:]] %[[#bb68:]]
; CHECK: %[[#bb69:]] = OpLabel
; CHECK: OpBranch %[[#bb67:]]
; CHECK: %[[#bb68:]] = OpLabel
; CHECK: OpBranch %[[#bb80:]]
; CHECK: %[[#bb80:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb81:]] %[[#bb82:]] None
; CHECK: OpBranch %[[#bb83:]]
; CHECK: %[[#bb83:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb84:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb85:]] %[[#bb86:]]
; CHECK: %[[#bb85:]] = OpLabel
; CHECK: OpBranch %[[#bb84:]]
; CHECK: %[[#bb86:]] = OpLabel
; CHECK: OpBranch %[[#bb84:]]
; CHECK: %[[#bb84:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb82:]] %[[#bb81:]]
; CHECK: %[[#bb82:]] = OpLabel
; CHECK: OpBranch %[[#bb80:]]
; CHECK: %[[#bb81:]] = OpLabel
; CHECK: OpBranch %[[#bb87:]]
; CHECK: %[[#func_11:]] = OpFunction %[[#void:]] DontInline %[[#]]
; CHECK: %[[#bb87:]] = OpLabel
; CHECK: OpLoopMerge %[[#bb88:]] %[[#bb89:]] None
; CHECK: OpBranch %[[#bb90:]]
; CHECK: %[[#bb90:]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb91:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb92:]] %[[#bb91:]]
; CHECK: %[[#bb92:]] = OpLabel
; CHECK: OpBranch %[[#bb88:]]
; CHECK: %[[#bb88]] = OpLabel
; CHECK: OpLoopMerge %[[#bb89:]] %[[#bb90:]] None
; CHECK: OpBranch %[[#bb91:]]
; CHECK: %[[#bb91:]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb89:]] %[[#bb88:]]
; CHECK: %[[#bb89:]] = OpLabel
; CHECK: OpBranch %[[#bb87:]]
; CHECK: %[[#bb88:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd
; CHECK: %[[#func_52:]] = OpFunction %[[#void:]] None %[[#]]
; CHECK: %[[#bb93:]] = OpLabel
; CHECK: %[[#bb91]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb92:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb93:]] %[[#bb94:]]
; CHECK: %[[#bb94]] = OpLabel
; CHECK: OpBranch %[[#bb92]]
; CHECK: %[[#bb93]] = OpLabel
; CHECK: OpBranch %[[#bb92]]
; CHECK: %[[#bb92]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb90]] %[[#bb89]]
; CHECK: %[[#bb89]] = OpLabel
; CHECK: OpBranch %[[#bb95:]]
; CHECK: %[[#bb95]] = OpLabel
; CHECK: OpLoopMerge %[[#bb96:]] %[[#bb97:]] None
; CHECK: OpBranch %[[#bb98:]]
; CHECK: %[[#bb98]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb99:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb100:]] %[[#bb101:]]
; CHECK: %[[#bb101]] = OpLabel
; CHECK: OpBranch %[[#bb99]]
; CHECK: %[[#bb100]] = OpLabel
; CHECK: OpBranch %[[#bb99]]
; CHECK: %[[#bb99]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb97]] %[[#bb96]]
; CHECK: %[[#bb96]] = OpLabel
; CHECK: OpBranch %[[#bb102:]]
; CHECK: %[[#bb102]] = OpLabel
; CHECK: OpLoopMerge %[[#bb103:]] %[[#bb104:]] None
; CHECK: OpBranch %[[#bb105:]]
; CHECK: %[[#bb105]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb106:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb107:]] %[[#bb108:]]
; CHECK: %[[#bb108]] = OpLabel
; CHECK: OpBranch %[[#bb106]]
; CHECK: %[[#bb107]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb109:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb110:]] %[[#bb109]]
; CHECK: %[[#bb110]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb111:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb112:]] %[[#bb113:]]
; CHECK: %[[#bb113]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb114:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb114]] %[[#bb115:]]
; CHECK: %[[#bb115]] = OpLabel
; CHECK: OpBranch %[[#bb114]]
; CHECK: %[[#bb114]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb116:]] %[[#bb111]]
; CHECK: %[[#bb116]] = OpLabel
; CHECK: OpBranch %[[#bb111]]
; CHECK: %[[#bb112]] = OpLabel
; CHECK: OpBranch %[[#bb111]]
; CHECK: %[[#bb111]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb109]] %[[#bb117:]]
; CHECK: %[[#bb117]] = OpLabel
; CHECK: OpBranch %[[#bb109]]
; CHECK: %[[#bb109]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb106]] %[[#bb118:]]
; CHECK: %[[#bb118]] = OpLabel
; CHECK: OpBranch %[[#bb106]]
; CHECK: %[[#bb106]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb119:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb119]] %[[#bb120:]]
; CHECK: %[[#bb120]] = OpLabel
; CHECK: %[[#bb119]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb104]] %[[#bb103]]
; CHECK: %[[#bb103]] = OpLabel
; CHECK: OpBranch %[[#bb121:]]
; CHECK: %[[#bb121]] = OpLabel
; CHECK: OpLoopMerge %[[#bb122:]] %[[#bb123:]] None
; CHECK: OpBranch %[[#bb124:]]
; CHECK: %[[#bb124]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb125:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb126:]] %[[#bb127:]]
; CHECK: %[[#bb127]] = OpLabel
; CHECK: OpBranch %[[#bb125]]
; CHECK: %[[#bb126]] = OpLabel
; CHECK: OpBranch %[[#bb125]]
; CHECK: %[[#bb125]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb123]] %[[#bb122]]
; CHECK: %[[#bb122]] = OpLabel
; CHECK: OpBranch %[[#bb128:]]
; CHECK: %[[#bb128]] = OpLabel
; CHECK: OpLoopMerge %[[#bb129:]] %[[#bb130:]] None
; CHECK: OpBranch %[[#bb131:]]
; CHECK: %[[#bb131]] = OpLabel
; CHECK: OpSelectionMerge %[[#bb132:]] None
; CHECK: OpBranchConditional %[[#]] %[[#bb133:]] %[[#bb134:]]
; CHECK: %[[#bb134]] = OpLabel
; CHECK: OpBranch %[[#bb132]]
; CHECK: %[[#bb133]] = OpLabel
; CHECK: OpBranch %[[#bb132]]
; CHECK: %[[#bb132]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#bb130]] %[[#bb129]]
; CHECK: %[[#bb129]] = OpLabel
; CHECK: OpReturn
; CHECK: %[[#bb130]] = OpLabel
; CHECK: OpBranch %[[#bb128]]
; CHECK: %[[#bb123]] = OpLabel
; CHECK: OpBranch %[[#bb121]]
; CHECK: %[[#bb104]] = OpLabel
; CHECK: OpBranch %[[#bb102]]
; CHECK: %[[#bb97]] = OpLabel
; CHECK: OpBranch %[[#bb95]]
; CHECK: %[[#bb90]] = OpLabel
; CHECK: OpBranch %[[#bb88]]
; CHECK: OpFunctionEnd
; CHECK: %[[#func_85:]] = OpFunction %[[#void]] None %[[#]]
; CHECK: %[[#bb135:]] = OpLabel
; CHECK: OpReturn
; CHECK: OpFunctionEnd
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
target triple = "spirv-unknown-vulkan1.3-compute"

View File

@@ -38,18 +38,18 @@ entry:
%b = alloca i32, align 4
br i1 true, label %cond1_true, label %cond1_false
; CHECK: %[[#cond1_true]] = OpLabel
; CHECK: OpStore %[[#reg_0]] %[[#]]
; CHECK: OpBranch %[[#cond1_merge]]
cond1_true:
%2 = load i32, ptr %a, align 4
br label %cond1_merge
; CHECK: %[[#cond1_false]] = OpLabel
; CHECK: OpStore %[[#reg_0]] %[[#]]
; CHECK: OpBranch %[[#cond1_merge]]
cond1_false:
%3 = load i32, ptr %b, align 4
%2 = load i32, ptr %b, align 4
br label %cond1_merge
; CHECK: %[[#cond1_true]] = OpLabel
; CHECK: OpStore %[[#reg_0]] %[[#]]
; CHECK: OpBranch %[[#cond1_merge]]
cond1_true:
%3 = load i32, ptr %a, align 4
br label %cond1_merge
; CHECK: %[[#cond1_merge]] = OpLabel
@@ -58,7 +58,7 @@ cond1_false:
; CHECK: OpSelectionMerge %[[#cond2_merge:]] None
; CHECK: OpBranchConditional %[[#cond]] %[[#cond2_true:]] %[[#cond2_merge]]
cond1_merge:
%cond = phi i32 [ %2, %cond1_true ], [ %3, %cond1_false ]
%cond = phi i32 [ %3, %cond1_true ], [ %2, %cond1_false ]
%tobool1 = icmp ne i32 %cond, 0
br i1 %tobool1, label %cond2_true, label %cond2_merge
@@ -76,14 +76,6 @@ cond2_merge:
%call2 = call spir_func noundef i32 @fn() #4 [ "convergencectrl"(token %0) ]
br i1 true, label %cond3_true, label %cond3_false
; CHECK: %[[#cond3_true]] = OpLabel
; CHECK: OpFunctionCall
; CHECK: OpStore %[[#reg_1]] %[[#]]
; CHECK: OpBranch %[[#cond3_merge]]
cond3_true:
%call5 = call spir_func noundef i32 @fn1() #4 [ "convergencectrl"(token %0) ]
br label %cond3_merge
; CHECK: %[[#cond3_false]] = OpLabel
; CHECK: OpFunctionCall
; CHECK: OpStore %[[#reg_1]] %[[#]]
@@ -92,6 +84,14 @@ cond3_false:
%call7 = call spir_func noundef i32 @fn2() #4 [ "convergencectrl"(token %0) ]
br label %cond3_merge
; CHECK: %[[#cond3_true]] = OpLabel
; CHECK: OpFunctionCall
; CHECK: OpStore %[[#reg_1]] %[[#]]
; CHECK: OpBranch %[[#cond3_merge]]
cond3_true:
%call5 = call spir_func noundef i32 @fn1() #4 [ "convergencectrl"(token %0) ]
br label %cond3_merge
; CHECK: %[[#cond3_merge]] = OpLabel
; CHECK: %[[#tmp:]] = OpLoad %[[#]] %[[#reg_1]]
; CHECK: %[[#cond:]] = OpINotEqual %[[#]] %[[#tmp]] %[[#]]

View File

@@ -21,7 +21,7 @@ entry:
; Here a the loop header had to be split in two:
; - 1 header for the loop
; - 1 header for the condition.
; In SPIR-V, a loop header cannot directly
; CHECK: %[[#do_header:]] = OpLabel
; CHECK: OpLoopMerge %[[#do_merge:]] %[[#do_latch:]] None
; CHECK: OpBranch %[[#new_header:]]
@@ -34,27 +34,21 @@ do_header:
store i32 0, ptr %var
br i1 true, label %if.then, label %if.end
; CHECK: %[[#if_then]] = OpLabel
; CHECK: OpBranch %[[#if_merge]]
if.then:
store i32 0, ptr %var
br label %do_latch
; CHECK: %[[#if_end]] = OpLabel
; CHECK: OpBranch %[[#if_merge]]
if.end:
store i32 0, ptr %var
br label %do_latch
; CHECK: %[[#if_then]] = OpLabel
; CHECK: OpBranch %[[#if_merge]]
if.then:
store i32 0, ptr %var
br label %do_latch
; CHECK: %[[#if_merge]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#do_latch]] %[[#do_merge]]
; CHECK: %[[#do_latch]] = OpLabel
; CHECK: OpBranch %[[#do_header]]
do_latch:
store i32 0, ptr %var
br i1 true, label %do_header, label %do.end
; CHECK: %[[#do_merge]] = OpLabel
; CHECK: OpBranch %[[#do2_header:]]
do.end:
@@ -80,12 +74,6 @@ do3_header:
; CHECK: %[[#do3_body]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#do3_continue]] %[[#do3_merge]]
; CHECK: %[[#do3_continue]] = OpLabel
; CHECK: OpBranch %[[#do3_header]]
do3_continue:
store i32 0, ptr %var
br i1 true, label %do3_header, label %do3_merge
; CHECK: %[[#do3_merge]] = OpLabel
; CHECK: OpBranch %[[#do2_new_latch:]]
do3_merge:
@@ -95,16 +83,28 @@ do3_merge:
; CHECK: %[[#do2_new_latch]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#do2_continue]] %[[#do2_merge]]
; CHECK: %[[#do2_merge]] = OpLabel
; CHECK: OpReturn
do2_merge:
ret void
; CHECK: %[[#do2_continue]] = OpLabel
; CHECK: OpBranch %[[#do2_header]]
do2_continue:
store i32 0, ptr %var
br i1 true, label %do2_header, label %do2_merge
; CHECK: %[[#do2_merge]] = OpLabel
; CHECK: OpReturn
do2_merge:
ret void
; CHECK: %[[#do3_continue]] = OpLabel
; CHECK: OpBranch %[[#do3_header]]
do3_continue:
store i32 0, ptr %var
br i1 true, label %do3_header, label %do3_merge
; CHECK: %[[#do_latch]] = OpLabel
; CHECK: OpBranch %[[#do_header]]
do_latch:
store i32 0, ptr %var
br i1 true, label %do_header, label %do.end
}
declare token @llvm.experimental.convergence.entry() #1

View File

@@ -37,11 +37,6 @@ do3_header:
; CHECK: %[[#do3_cond]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#do3_continue]] %[[#do3_merge]]
; CHECK: %[[#do3_continue]] = OpLabel
; CHECK: OpBranch %[[#do3_header]]
do3_continue:
store i32 0, ptr %var
br i1 true, label %do3_header, label %do3_merge
; CHECK: %[[#do3_merge]] = OpLabel
; CHECK: OpBranch %[[#do2_cond:]]
@@ -51,30 +46,38 @@ do3_merge:
; CHECK: %[[#do2_cond]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#do2_continue]] %[[#do2_merge]]
; CHECK: %[[#do2_continue]] = OpLabel
; CHECK: OpBranch %[[#do2_header]]
do2_continue:
store i32 0, ptr %var
br i1 true, label %do2_header, label %do2_merge
; CHECK: %[[#do2_merge]] = OpLabel
; CHECK: OpBranch %[[#do1_cond:]]
; CHECK: %[[#do1_cond]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#do1_continue]] %[[#do1_merge]]
do2_merge:
store i32 0, ptr %var
br label %do1_continue
; CHECK: %[[#do1_cond]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#do1_continue]] %[[#do1_merge]]
; CHECK: %[[#do1_merge]] = OpLabel
; CHECK: OpReturn
do1_merge:
ret void
; CHECK: %[[#do1_continue]] = OpLabel
; CHECK: OpBranch %[[#do1_header]]
do1_continue:
store i32 0, ptr %var
br i1 true, label %do1_header, label %do1_merge
; CHECK: %[[#do1_merge]] = OpLabel
; CHECK: OpReturn
do1_merge:
ret void
; CHECK: %[[#do2_continue]] = OpLabel
; CHECK: OpBranch %[[#do2_header]]
do2_continue:
store i32 0, ptr %var
br i1 true, label %do2_header, label %do2_merge
; CHECK: %[[#do3_continue]] = OpLabel
; CHECK: OpBranch %[[#do3_header]]
do3_continue:
store i32 0, ptr %var
br i1 true, label %do3_header, label %do3_merge
}
declare token @llvm.experimental.convergence.entry() #1

View File

@@ -24,19 +24,14 @@ entry:
; CHECK: %[[#do1_header]] = OpLabel
; CHECK: OpLoopMerge %[[#do1_merge:]] %[[#do1_continue:]] None
; CHECK: OpBranch %[[#do1_cond:]]
; CHECK: %[[#do1_cond]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#do1_continue]] %[[#do1_merge]]
do1_header:
%1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ]
store i32 0, ptr %var
br label %do1_continue
; CHECK: %[[#do1_cond]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#do1_continue]] %[[#do1_merge]]
; CHECK: %[[#do1_continue]] = OpLabel
; CHECK: OpBranch %[[#do1_header]]
do1_continue:
store i32 0, ptr %var
br i1 true, label %do1_header, label %do1_merge
; CHECK: %[[#do1_merge]] = OpLabel
; CHECK: OpBranch %[[#do2_header:]]
do1_merge:
@@ -53,11 +48,6 @@ do2_header:
; CHECK: %[[#do2_cond]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#do2_continue]] %[[#do2_merge]]
; CHECK: %[[#do2_continue]] = OpLabel
; CHECK: OpBranch %[[#do2_header]]
do2_continue:
store i32 0, ptr %var
br i1 true, label %do2_header, label %do2_merge
; CHECK: %[[#do2_merge]] = OpLabel
; CHECK: OpBranch %[[#do3_header:]]
@@ -75,16 +65,29 @@ do3_header:
; CHECK: %[[#do3_cond]] = OpLabel
; CHECK: OpBranchConditional %[[#]] %[[#do3_continue]] %[[#do3_merge]]
; CHECK: %[[#do3_merge]] = OpLabel
; CHECK: OpReturn
do3_merge:
ret void
; CHECK: %[[#do3_continue]] = OpLabel
; CHECK: OpBranch %[[#do3_header]]
do3_continue:
store i32 0, ptr %var
br i1 true, label %do3_header, label %do3_merge
; CHECK: %[[#do3_merge]] = OpLabel
; CHECK: OpReturn
do3_merge:
ret void
; CHECK: %[[#do2_continue]] = OpLabel
; CHECK: OpBranch %[[#do2_header]]
do2_continue:
store i32 0, ptr %var
br i1 true, label %do2_header, label %do2_merge
; CHECK: %[[#do1_continue]] = OpLabel
; CHECK: OpBranch %[[#do1_header]]
do1_continue:
store i32 0, ptr %var
br i1 true, label %do1_header, label %do1_merge
}

View File

@@ -17,16 +17,12 @@ define internal spir_func void @main() #3 {
; CHECK: OpSelectionMerge %[[#merge:]] None
; CHECK: OpBranchConditional %[[#]] %[[#new_header:]] %[[#unreachable:]]
; CHECK: %[[#new_header]] = OpLabel
; CHECK: OpSelectionMerge %[[#new_merge:]] None
; CHECK: OpBranchConditional %[[#]] %[[#taint_true_merge:]] %[[#br_false:]]
; CHECK: %[[#unreachable]] = OpLabel
; CHECK-NEXT: OpUnreachable
; CHECK: %[[#taint_true_merge]] = OpLabel
; CHECK: OpStore %[[#switch_0]] %[[#int_1]]
; CHECK: OpBranch %[[#new_merge]]
; CHECK: %[[#new_header]] = OpLabel
; CHECK: OpSelectionMerge %[[#new_merge:]] None
; CHECK: OpBranchConditional %[[#]] %[[#taint_true_merge:]] %[[#br_false:]]
; CHECK: %[[#br_false]] = OpLabel
; CHECK-DAG: OpStore %[[#switch_1]] %[[#int_0]]
@@ -47,6 +43,10 @@ define internal spir_func void @main() #3 {
; CHECK: OpStore %[[#switch_0]] %[[#int_1]]
; CHECK: OpBranch %[[#new_merge]]
; CHECK: %[[#taint_true_merge]] = OpLabel
; CHECK: OpStore %[[#switch_0]] %[[#int_1]]
; CHECK: OpBranch %[[#new_merge]]
; CHECK: %[[#new_merge]] = OpLabel
; CHECK: %[[#tmp:]] = OpLoad %[[#]] %[[#switch_0]]
; CHECK: %[[#cond:]] = OpIEqual %[[#]] %[[#int_0]] %[[#tmp]]

View File

@@ -43,14 +43,6 @@ header:
%2 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ]
br i1 true, label %left, label %right
; CHECK: %[[#left]] = OpLabel
; CHECK-DAG: OpStore %[[#switch_0]] %[[#int_0]]
; CHECK-DAG: OpStore %[[#variable]] %[[#int_1]]
; CHECK: OpBranchConditional %[[#]] %[[#inner_merge]] %[[#left_next:]]
left:
store i32 1, ptr %var
br i1 true, label %merge, label %left_next
; CHECK: %[[#right]] = OpLabel
; CHECK-DAG: OpStore %[[#switch_0]] %[[#int_0]]
; CHECK-DAG: OpStore %[[#variable]] %[[#int_2]]
@@ -59,14 +51,6 @@ right:
store i32 2, ptr %var
br i1 true, label %merge, label %right_next
; CHECK: %[[#left_next]] = OpLabel
; CHECK-DAG: OpStore %[[#switch_0]] %[[#int_1]]
; CHECK-DAG: OpStore %[[#variable]] %[[#int_3]]
; CHECK: OpBranch %[[#inner_merge]]
left_next:
store i32 3, ptr %var
br label %continue
; CHECK: %[[#right_next]] = OpLabel
; CHECK-DAG: OpStore %[[#switch_0]] %[[#int_1]]
; CHECK-DAG: OpStore %[[#variable]] %[[#int_4]]
@@ -75,6 +59,22 @@ right_next:
store i32 4, ptr %var
br label %continue
; CHECK: %[[#left]] = OpLabel
; CHECK-DAG: OpStore %[[#switch_0]] %[[#int_0]]
; CHECK-DAG: OpStore %[[#variable]] %[[#int_1]]
; CHECK: OpBranchConditional %[[#]] %[[#inner_merge]] %[[#left_next:]]
left:
store i32 1, ptr %var
br i1 true, label %merge, label %left_next
; CHECK: %[[#left_next]] = OpLabel
; CHECK-DAG: OpStore %[[#switch_0]] %[[#int_1]]
; CHECK-DAG: OpStore %[[#variable]] %[[#int_3]]
; CHECK: OpBranch %[[#inner_merge]]
left_next:
store i32 3, ptr %var
br label %continue
; CHECK: %[[#inner_merge]] = OpLabel
; CHECK: %[[#tmp:]] = OpLoad %[[#]] %[[#switch_0]]
; CHECK: %[[#cond:]] = OpIEqual %[[#]] %[[#int_0]] %[[#tmp]]

View File

@@ -22,6 +22,11 @@ while.cond:
%cmp = icmp ne i32 %2, 0
br i1 %cmp, label %while.body, label %while.end
; CHECK: %[[#while_end]] = OpLabel
; CHECK-NEXT: OpReturn
while.end:
ret void
; CHECK: %[[#while_body]] = OpLabel
; CHECK: OpBranch %[[#while_cond]]
while.body:
@@ -29,10 +34,6 @@ while.body:
store i32 %3, ptr %idx, align 4
br label %while.cond
; CHECK: %[[#while_end]] = OpLabel
; CHECK-NEXT: OpReturn
while.end:
ret void
}
declare token @llvm.experimental.convergence.entry() #2

View File

@@ -39,11 +39,11 @@ while.body:
i32 5, label %sw.bb2
]
; CHECK: %[[#case_1]] = OpLabel
; CHECK: %[[#case_5]] = OpLabel
; CHECK: OpStore %[[#reg_0]] %[[#]]
; CHECK: OpBranch %[[#switch_end]]
sw.bb:
store i32 1, ptr %a, align 4
sw.bb2:
store i32 5, ptr %a, align 4
br label %while.end
; CHECK: %[[#case_2]] = OpLabel
@@ -53,11 +53,11 @@ sw.bb1:
store i32 3, ptr %a, align 4
br label %while.end
; CHECK: %[[#case_5]] = OpLabel
; CHECK: %[[#case_1]] = OpLabel
; CHECK: OpStore %[[#reg_0]] %[[#]]
; CHECK: OpBranch %[[#switch_end]]
sw.bb2:
store i32 5, ptr %a, align 4
sw.bb:
store i32 1, ptr %a, align 4
br label %while.end
; CHECK: %[[#switch_end]] = OpLabel

View File

@@ -15,6 +15,6 @@ set(LLVM_LINK_COMPONENTS
add_llvm_target_unittest(SPIRVTests
SPIRVConvergenceRegionAnalysisTests.cpp
SPIRVSortBlocksTests.cpp
SPIRVAPITest.cpp
)
)

View File

@@ -0,0 +1,389 @@
//===- SPIRVSortBlocksTests.cpp ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "SPIRVUtils.h"
#include "llvm/Analysis/DominanceFrontier.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassInstrumentation.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/TypedPointerType.h"
#include "llvm/Support/SourceMgr.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <queue>
using namespace llvm;
using namespace llvm::SPIRV;
class SPIRVSortBlocksTest : public testing::Test {
protected:
void TearDown() override { M.reset(); }
bool run(StringRef Assembly) {
assert(M == nullptr &&
"Calling runAnalysis multiple times is unsafe. See getAnalysis().");
SMDiagnostic Error;
M = parseAssemblyString(Assembly, Error, Context);
assert(M && "Bad assembly. Bad test?");
llvm::Function *F = M->getFunction("main");
return sortBlocks(*F);
}
void checkBasicBlockOrder(std::vector<const char *> &&Expected) {
llvm::Function *F = M->getFunction("main");
auto It = F->begin();
for (const char *Name : Expected) {
ASSERT_TRUE(It != F->end())
<< "Expected block \"" << Name
<< "\" but reached the end of the function instead.";
ASSERT_TRUE(It->getName() == Name)
<< "Error: expected block \"" << Name << "\" got \"" << It->getName()
<< "\"";
It++;
}
ASSERT_TRUE(It == F->end())
<< "No more blocks were expected, but function has more.";
}
protected:
LLVMContext Context;
std::unique_ptr<Module> M;
};
TEST_F(SPIRVSortBlocksTest, DefaultRegion) {
StringRef Assembly = R"(
define void @main() convergent "hlsl.numthreads"="4,8,16" "hlsl.shader"="compute" {
ret void
}
)";
// No sorting is required.
EXPECT_FALSE(run(Assembly));
}
TEST_F(SPIRVSortBlocksTest, BasicBlockSwap) {
StringRef Assembly = R"(
define void @main() convergent "hlsl.numthreads"="4,8,16" "hlsl.shader"="compute" {
entry:
br label %middle
exit:
ret void
middle:
br label %exit
}
)";
EXPECT_TRUE(run(Assembly));
checkBasicBlockOrder({"entry", "middle", "exit"});
}
// Skip condition:
// +-> A -+
// entry -+ +-> C
// +------+
TEST_F(SPIRVSortBlocksTest, SkipCondition) {
StringRef Assembly = R"(
define void @main() convergent "hlsl.numthreads"="4,8,16" "hlsl.shader"="compute" {
entry:
%1 = icmp ne i32 0, 0
br i1 %1, label %c, label %a
c:
ret void
a:
br label %c
}
)";
EXPECT_TRUE(run(Assembly));
checkBasicBlockOrder({"entry", "a", "c"});
}
// Simple loop:
// entry -> header <-----------------+
// | `-> body -> continue -+
// `-> end
TEST_F(SPIRVSortBlocksTest, LoopOrdering) {
StringRef Assembly = R"(
define void @main() convergent "hlsl.numthreads"="4,8,16" "hlsl.shader"="compute" {
entry:
%1 = icmp ne i32 0, 0
br label %header
end:
ret void
body:
br label %continue
continue:
br label %header
header:
br i1 %1, label %body, label %end
}
)";
EXPECT_TRUE(run(Assembly));
checkBasicBlockOrder({"entry", "header", "end", "body", "continue"});
}
// Diamond condition:
// +-> A -+
// entry -+ +-> C
// +-> B -+
//
// A and B order can be flipped with no effect, but it must be remain
// deterministic/stable.
TEST_F(SPIRVSortBlocksTest, DiamondCondition) {
StringRef Assembly = R"(
define void @main() convergent "hlsl.numthreads"="4,8,16" "hlsl.shader"="compute" {
entry:
%1 = icmp ne i32 0, 0
br i1 %1, label %b, label %a
c:
ret void
b:
br label %c
a:
br label %c
}
)";
EXPECT_TRUE(run(Assembly));
checkBasicBlockOrder({"entry", "a", "b", "c"});
}
// Crossing conditions:
// +------+ +-> C -+
// +-> A -+ | | |
// entry -+ +--_|_-+ +-> E
// +-> B -+ | |
// +------+----> D -+
//
// A & B have the same rank.
// C & D have the same rank, but are after A & B.
// E if the last block.
TEST_F(SPIRVSortBlocksTest, CrossingCondition) {
StringRef Assembly = R"(
define void @main() convergent "hlsl.numthreads"="4,8,16" "hlsl.shader"="compute" {
entry:
%1 = icmp ne i32 0, 0
br i1 %1, label %b, label %a
e:
ret void
c:
br label %e
b:
br i1 %1, label %d, label %c
d:
br label %e
a:
br i1 %1, label %d, label %c
}
)";
EXPECT_TRUE(run(Assembly));
checkBasicBlockOrder({"entry", "a", "b", "c", "d", "e"});
}
// Irreducible CFG
// digraph {
// entry -> A;
//
// A -> B;
// A -> C;
//
// B -> A;
// B -> C;
//
// C -> B;
// }
//
// Order starts with Entry and A. Order of B and C can change, but must remain
// stable.
// In such case, rank will be defined by the arbitrary traversal order. What's
// important is to have a stable value.
TEST_F(SPIRVSortBlocksTest, IrreducibleOrdering) {
StringRef Assembly = R"(
define void @main() convergent "hlsl.numthreads"="4,8,16" "hlsl.shader"="compute" {
entry:
%1 = icmp ne i32 0, 0
br label %a
b:
br i1 %1, label %a, label %c
c:
br label %b
a:
br i1 %1, label %b, label %c
}
)";
EXPECT_TRUE(run(Assembly));
checkBasicBlockOrder({"entry", "a", "b", "c"});
}
TEST_F(SPIRVSortBlocksTest, IrreducibleOrderingBeforeReduction) {
StringRef Assembly = R"(
define void @main() convergent "hlsl.numthreads"="4,8,16" "hlsl.shader"="compute" {
entry:
%1 = icmp ne i32 0, 0
br label %a
c:
br i1 %1, label %e, label %d
e:
ret void
b:
br i1 %1, label %c, label %d
a:
br label %b
d:
br i1 %1, label %b, label %c
}
)";
EXPECT_TRUE(run(Assembly));
checkBasicBlockOrder({"entry", "a", "b", "c", "d", "e"});
}
TEST_F(SPIRVSortBlocksTest, LoopDiamond) {
StringRef Assembly = R"(
define void @main() convergent "hlsl.numthreads"="4,8,16" "hlsl.shader"="compute" {
entry:
%1 = icmp ne i32 0, 0
br label %header
header:
br i1 %1, label %body, label %end
body:
br i1 %1, label %break, label %inside_a
inside_a:
br label %inside_b
inside_b:
br i1 %1, label %inside_d, label %inside_c
inside_c:
br label %continue
inside_d:
br label %continue
break:
br label %end
continue:
br label %header
end:
ret void
}
)";
EXPECT_TRUE(run(Assembly));
checkBasicBlockOrder({"entry", "header", "body", "inside_a", "inside_b",
"inside_c", "inside_d", "continue", "break", "end"});
}
TEST_F(SPIRVSortBlocksTest, LoopNested) {
StringRef Assembly = R"(
define void @main() convergent "hlsl.numthreads"="4,8,16" "hlsl.shader"="compute" {
entry:
%1 = icmp ne i32 0, 0
br label %a
a:
br i1 %1, label %h, label %b
b:
br label %c
c:
br i1 %1, label %d, label %e
d:
br label %g
e:
br label %f
f:
br label %c
g:
br label %a
h:
ret void
}
)";
EXPECT_TRUE(run(Assembly));
checkBasicBlockOrder({"entry", "a", "b", "c", "e", "f", "d", "g", "h"});
}
TEST_F(SPIRVSortBlocksTest, IfNested) {
StringRef Assembly = R"(
define void @main() convergent "hlsl.numthreads"="4,8,16" "hlsl.shader"="compute" {
entry:
br i1 true, label %d, label %a
i:
br label %j
j:
ret void
a:
br i1 true, label %b, label %c
d:
br i1 true, label %f, label %e
e:
br label %i
b:
br label %c
f:
br i1 true, label %h, label %g
g:
br label %h
c:
br label %j
h:
br label %i
}
)";
EXPECT_TRUE(run(Assembly));
checkBasicBlockOrder(
{"entry", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j"});
}
// Same as above, but this time blocks are already sorted, so no need to reorder
// them.
TEST_F(SPIRVSortBlocksTest, IfNestedSorted) {
StringRef Assembly = R"(
define void @main() convergent "hlsl.numthreads"="4,8,16" "hlsl.shader"="compute" {
entry:
br i1 true, label %d, label %z
z:
br i1 true, label %b, label %c
b:
br label %c
c:
br label %j
d:
br i1 true, label %f, label %e
e:
br label %i
f:
br i1 true, label %h, label %g
g:
br label %h
h:
br label %i
i:
br label %j
j:
ret void
}
)";
EXPECT_FALSE(run(Assembly));
}