| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,292 @@ | ||
| ; 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 %} | ||
| ; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | spirv-sim --function=_Z7processv --wave=1 --expects=6 | ||
|
|
||
| ; | ||
| ; int process() { | ||
| ; int color = 0; | ||
| ; | ||
| ; int val = 0; | ||
| ; | ||
| ; if (color < 0) { | ||
| ; val = 1; | ||
| ; } | ||
| ; | ||
| ; // for-stmt following if-stmt | ||
| ; for (int i = 0; i < 10; ++i) { | ||
| ; if (color < 0) { // if-stmt nested in for-stmt | ||
| ; val = val + 1; | ||
| ; for (int j = 0; j < 15; ++j) { // for-stmt deeply nested in if-then | ||
| ; val = val * 2; | ||
| ; } // end for (int j | ||
| ; val = val + 3; | ||
| ; } | ||
| ; | ||
| ; if (color < 1) { // if-stmt following if-stmt | ||
| ; val = val * 4; | ||
| ; } else { | ||
| ; for (int k = 0; k < 20; ++k) { // for-stmt deeply nested in if-else | ||
| ; val = val - 5; | ||
| ; if (val < 0) { // deeply nested if-stmt | ||
| ; val = val + 100; | ||
| ; } | ||
| ; } // end for (int k | ||
| ; } // end elsek | ||
| ; } // end for (int i | ||
| ; | ||
| ; // if-stmt following for-stmt | ||
| ; if (color < 2) { | ||
| ; val = val + 6; | ||
| ; } | ||
| ; | ||
| ; return val; | ||
| ; } | ||
| ; | ||
| ; [numthreads(1, 1, 1)] | ||
| ; void main() { | ||
| ; process(); | ||
| ; } | ||
|
|
||
| ; 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: OpBranch %[[#bb68:]] | ||
| ; CHECK: %[[#bb68:]] = OpLabel | ||
| ; CHECK: OpLoopMerge %[[#bb69:]] %[[#bb70:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb71:]] %[[#bb69:]] | ||
| ; CHECK: %[[#bb71:]] = 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: OpReturnValue %[[#]] | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_61:]] = OpFunction %[[#void:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb89:]] = OpLabel | ||
| ; CHECK: OpReturn | ||
| ; CHECK: OpFunctionEnd | ||
| ; 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" | ||
|
|
||
| ; Function Attrs: convergent noinline norecurse nounwind optnone | ||
| define spir_func noundef i32 @_Z7processv() #0 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| %color = alloca i32, align 4 | ||
| %val = alloca i32, align 4 | ||
| %i = alloca i32, align 4 | ||
| %j = alloca i32, align 4 | ||
| %k = alloca i32, align 4 | ||
| store i32 0, ptr %color, align 4 | ||
| store i32 0, ptr %val, align 4 | ||
| %1 = load i32, ptr %color, align 4 | ||
| %cmp = icmp slt i32 %1, 0 | ||
| br i1 %cmp, label %if.then, label %if.end | ||
|
|
||
| if.then: ; preds = %entry | ||
| store i32 1, ptr %val, align 4 | ||
| br label %if.end | ||
|
|
||
| if.end: ; preds = %if.then, %entry | ||
| store i32 0, ptr %i, align 4 | ||
| br label %for.cond | ||
|
|
||
| for.cond: ; preds = %for.inc23, %if.end | ||
| %2 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ] | ||
| %3 = load i32, ptr %i, align 4 | ||
| %cmp1 = icmp slt i32 %3, 10 | ||
| br i1 %cmp1, label %for.body, label %for.end25 | ||
|
|
||
| for.body: ; preds = %for.cond | ||
| %4 = load i32, ptr %color, align 4 | ||
| %cmp2 = icmp slt i32 %4, 0 | ||
| br i1 %cmp2, label %if.then3, label %if.end8 | ||
|
|
||
| if.then3: ; preds = %for.body | ||
| %5 = load i32, ptr %val, align 4 | ||
| %add = add nsw i32 %5, 1 | ||
| store i32 %add, ptr %val, align 4 | ||
| store i32 0, ptr %j, align 4 | ||
| br label %for.cond4 | ||
|
|
||
| for.cond4: ; preds = %for.inc, %if.then3 | ||
| %6 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %2) ] | ||
| %7 = load i32, ptr %j, align 4 | ||
| %cmp5 = icmp slt i32 %7, 15 | ||
| br i1 %cmp5, label %for.body6, label %for.end | ||
|
|
||
| for.body6: ; preds = %for.cond4 | ||
| %8 = load i32, ptr %val, align 4 | ||
| %mul = mul nsw i32 %8, 2 | ||
| store i32 %mul, ptr %val, align 4 | ||
| br label %for.inc | ||
|
|
||
| for.inc: ; preds = %for.body6 | ||
| %9 = load i32, ptr %j, align 4 | ||
| %inc = add nsw i32 %9, 1 | ||
| store i32 %inc, ptr %j, align 4 | ||
| br label %for.cond4 | ||
|
|
||
| for.end: ; preds = %for.cond4 | ||
| %10 = load i32, ptr %val, align 4 | ||
| %add7 = add nsw i32 %10, 3 | ||
| store i32 %add7, ptr %val, align 4 | ||
| br label %if.end8 | ||
|
|
||
| if.end8: ; preds = %for.end, %for.body | ||
| %11 = load i32, ptr %color, align 4 | ||
| %cmp9 = icmp slt i32 %11, 1 | ||
| br i1 %cmp9, label %if.then10, label %if.else | ||
|
|
||
| if.then10: ; preds = %if.end8 | ||
| %12 = load i32, ptr %val, align 4 | ||
| %mul11 = mul nsw i32 %12, 4 | ||
| store i32 %mul11, ptr %val, align 4 | ||
| br label %if.end22 | ||
|
|
||
| if.else: ; preds = %if.end8 | ||
| store i32 0, ptr %k, align 4 | ||
| br label %for.cond12 | ||
|
|
||
| for.cond12: ; preds = %for.inc19, %if.else | ||
| %13 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %2) ] | ||
| %14 = load i32, ptr %k, align 4 | ||
| %cmp13 = icmp slt i32 %14, 20 | ||
| br i1 %cmp13, label %for.body14, label %for.end21 | ||
|
|
||
| for.body14: ; preds = %for.cond12 | ||
| %15 = load i32, ptr %val, align 4 | ||
| %sub = sub nsw i32 %15, 5 | ||
| store i32 %sub, ptr %val, align 4 | ||
| %16 = load i32, ptr %val, align 4 | ||
| %cmp15 = icmp slt i32 %16, 0 | ||
| br i1 %cmp15, label %if.then16, label %if.end18 | ||
|
|
||
| if.then16: ; preds = %for.body14 | ||
| %17 = load i32, ptr %val, align 4 | ||
| %add17 = add nsw i32 %17, 100 | ||
| store i32 %add17, ptr %val, align 4 | ||
| br label %if.end18 | ||
|
|
||
| if.end18: ; preds = %if.then16, %for.body14 | ||
| br label %for.inc19 | ||
|
|
||
| for.inc19: ; preds = %if.end18 | ||
| %18 = load i32, ptr %k, align 4 | ||
| %inc20 = add nsw i32 %18, 1 | ||
| store i32 %inc20, ptr %k, align 4 | ||
| br label %for.cond12 | ||
|
|
||
| for.end21: ; preds = %for.cond12 | ||
| br label %if.end22 | ||
|
|
||
| if.end22: ; preds = %for.end21, %if.then10 | ||
| br label %for.inc23 | ||
|
|
||
| for.inc23: ; preds = %if.end22 | ||
| %19 = load i32, ptr %i, align 4 | ||
| %inc24 = add nsw i32 %19, 1 | ||
| store i32 %inc24, ptr %i, align 4 | ||
| br label %for.cond | ||
|
|
||
| for.end25: ; preds = %for.cond | ||
| %20 = load i32, ptr %color, align 4 | ||
| %cmp26 = icmp slt i32 %20, 2 | ||
| br i1 %cmp26, label %if.then27, label %if.end29 | ||
|
|
||
| if.then27: ; preds = %for.end25 | ||
| %21 = load i32, ptr %val, align 4 | ||
| %add28 = add nsw i32 %21, 6 | ||
| store i32 %add28, ptr %val, align 4 | ||
| br label %if.end29 | ||
|
|
||
| if.end29: ; preds = %if.then27, %for.end25 | ||
| %22 = load i32, ptr %val, align 4 | ||
| ret i32 %22 | ||
| } | ||
|
|
||
| ; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none) | ||
| declare token @llvm.experimental.convergence.entry() #1 | ||
|
|
||
| ; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none) | ||
| declare token @llvm.experimental.convergence.loop() #1 | ||
|
|
||
| ; 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) ] | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent norecurse | ||
| define void @main.1() #2 { | ||
| entry: | ||
| call void @main() | ||
| ret void | ||
| } | ||
|
|
||
| attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "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} | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,163 @@ | ||
| ; 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 %} | ||
| ; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | spirv-sim --function=_Z7processv --wave=1 --expects=3 | ||
|
|
||
|
|
||
| ; | ||
| ; int process() { | ||
| ; int c1 = 0; | ||
| ; int c2 = 1; | ||
| ; int c3 = 0; | ||
| ; int c4 = 1; | ||
| ; int val = 0; | ||
| ; | ||
| ; if (c1) { | ||
| ; if (c2) | ||
| ; val = 1; | ||
| ; } else { | ||
| ; if (c3) { | ||
| ; val = 2; | ||
| ; } else { | ||
| ; if (c4) { | ||
| ; val = 3; | ||
| ; } | ||
| ; } | ||
| ; } | ||
| ; return val; | ||
| ; } | ||
| ; | ||
| ; [numthreads(1, 1, 1)] | ||
| ; void main() { | ||
| ; process(); | ||
| ; } | ||
|
|
||
| ; CHECK: %[[#func_11:]] = OpFunction %[[#uint:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb30:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb31:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb32:]] %[[#bb33:]] | ||
| ; CHECK: %[[#bb32:]] = 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: 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: OpReturnValue %[[#]] | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_26:]] = OpFunction %[[#void:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb41:]] = OpLabel | ||
| ; CHECK: OpReturn | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_28:]] = OpFunction %[[#void:]] None %[[#]] | ||
| ; CHECK: %[[#bb42:]] = 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 @_Z7processv() #0 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| %c1 = alloca i32, align 4 | ||
| %c2 = alloca i32, align 4 | ||
| %c3 = alloca i32, align 4 | ||
| %c4 = alloca i32, align 4 | ||
| %val = alloca i32, align 4 | ||
| store i32 0, ptr %c1, align 4 | ||
| store i32 1, ptr %c2, align 4 | ||
| store i32 0, ptr %c3, align 4 | ||
| store i32 1, ptr %c4, align 4 | ||
| store i32 0, ptr %val, align 4 | ||
| %1 = load i32, ptr %c1, align 4 | ||
| %tobool = icmp ne i32 %1, 0 | ||
| br i1 %tobool, label %if.then, label %if.else | ||
|
|
||
| if.then: ; preds = %entry | ||
| %2 = load i32, ptr %c2, align 4 | ||
| %tobool1 = icmp ne i32 %2, 0 | ||
| br i1 %tobool1, label %if.then2, label %if.end | ||
|
|
||
| if.then2: ; preds = %if.then | ||
| store i32 1, ptr %val, align 4 | ||
| br label %if.end | ||
|
|
||
| if.end: ; preds = %if.then2, %if.then | ||
| br label %if.end10 | ||
|
|
||
| if.else: ; preds = %entry | ||
| %3 = load i32, ptr %c3, align 4 | ||
| %tobool3 = icmp ne i32 %3, 0 | ||
| br i1 %tobool3, label %if.then4, label %if.else5 | ||
|
|
||
| if.then4: ; preds = %if.else | ||
| store i32 2, ptr %val, align 4 | ||
| br label %if.end9 | ||
|
|
||
| if.else5: ; preds = %if.else | ||
| %4 = load i32, ptr %c4, align 4 | ||
| %tobool6 = icmp ne i32 %4, 0 | ||
| br i1 %tobool6, label %if.then7, label %if.end8 | ||
|
|
||
| if.then7: ; preds = %if.else5 | ||
| store i32 3, ptr %val, align 4 | ||
| br label %if.end8 | ||
|
|
||
| if.end8: ; preds = %if.then7, %if.else5 | ||
| br label %if.end9 | ||
|
|
||
| if.end9: ; preds = %if.end8, %if.then4 | ||
| br label %if.end10 | ||
|
|
||
| if.end10: ; preds = %if.end9, %if.end | ||
| %5 = load i32, ptr %val, align 4 | ||
| ret i32 %5 | ||
| } | ||
|
|
||
| ; 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 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) ] | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent norecurse | ||
| define void @main.1() #2 { | ||
| entry: | ||
| call void @main() | ||
| ret void | ||
| } | ||
|
|
||
| attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "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} | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,183 @@ | ||
| ; 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 %} | ||
| ; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | spirv-sim --function=_Z7processv --wave=1 --expects=2 | ||
|
|
||
| ; | ||
| ; int process() { | ||
| ; int c = 0; | ||
| ; int val = 0; | ||
| ; | ||
| ; // Both then and else | ||
| ; if (c) { | ||
| ; val = val + 1; | ||
| ; } else { | ||
| ; val = val + 2; | ||
| ; } | ||
| ; | ||
| ; // No else | ||
| ; if (c) | ||
| ; val = 1; | ||
| ; | ||
| ; // Empty then | ||
| ; if (c) { | ||
| ; } else { | ||
| ; val = 2; | ||
| ; } | ||
| ; | ||
| ; // Null body | ||
| ; if (c) | ||
| ; ; | ||
| ; | ||
| ; if (int d = val) { | ||
| ; c = true; | ||
| ; } | ||
| ; | ||
| ; return val; | ||
| ; } | ||
| ; | ||
| ; [numthreads(1, 1, 1)] | ||
| ; void main() { | ||
| ; process(); | ||
| ; } | ||
|
|
||
| ; CHECK: %[[#func_10:]] = OpFunction %[[#uint:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb34:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb35:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb36:]] %[[#bb37:]] | ||
| ; CHECK: %[[#bb36:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb35:]] | ||
| ; CHECK: %[[#bb37:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb35:]] | ||
| ; CHECK: %[[#bb35:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb38:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb39:]] %[[#bb38:]] | ||
| ; CHECK: %[[#bb39:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb38:]] | ||
| ; CHECK: %[[#bb38:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb40:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb40:]] %[[#bb41:]] | ||
| ; CHECK: %[[#bb41:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb40:]] | ||
| ; CHECK: %[[#bb40:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb42:]] | ||
| ; CHECK: %[[#bb42:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb43:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb44:]] %[[#bb43:]] | ||
| ; CHECK: %[[#bb44:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb43:]] | ||
| ; CHECK: %[[#bb43:]] = OpLabel | ||
| ; CHECK: OpReturnValue %[[#]] | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_30:]] = OpFunction %[[#void:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb45:]] = OpLabel | ||
| ; CHECK: OpReturn | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_32:]] = OpFunction %[[#void:]] None %[[#]] | ||
| ; CHECK: %[[#bb46:]] = 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 @_Z7processv() #0 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| %c = alloca i32, align 4 | ||
| %val = alloca i32, align 4 | ||
| %d = alloca i32, align 4 | ||
| store i32 0, ptr %c, align 4 | ||
| store i32 0, ptr %val, align 4 | ||
| %1 = load i32, ptr %c, align 4 | ||
| %tobool = icmp ne i32 %1, 0 | ||
| br i1 %tobool, label %if.then, label %if.else | ||
|
|
||
| if.then: ; preds = %entry | ||
| %2 = load i32, ptr %val, align 4 | ||
| %add = add nsw i32 %2, 1 | ||
| store i32 %add, ptr %val, align 4 | ||
| br label %if.end | ||
|
|
||
| if.else: ; preds = %entry | ||
| %3 = load i32, ptr %val, align 4 | ||
| %add1 = add nsw i32 %3, 2 | ||
| store i32 %add1, ptr %val, align 4 | ||
| br label %if.end | ||
|
|
||
| if.end: ; preds = %if.else, %if.then | ||
| %4 = load i32, ptr %c, align 4 | ||
| %tobool2 = icmp ne i32 %4, 0 | ||
| br i1 %tobool2, label %if.then3, label %if.end4 | ||
|
|
||
| if.then3: ; preds = %if.end | ||
| store i32 1, ptr %val, align 4 | ||
| br label %if.end4 | ||
|
|
||
| if.end4: ; preds = %if.then3, %if.end | ||
| %5 = load i32, ptr %c, align 4 | ||
| %tobool5 = icmp ne i32 %5, 0 | ||
| br i1 %tobool5, label %if.then6, label %if.else7 | ||
|
|
||
| if.then6: ; preds = %if.end4 | ||
| br label %if.end8 | ||
|
|
||
| if.else7: ; preds = %if.end4 | ||
| store i32 2, ptr %val, align 4 | ||
| br label %if.end8 | ||
|
|
||
| if.end8: ; preds = %if.else7, %if.then6 | ||
| %6 = load i32, ptr %c, align 4 | ||
| %tobool9 = icmp ne i32 %6, 0 | ||
| br i1 %tobool9, label %if.then10, label %if.end11 | ||
|
|
||
| if.then10: ; preds = %if.end8 | ||
| br label %if.end11 | ||
|
|
||
| if.end11: ; preds = %if.then10, %if.end8 | ||
| %7 = load i32, ptr %val, align 4 | ||
| store i32 %7, ptr %d, align 4 | ||
| %8 = load i32, ptr %d, align 4 | ||
| %tobool12 = icmp ne i32 %8, 0 | ||
| br i1 %tobool12, label %if.then13, label %if.end14 | ||
|
|
||
| if.then13: ; preds = %if.end11 | ||
| store i32 1, ptr %c, align 4 | ||
| br label %if.end14 | ||
|
|
||
| if.end14: ; preds = %if.then13, %if.end11 | ||
| %9 = load i32, ptr %val, align 4 | ||
| ret i32 %9 | ||
| } | ||
|
|
||
| ; 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 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) ] | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent norecurse | ||
| define void @main.1() #2 { | ||
| entry: | ||
| call void @main() | ||
| ret void | ||
| } | ||
|
|
||
| attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "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} | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,194 @@ | ||
| ; 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 %} | ||
| ; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | spirv-sim --function=_Z7processv --wave=1 --expects=1 | ||
|
|
||
| ; | ||
| ; int fn() { return true; } | ||
| ; | ||
| ; int process() { | ||
| ; // Use in control flow | ||
| ; int a = 0; | ||
| ; int b = 0; | ||
| ; int val = 0; | ||
| ; if (a && b) val++; | ||
| ; | ||
| ; // Operand with side effects | ||
| ; if (fn() && fn()) val++; | ||
| ; | ||
| ; if (a && fn()) | ||
| ; val++; | ||
| ; | ||
| ; if (fn() && b) | ||
| ; val++; | ||
| ; return val; | ||
| ; } | ||
| ; | ||
| ; [numthreads(1, 1, 1)] | ||
| ; void main() { | ||
| ; process(); | ||
| ; } | ||
|
|
||
| ; CHECK: %[[#func_9:]] = OpFunction %[[#uint:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb43:]] = OpLabel | ||
| ; CHECK: OpReturnValue %[[#]] | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_10:]] = OpFunction %[[#uint:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb44:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb45:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb46:]] %[[#bb45:]] | ||
| ; CHECK: %[[#bb46:]] = OpLabel | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb47:]] %[[#bb45:]] | ||
| ; CHECK: %[[#bb47:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb45:]] | ||
| ; CHECK: %[[#bb45:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb48:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb49:]] %[[#bb48:]] | ||
| ; CHECK: %[[#bb49:]] = OpLabel | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb50:]] %[[#bb48:]] | ||
| ; CHECK: %[[#bb50:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb48:]] | ||
| ; CHECK: %[[#bb48:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb51:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb52:]] %[[#bb51:]] | ||
| ; CHECK: %[[#bb52:]] = OpLabel | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb53:]] %[[#bb51:]] | ||
| ; CHECK: %[[#bb53:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb51:]] | ||
| ; CHECK: %[[#bb51:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb54:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb55:]] %[[#bb54:]] | ||
| ; CHECK: %[[#bb55:]] = OpLabel | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb56:]] %[[#bb54:]] | ||
| ; CHECK: %[[#bb56:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb54:]] | ||
| ; CHECK: %[[#bb54:]] = OpLabel | ||
| ; CHECK: OpReturnValue %[[#]] | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_39:]] = OpFunction %[[#void:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb57:]] = OpLabel | ||
| ; CHECK: OpReturn | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_41:]] = OpFunction %[[#void:]] None %[[#]] | ||
| ; CHECK: %[[#bb58:]] = 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 @_Z2fnv() #0 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| ret i32 1 | ||
| } | ||
|
|
||
| ; 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 | ||
| %val = alloca i32, align 4 | ||
| store i32 0, ptr %a, align 4 | ||
| store i32 0, ptr %b, align 4 | ||
| store i32 0, ptr %val, align 4 | ||
| %1 = load i32, ptr %a, align 4 | ||
| %tobool = icmp ne i32 %1, 0 | ||
| br i1 %tobool, label %land.lhs.true, label %if.end | ||
|
|
||
| land.lhs.true: ; preds = %entry | ||
| %2 = load i32, ptr %b, align 4 | ||
| %tobool1 = icmp ne i32 %2, 0 | ||
| br i1 %tobool1, label %if.then, label %if.end | ||
|
|
||
| if.then: ; preds = %land.lhs.true | ||
| %3 = load i32, ptr %val, align 4 | ||
| %inc = add nsw i32 %3, 1 | ||
| store i32 %inc, ptr %val, align 4 | ||
| br label %if.end | ||
|
|
||
| if.end: ; preds = %if.then, %land.lhs.true, %entry | ||
| %call2 = call spir_func noundef i32 @_Z2fnv() #3 [ "convergencectrl"(token %0) ] | ||
| %tobool3 = icmp ne i32 %call2, 0 | ||
| br i1 %tobool3, label %land.lhs.true4, label %if.end9 | ||
|
|
||
| land.lhs.true4: ; preds = %if.end | ||
| %call5 = call spir_func noundef i32 @_Z2fnv() #3 [ "convergencectrl"(token %0) ] | ||
| %tobool6 = icmp ne i32 %call5, 0 | ||
| br i1 %tobool6, label %if.then7, label %if.end9 | ||
|
|
||
| if.then7: ; preds = %land.lhs.true4 | ||
| %4 = load i32, ptr %val, align 4 | ||
| %inc8 = add nsw i32 %4, 1 | ||
| store i32 %inc8, ptr %val, align 4 | ||
| br label %if.end9 | ||
|
|
||
| if.end9: ; preds = %if.then7, %land.lhs.true4, %if.end | ||
| %5 = load i32, ptr %a, align 4 | ||
| %tobool10 = icmp ne i32 %5, 0 | ||
| br i1 %tobool10, label %land.lhs.true11, label %if.end16 | ||
|
|
||
| land.lhs.true11: ; preds = %if.end9 | ||
| %call12 = call spir_func noundef i32 @_Z2fnv() #3 [ "convergencectrl"(token %0) ] | ||
| %tobool13 = icmp ne i32 %call12, 0 | ||
| br i1 %tobool13, label %if.then14, label %if.end16 | ||
|
|
||
| if.then14: ; preds = %land.lhs.true11 | ||
| %6 = load i32, ptr %val, align 4 | ||
| %inc15 = add nsw i32 %6, 1 | ||
| store i32 %inc15, ptr %val, align 4 | ||
| br label %if.end16 | ||
|
|
||
| if.end16: ; preds = %if.then14, %land.lhs.true11, %if.end9 | ||
| %call17 = call spir_func noundef i32 @_Z2fnv() #3 [ "convergencectrl"(token %0) ] | ||
| %tobool18 = icmp ne i32 %call17, 0 | ||
| br i1 %tobool18, label %land.lhs.true19, label %if.end23 | ||
|
|
||
| land.lhs.true19: ; preds = %if.end16 | ||
| %7 = load i32, ptr %b, align 4 | ||
| %tobool20 = icmp ne i32 %7, 0 | ||
| br i1 %tobool20, label %if.then21, label %if.end23 | ||
|
|
||
| if.then21: ; preds = %land.lhs.true19 | ||
| %8 = load i32, ptr %val, align 4 | ||
| %inc22 = add nsw i32 %8, 1 | ||
| store i32 %inc22, ptr %val, align 4 | ||
| br label %if.end23 | ||
|
|
||
| if.end23: ; preds = %if.then21, %land.lhs.true19, %if.end16 | ||
| %9 = load i32, ptr %val, align 4 | ||
| ret i32 %9 | ||
| } | ||
|
|
||
| ; 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) ] | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent norecurse | ||
| define void @main.1() #2 { | ||
| entry: | ||
| call void @main() | ||
| ret void | ||
| } | ||
|
|
||
| attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "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} | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,223 @@ | ||
| ; 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 %} | ||
| ; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | spirv-sim --function=_Z7processv --wave=1 --expects=3 | ||
|
|
||
| ; | ||
| ; int fn() { return true; } | ||
| ; | ||
| ; int process() { | ||
| ; int a = 0; | ||
| ; int b = 0; | ||
| ; int val = 0; | ||
| ; | ||
| ; // Use in control flow | ||
| ; if (a || b) val++; | ||
| ; | ||
| ; // Operand with side effects | ||
| ; if (fn() || fn()) val++; | ||
| ; if (a || fn()) val++; | ||
| ; if (fn() || b) val++; | ||
| ; return val; | ||
| ; } | ||
| ; | ||
| ; [numthreads(1, 1, 1)] | ||
| ; void main() { | ||
| ; process(); | ||
| ; } | ||
|
|
||
| ; CHECK: %[[#func_10:]] = OpFunction %[[#uint:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb52:]] = OpLabel | ||
| ; CHECK: OpReturnValue %[[#]] | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_11:]] = OpFunction %[[#uint:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb53:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb54:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb55:]] %[[#bb56:]] | ||
| ; CHECK: %[[#bb55:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb57:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb57:]] %[[#bb58:]] | ||
| ; CHECK: %[[#bb56:]] = OpLabel | ||
| ; CHECK: %[[#bb58:]] = OpLabel | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb57:]] %[[#bb59:]] | ||
| ; CHECK: %[[#bb59:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb57:]] | ||
| ; CHECK: %[[#bb57:]] = OpLabel | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb60:]] %[[#bb54:]] | ||
| ; CHECK: %[[#bb60:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb54:]] | ||
| ; CHECK: %[[#bb54:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb61:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb62:]] %[[#bb63:]] | ||
| ; CHECK: %[[#bb62:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb64:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb64:]] %[[#bb65:]] | ||
| ; CHECK: %[[#bb63:]] = OpLabel | ||
| ; CHECK: %[[#bb65:]] = OpLabel | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb64:]] %[[#bb66:]] | ||
| ; CHECK: %[[#bb66:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb64:]] | ||
| ; CHECK: %[[#bb64:]] = OpLabel | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb67:]] %[[#bb61:]] | ||
| ; CHECK: %[[#bb67:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb61:]] | ||
| ; CHECK: %[[#bb61:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb68:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb69:]] %[[#bb70:]] | ||
| ; CHECK: %[[#bb69:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb71:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb71:]] %[[#bb72:]] | ||
| ; CHECK: %[[#bb70:]] = OpLabel | ||
| ; CHECK: %[[#bb72:]] = OpLabel | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb71:]] %[[#bb73:]] | ||
| ; CHECK: %[[#bb73:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb71:]] | ||
| ; CHECK: %[[#bb71:]] = OpLabel | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb74:]] %[[#bb68:]] | ||
| ; CHECK: %[[#bb74:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb68:]] | ||
| ; CHECK: %[[#bb68:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb75:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb76:]] %[[#bb77:]] | ||
| ; CHECK: %[[#bb76:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb78:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb78:]] %[[#bb79:]] | ||
| ; CHECK: %[[#bb77:]] = OpLabel | ||
| ; CHECK: %[[#bb79:]] = OpLabel | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb78:]] %[[#bb80:]] | ||
| ; CHECK: %[[#bb80:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb78:]] | ||
| ; CHECK: %[[#bb78:]] = OpLabel | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb81:]] %[[#bb75:]] | ||
| ; CHECK: %[[#bb81:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb75:]] | ||
| ; CHECK: %[[#bb75:]] = OpLabel | ||
| ; CHECK: OpReturnValue %[[#]] | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_48:]] = OpFunction %[[#void:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb82:]] = OpLabel | ||
| ; CHECK: OpReturn | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_50:]] = OpFunction %[[#void:]] None %[[#]] | ||
| ; CHECK: %[[#bb83:]] = 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 @_Z2fnv() #0 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| ret i32 1 | ||
| } | ||
|
|
||
| ; 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 | ||
| %val = alloca i32, align 4 | ||
| store i32 0, ptr %a, align 4 | ||
| store i32 0, ptr %b, align 4 | ||
| store i32 0, ptr %val, align 4 | ||
| %1 = load i32, ptr %a, align 4 | ||
| %tobool = icmp ne i32 %1, 0 | ||
| br i1 %tobool, label %if.then, label %lor.lhs.false | ||
|
|
||
| lor.lhs.false: ; preds = %entry | ||
| %2 = load i32, ptr %b, align 4 | ||
| %tobool1 = icmp ne i32 %2, 0 | ||
| br i1 %tobool1, label %if.then, label %if.end | ||
|
|
||
| if.then: ; preds = %lor.lhs.false, %entry | ||
| %3 = load i32, ptr %val, align 4 | ||
| %inc = add nsw i32 %3, 1 | ||
| store i32 %inc, ptr %val, align 4 | ||
| br label %if.end | ||
|
|
||
| if.end: ; preds = %if.then, %lor.lhs.false | ||
| %call2 = call spir_func noundef i32 @_Z2fnv() #3 [ "convergencectrl"(token %0) ] | ||
| %tobool3 = icmp ne i32 %call2, 0 | ||
| br i1 %tobool3, label %if.then7, label %lor.lhs.false4 | ||
|
|
||
| lor.lhs.false4: ; preds = %if.end | ||
| %call5 = call spir_func noundef i32 @_Z2fnv() #3 [ "convergencectrl"(token %0) ] | ||
| %tobool6 = icmp ne i32 %call5, 0 | ||
| br i1 %tobool6, label %if.then7, label %if.end9 | ||
|
|
||
| if.then7: ; preds = %lor.lhs.false4, %if.end | ||
| %4 = load i32, ptr %val, align 4 | ||
| %inc8 = add nsw i32 %4, 1 | ||
| store i32 %inc8, ptr %val, align 4 | ||
| br label %if.end9 | ||
|
|
||
| if.end9: ; preds = %if.then7, %lor.lhs.false4 | ||
| %5 = load i32, ptr %a, align 4 | ||
| %tobool10 = icmp ne i32 %5, 0 | ||
| br i1 %tobool10, label %if.then14, label %lor.lhs.false11 | ||
|
|
||
| lor.lhs.false11: ; preds = %if.end9 | ||
| %call12 = call spir_func noundef i32 @_Z2fnv() #3 [ "convergencectrl"(token %0) ] | ||
| %tobool13 = icmp ne i32 %call12, 0 | ||
| br i1 %tobool13, label %if.then14, label %if.end16 | ||
|
|
||
| if.then14: ; preds = %lor.lhs.false11, %if.end9 | ||
| %6 = load i32, ptr %val, align 4 | ||
| %inc15 = add nsw i32 %6, 1 | ||
| store i32 %inc15, ptr %val, align 4 | ||
| br label %if.end16 | ||
|
|
||
| if.end16: ; preds = %if.then14, %lor.lhs.false11 | ||
| %call17 = call spir_func noundef i32 @_Z2fnv() #3 [ "convergencectrl"(token %0) ] | ||
| %tobool18 = icmp ne i32 %call17, 0 | ||
| br i1 %tobool18, label %if.then21, label %lor.lhs.false19 | ||
|
|
||
| lor.lhs.false19: ; preds = %if.end16 | ||
| %7 = load i32, ptr %b, align 4 | ||
| %tobool20 = icmp ne i32 %7, 0 | ||
| br i1 %tobool20, label %if.then21, label %if.end23 | ||
|
|
||
| if.then21: ; preds = %lor.lhs.false19, %if.end16 | ||
| %8 = load i32, ptr %val, align 4 | ||
| %inc22 = add nsw i32 %8, 1 | ||
| store i32 %inc22, ptr %val, align 4 | ||
| br label %if.end23 | ||
|
|
||
| if.end23: ; preds = %if.then21, %lor.lhs.false19 | ||
| %9 = load i32, ptr %val, align 4 | ||
| ret i32 %9 | ||
| } | ||
|
|
||
| ; 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) ] | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent norecurse | ||
| define void @main.1() #2 { | ||
| entry: | ||
| call void @main() | ||
| ret void | ||
| } | ||
|
|
||
| attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "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} | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,237 @@ | ||
| ; 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 %} | ||
| ; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | spirv-sim --function=_Z7processv --wave=1 --expects=0 | ||
|
|
||
| ; | ||
| ; int process() { | ||
| ; int cond = 1; | ||
| ; int value = 0; | ||
| ; | ||
| ; while(value < 10) { | ||
| ; switch(value) { | ||
| ; case 1: | ||
| ; value = 1; | ||
| ; return value; | ||
| ; case 2: { | ||
| ; value = 3; | ||
| ; {return value;} // Return from function. | ||
| ; value = 4; // No SPIR-V should be emitted for this statement. | ||
| ; break; // No SPIR-V should be emitted for this statement. | ||
| ; } | ||
| ; case 5 : { | ||
| ; value = 5; | ||
| ; {{return value;}} // Return from function. | ||
| ; value = 6; // No SPIR-V should be emitted for this statement. | ||
| ; } | ||
| ; default: | ||
| ; for (int i=0; i<10; ++i) { | ||
| ; if (cond) { | ||
| ; return value; // Return from function. | ||
| ; return value; // No SPIR-V should be emitted for this statement. | ||
| ; continue; // No SPIR-V should be emitted for this statement. | ||
| ; break; // No SPIR-V should be emitted for this statement. | ||
| ; ++value; // No SPIR-V should be emitted for this statement. | ||
| ; } else { | ||
| ; return value; // Return from function | ||
| ; continue; // No SPIR-V should be emitted for this statement. | ||
| ; break; // No SPIR-V should be emitted for this statement. | ||
| ; ++value; // No SPIR-V should be emitted for this statement. | ||
| ; } | ||
| ; } | ||
| ; | ||
| ; // Return from function. | ||
| ; // Even though this statement will never be executed [because both "if" and "else" above have return statements], | ||
| ; // SPIR-V code should be emitted for it as we do not analyze the logic. | ||
| ; return value; | ||
| ; } | ||
| ; | ||
| ; // Return from function. | ||
| ; // Even though this statement will never be executed [because all "case" statements above contain a return statement], | ||
| ; // SPIR-V code should be emitted for it as we do not analyze the logic. | ||
| ; return value; | ||
| ; } | ||
| ; | ||
| ; return value; | ||
| ; } | ||
| ; | ||
| ; [numthreads(1, 1, 1)] | ||
| ; void main() { | ||
| ; process(); | ||
| ; } | ||
|
|
||
| ; 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: 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: 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: OpReturnValue %[[#]] | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_39:]] = OpFunction %[[#void:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb60:]] = OpLabel | ||
| ; CHECK: OpReturn | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_41:]] = OpFunction %[[#void:]] None %[[#]] | ||
| ; CHECK: %[[#bb61:]] = 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 @_Z7processv() #0 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| %retval = alloca i32, align 4 | ||
| %cond = alloca i32, align 4 | ||
| %value = alloca i32, align 4 | ||
| %i = alloca i32, align 4 | ||
| store i32 1, ptr %cond, align 4 | ||
| store i32 0, ptr %value, align 4 | ||
| br label %while.cond | ||
|
|
||
| while.cond: ; preds = %entry | ||
| %1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ] | ||
| %2 = load i32, ptr %value, align 4 | ||
| %cmp = icmp slt i32 %2, 10 | ||
| br i1 %cmp, label %while.body, label %while.end | ||
|
|
||
| while.body: ; preds = %while.cond | ||
| %3 = load i32, ptr %value, align 4 | ||
| switch i32 %3, label %sw.default [ | ||
| i32 1, label %sw.bb | ||
| i32 2, label %sw.bb1 | ||
| i32 5, label %sw.bb2 | ||
| ] | ||
|
|
||
| sw.bb: ; preds = %while.body | ||
| store i32 1, ptr %value, align 4 | ||
| %4 = load i32, ptr %value, align 4 | ||
| store i32 %4, ptr %retval, align 4 | ||
| br label %return | ||
|
|
||
| sw.bb1: ; preds = %while.body | ||
| store i32 3, ptr %value, align 4 | ||
| %5 = load i32, ptr %value, align 4 | ||
| store i32 %5, ptr %retval, align 4 | ||
| br label %return | ||
|
|
||
| sw.bb2: ; preds = %while.body | ||
| store i32 5, ptr %value, align 4 | ||
| %6 = load i32, ptr %value, align 4 | ||
| store i32 %6, ptr %retval, align 4 | ||
| br label %return | ||
|
|
||
| sw.default: ; preds = %while.body | ||
| store i32 0, ptr %i, align 4 | ||
| br label %for.cond | ||
|
|
||
| for.cond: ; preds = %for.inc, %sw.default | ||
| %7 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %1) ] | ||
| %8 = load i32, ptr %i, align 4 | ||
| %cmp3 = icmp slt i32 %8, 10 | ||
| br i1 %cmp3, label %for.body, label %for.end | ||
|
|
||
| for.body: ; preds = %for.cond | ||
| %9 = load i32, ptr %cond, align 4 | ||
| %tobool = icmp ne i32 %9, 0 | ||
| br i1 %tobool, label %if.then, label %if.else | ||
|
|
||
| if.then: ; preds = %for.body | ||
| %10 = load i32, ptr %value, align 4 | ||
| store i32 %10, ptr %retval, align 4 | ||
| br label %return | ||
|
|
||
| if.else: ; preds = %for.body | ||
| %11 = load i32, ptr %value, align 4 | ||
| store i32 %11, ptr %retval, align 4 | ||
| br label %return | ||
|
|
||
| for.inc: ; No predecessors! | ||
| %12 = load i32, ptr %i, align 4 | ||
| %inc = add nsw i32 %12, 1 | ||
| store i32 %inc, ptr %i, align 4 | ||
| br label %for.cond | ||
|
|
||
| for.end: ; preds = %for.cond | ||
| %13 = load i32, ptr %value, align 4 | ||
| store i32 %13, ptr %retval, align 4 | ||
| br label %return | ||
|
|
||
| while.end: ; preds = %while.cond | ||
| %14 = load i32, ptr %value, align 4 | ||
| store i32 %14, ptr %retval, align 4 | ||
| br label %return | ||
|
|
||
| return: ; preds = %while.end, %for.end, %if.else, %if.then, %sw.bb2, %sw.bb1, %sw.bb | ||
| %15 = load i32, ptr %retval, align 4 | ||
| ret i32 %15 | ||
| } | ||
|
|
||
| ; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none) | ||
| declare token @llvm.experimental.convergence.entry() #1 | ||
|
|
||
| ; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none) | ||
| declare token @llvm.experimental.convergence.loop() #1 | ||
|
|
||
| ; 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) ] | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent norecurse | ||
| define void @main.1() #2 { | ||
| entry: | ||
| call void @main() | ||
| ret void | ||
| } | ||
|
|
||
| attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "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} | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| ; 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 %} | ||
|
|
||
| ; | ||
| ; [numthreads(1, 1, 1)] | ||
| ; void main() { | ||
| ; int a, b; | ||
| ; int cond = 1; | ||
| ; | ||
| ; while(cond) { | ||
| ; switch(b) { | ||
| ; default: | ||
| ; if (cond) { | ||
| ; if (cond) | ||
| ; return; | ||
| ; else | ||
| ; return; | ||
| ; } | ||
| ; } | ||
| ; return; | ||
| ; } | ||
| ; } | ||
|
|
||
| ; CHECK: %[[#func_8:]] = OpFunction %[[#void:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb22:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb23:]] | ||
| ; CHECK: %[[#bb23:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb24:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb25:]] %[[#bb24:]] | ||
| ; CHECK: %[[#bb25:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb26:]] | ||
| ; CHECK: %[[#bb26:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb27:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb27:]] %[[#bb28:]] | ||
| ; CHECK: %[[#bb28:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb27:]] | ||
| ; CHECK: %[[#bb27:]] = OpLabel | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb29:]] %[[#bb24:]] | ||
| ; CHECK: %[[#bb29:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb30:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb30:]] %[[#bb31:]] | ||
| ; CHECK: %[[#bb31:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb30:]] | ||
| ; CHECK: %[[#bb30:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb24:]] | ||
| ; CHECK: %[[#bb24:]] = OpLabel | ||
| ; CHECK: OpReturn | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_20:]] = OpFunction %[[#void:]] None %[[#]] | ||
| ; CHECK: %[[#bb32:]] = 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 internal spir_func void @main() #0 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| %a = alloca i32, align 4 | ||
| %b = alloca i32, align 4 | ||
| %cond = alloca i32, align 4 | ||
| store i32 1, ptr %cond, align 4 | ||
| br label %while.cond | ||
|
|
||
| while.cond: ; preds = %entry | ||
| %1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ] | ||
| %2 = load i32, ptr %cond, align 4 | ||
| %tobool = icmp ne i32 %2, 0 | ||
| br i1 %tobool, label %while.body, label %while.end | ||
|
|
||
| while.body: ; preds = %while.cond | ||
| %3 = load i32, ptr %b, align 4 | ||
| switch i32 %3, label %sw.default [ | ||
| ] | ||
|
|
||
| sw.default: ; preds = %while.body | ||
| %4 = load i32, ptr %cond, align 4 | ||
| %tobool1 = icmp ne i32 %4, 0 | ||
| br i1 %tobool1, label %if.then, label %if.end | ||
|
|
||
| if.then: ; preds = %sw.default | ||
| %5 = load i32, ptr %cond, align 4 | ||
| %tobool2 = icmp ne i32 %5, 0 | ||
| br i1 %tobool2, label %if.then3, label %if.else | ||
|
|
||
| if.then3: ; preds = %if.then | ||
| br label %while.end | ||
|
|
||
| if.else: ; preds = %if.then | ||
| br label %while.end | ||
|
|
||
| if.end: ; preds = %sw.default | ||
| br label %sw.epilog | ||
|
|
||
| sw.epilog: ; preds = %if.end | ||
| br label %while.end | ||
|
|
||
| while.end: ; preds = %if.then3, %if.else, %sw.epilog, %while.cond | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent norecurse | ||
| define void @main.1() #1 { | ||
| entry: | ||
| call void @main() | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none) | ||
| declare token @llvm.experimental.convergence.entry() #2 | ||
|
|
||
| ; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none) | ||
| declare token @llvm.experimental.convergence.loop() #2 | ||
|
|
||
| attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } | ||
| attributes #1 = { convergent norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } | ||
| attributes #2 = { convergent nocallback nofree nosync nounwind willreturn memory(none) } | ||
|
|
||
| !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} | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| ; 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 %} | ||
|
|
||
| ; | ||
| ; void A() { | ||
| ; } | ||
| ; | ||
| ; [numthreads(1, 1, 1)] | ||
| ; void main() { | ||
| ; return A(); | ||
| ; } | ||
|
|
||
| ; CHECK: %[[#func_3:]] = OpFunction %[[#void:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb8:]] = OpLabel | ||
| ; CHECK: OpReturn | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_4:]] = OpFunction %[[#void:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb9:]] = OpLabel | ||
| ; CHECK: OpReturn | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_6:]] = OpFunction %[[#void:]] None %[[#]] | ||
| ; CHECK: %[[#bb10:]] = 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 void @_Z1Av() #0 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| ret void | ||
| } | ||
|
|
||
| ; 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 internal spir_func void @main() #0 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| call spir_func void @_Z1Av() #3 [ "convergencectrl"(token %0) ] | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent norecurse | ||
| define void @main.1() #2 { | ||
| entry: | ||
| call void @main() | ||
| ret void | ||
| } | ||
|
|
||
| attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "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} | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| ; 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 %} | ||
| ; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | spirv-sim --function=_Z7processv --wave=1 --expects=5 | ||
|
|
||
| ; | ||
| ; int process() { | ||
| ; int b = 0; | ||
| ; const int t = 50; | ||
| ; | ||
| ; switch(int d = 5) { | ||
| ; case t: | ||
| ; b = t; | ||
| ; case 4: | ||
| ; case 5: | ||
| ; b = 5; | ||
| ; break; | ||
| ; default: | ||
| ; break; | ||
| ; } | ||
| ; | ||
| ; return b; | ||
| ; } | ||
| ; | ||
| ; [numthreads(1, 1, 1)] | ||
| ; void main() { | ||
| ; process(); | ||
| ; } | ||
|
|
||
| ; CHECK: %[[#func_13:]] = OpFunction %[[#uint:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb25:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb26:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb27:]] %[[#bb28:]] | ||
| ; CHECK: %[[#bb27:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb29:]] None | ||
| ; CHECK: OpSwitch %[[#]] %[[#bb30:]] 50 %[[#bb31:]] 4 %[[#bb29:]] 5 %[[#bb32:]] | ||
| ; CHECK: %[[#bb28:]] = OpLabel | ||
| ; CHECK: %[[#bb30:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb29:]] | ||
| ; CHECK: %[[#bb31:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb29:]] | ||
| ; CHECK: %[[#bb32:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb29:]] | ||
| ; CHECK: %[[#bb29:]] = OpLabel | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb33:]] %[[#bb26:]] | ||
| ; CHECK: %[[#bb33:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb26:]] | ||
| ; CHECK: %[[#bb26:]] = OpLabel | ||
| ; CHECK: OpReturnValue %[[#]] | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_21:]] = OpFunction %[[#void:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb34:]] = OpLabel | ||
| ; CHECK: OpReturn | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_23:]] = OpFunction %[[#void:]] None %[[#]] | ||
| ; CHECK: %[[#bb35:]] = 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 @_Z7processv() #0 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| %b = alloca i32, align 4 | ||
| %t = alloca i32, align 4 | ||
| %d = alloca i32, align 4 | ||
| store i32 0, ptr %b, align 4 | ||
| store i32 50, 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 50, label %sw.bb | ||
| i32 4, label %sw.bb1 | ||
| i32 5, label %sw.bb1 | ||
| ] | ||
|
|
||
| sw.bb: ; preds = %entry | ||
| store i32 50, ptr %b, align 4 | ||
| br label %sw.bb1 | ||
|
|
||
| sw.bb1: ; preds = %entry, %entry, %sw.bb | ||
| store i32 5, ptr %b, align 4 | ||
| br label %sw.epilog | ||
|
|
||
| sw.default: ; preds = %entry | ||
| br label %sw.epilog | ||
|
|
||
| sw.epilog: ; preds = %sw.default, %sw.bb1 | ||
| %2 = load i32, ptr %b, align 4 | ||
| ret i32 %2 | ||
| } | ||
|
|
||
| ; 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 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) ] | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent norecurse | ||
| define void @main.1() #2 { | ||
| entry: | ||
| call void @main() | ||
| ret void | ||
| } | ||
|
|
||
| attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "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} | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,243 @@ | ||
| ; 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 %} | ||
| ; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | spirv-sim --function=_Z7processv --wave=1 --expects=5 | ||
|
|
||
| ; | ||
| ; int foo() { return 200; } | ||
| ; | ||
| ; int process() { | ||
| ; int a = 0; | ||
| ; int b = 0; | ||
| ; int c = 0; | ||
| ; const int r = 20; | ||
| ; const int s = 40; | ||
| ; const int t = 3*r+2*s; | ||
| ; | ||
| ; switch(int d = 5) { | ||
| ; case 1: | ||
| ; b += 1; | ||
| ; c += foo(); | ||
| ; case 2: | ||
| ; b += 2; | ||
| ; break; | ||
| ; case 3: | ||
| ; { | ||
| ; b += 3; | ||
| ; break; | ||
| ; } | ||
| ; case t: | ||
| ; b += t; | ||
| ; case 4: | ||
| ; case 5: | ||
| ; b += 5; | ||
| ; break; | ||
| ; case 6: { | ||
| ; case 7: | ||
| ; break;} | ||
| ; default: | ||
| ; break; | ||
| ; } | ||
| ; | ||
| ; return a + b + c; | ||
| ; } | ||
| ; | ||
| ; [numthreads(1, 1, 1)] | ||
| ; void main() { | ||
| ; 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 | ||
|
|
||
|
|
||
|
|
||
| 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 { | ||
| entry: | ||
| %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 | ||
| ] | ||
|
|
||
| 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.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.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.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.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.bb11: ; preds = %entry | ||
| br label %sw.bb12 | ||
|
|
||
| sw.bb12: ; preds = %entry, %sw.bb11 | ||
| br label %sw.epilog | ||
|
|
||
| sw.default: ; preds = %entry | ||
| br label %sw.epilog | ||
|
|
||
| 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) ] | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent norecurse | ||
| define void @main.1() #2 { | ||
| entry: | ||
| call void @main() | ||
| ret void | ||
| } | ||
|
|
||
| attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "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} | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| ; 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 %} | ||
|
|
||
| ; | ||
| ; [numthreads(1, 1, 1)] | ||
| ; void main() { | ||
| ; /////////////////////////////// | ||
| ; // 32-bit int literal switch // | ||
| ; /////////////////////////////// | ||
| ; switch (0) { | ||
| ; case 0: | ||
| ; return; | ||
| ; default: | ||
| ; return; | ||
| ; } | ||
| ; | ||
| ; /////////////////////////////// | ||
| ; // 64-bit int literal switch // | ||
| ; /////////////////////////////// | ||
| ; switch (12345678910) { | ||
| ; case 12345678910: | ||
| ; return; | ||
| ; } | ||
| ; | ||
| ; return; | ||
| ; } | ||
|
|
||
| ; CHECK: %[[#func_3:]] = OpFunction %[[#void:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb6:]] = OpLabel | ||
| ; CHECK: OpReturn | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_4:]] = OpFunction %[[#void:]] None %[[#]] | ||
| ; CHECK: %[[#bb7:]] = 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 internal spir_func void @main() #0 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent norecurse | ||
| define void @main.1() #1 { | ||
| entry: | ||
| call void @main() | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none) | ||
| declare token @llvm.experimental.convergence.entry() #2 | ||
|
|
||
| attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } | ||
| attributes #1 = { convergent norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } | ||
| attributes #2 = { convergent nocallback nofree nosync nounwind willreturn memory(none) } | ||
|
|
||
| !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} | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,165 @@ | ||
| ; 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 %} | ||
|
|
||
| ; | ||
| ; int foo() { return 200; } | ||
| ; | ||
| ; [numthreads(1, 1, 1)] | ||
| ; void main() { | ||
| ; int result; | ||
| ; | ||
| ; int a = 0; | ||
| ; switch(a) { | ||
| ; case -3: | ||
| ; result = -300; | ||
| ; break; | ||
| ; case 0: | ||
| ; result = 0; | ||
| ; break; | ||
| ; case 1: | ||
| ; result = 100; | ||
| ; break; | ||
| ; case 2: | ||
| ; result = foo(); | ||
| ; break; | ||
| ; default: | ||
| ; result = 777; | ||
| ; break; | ||
| ; } | ||
| ; | ||
| ; switch(int c = a) { | ||
| ; case -4: | ||
| ; result = -400; | ||
| ; break; | ||
| ; case 4: | ||
| ; result = 400; | ||
| ; break; | ||
| ; } | ||
| ; } | ||
|
|
||
| ; CHECK: %[[#func_14:]] = OpFunction %[[#uint:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb25:]] = OpLabel | ||
| ; CHECK: OpReturnValue %[[#]] | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_15:]] = OpFunction %[[#void:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb26:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb27:]] None | ||
| ; CHECK: OpSwitch %[[#]] %[[#bb28:]] 4294967293 %[[#bb29:]] 0 %[[#bb30:]] 1 %[[#bb31:]] 2 %[[#bb32:]] | ||
| ; CHECK: %[[#bb28:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb27:]] | ||
| ; CHECK: %[[#bb29:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb27:]] | ||
| ; CHECK: %[[#bb30:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb27:]] | ||
| ; CHECK: %[[#bb31:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb27:]] | ||
| ; CHECK: %[[#bb32:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb27:]] | ||
| ; CHECK: %[[#bb27:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb33:]] None | ||
| ; CHECK: OpSwitch %[[#]] %[[#bb33:]] 4294967292 %[[#bb34:]] 4 %[[#bb35:]] | ||
| ; CHECK: %[[#bb34:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb33:]] | ||
| ; CHECK: %[[#bb35:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb33:]] | ||
| ; CHECK: %[[#bb33:]] = OpLabel | ||
| ; CHECK: OpReturn | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_23:]] = OpFunction %[[#void:]] None %[[#]] | ||
| ; CHECK: %[[#bb36:]] = 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 { | ||
| entry: | ||
| %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 internal spir_func void @main() #0 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| %result = alloca i32, align 4 | ||
| %a = alloca i32, align 4 | ||
| %c = alloca i32, align 4 | ||
| store i32 0, ptr %a, align 4 | ||
| %1 = load i32, ptr %a, align 4 | ||
| switch i32 %1, label %sw.default [ | ||
| i32 -3, label %sw.bb | ||
| i32 0, label %sw.bb1 | ||
| i32 1, label %sw.bb2 | ||
| i32 2, label %sw.bb3 | ||
| ] | ||
|
|
||
| sw.bb: ; preds = %entry | ||
| store i32 -300, ptr %result, align 4 | ||
| br label %sw.epilog | ||
|
|
||
| sw.bb1: ; preds = %entry | ||
| store i32 0, ptr %result, align 4 | ||
| br label %sw.epilog | ||
|
|
||
| sw.bb2: ; preds = %entry | ||
| store i32 100, ptr %result, align 4 | ||
| br label %sw.epilog | ||
|
|
||
| sw.bb3: ; preds = %entry | ||
| %call4 = call spir_func noundef i32 @_Z3foov() #3 [ "convergencectrl"(token %0) ] | ||
| store i32 %call4, ptr %result, align 4 | ||
| br label %sw.epilog | ||
|
|
||
| sw.default: ; preds = %entry | ||
| store i32 777, ptr %result, align 4 | ||
| br label %sw.epilog | ||
|
|
||
| sw.epilog: ; preds = %sw.default, %sw.bb3, %sw.bb2, %sw.bb1, %sw.bb | ||
| %2 = load i32, ptr %a, align 4 | ||
| store i32 %2, ptr %c, align 4 | ||
| %3 = load i32, ptr %c, align 4 | ||
| switch i32 %3, label %sw.epilog7 [ | ||
| i32 -4, label %sw.bb5 | ||
| i32 4, label %sw.bb6 | ||
| ] | ||
|
|
||
| sw.bb5: ; preds = %sw.epilog | ||
| store i32 -400, ptr %result, align 4 | ||
| br label %sw.epilog7 | ||
|
|
||
| sw.bb6: ; preds = %sw.epilog | ||
| store i32 400, ptr %result, align 4 | ||
| br label %sw.epilog7 | ||
|
|
||
| sw.epilog7: ; preds = %sw.epilog, %sw.bb6, %sw.bb5 | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent norecurse | ||
| define void @main.1() #2 { | ||
| entry: | ||
| call void @main() | ||
| ret void | ||
| } | ||
|
|
||
| attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "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} | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,190 @@ | ||
| ; 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 %} | ||
|
|
||
| ; | ||
| ; int foo() { return true; } | ||
| ; | ||
| ; [numthreads(1, 1, 1)] | ||
| ; void main() { | ||
| ; int val = 0; | ||
| ; int i = 0; | ||
| ; | ||
| ; while (i < 10) { | ||
| ; val = i; | ||
| ; if (val > 5) { | ||
| ; break; | ||
| ; } | ||
| ; | ||
| ; if (val > 6) { | ||
| ; break; | ||
| ; break; // No SPIR-V should be emitted for this statement. | ||
| ; val++; // No SPIR-V should be emitted for this statement. | ||
| ; while(true); // No SPIR-V should be emitted for this statement. | ||
| ; --i; // No SPIR-V should be emitted for this statement. | ||
| ; } | ||
| ; } | ||
| ; | ||
| ; //////////////////////////////////////////////////////////////////////////////// | ||
| ; // Nested while loops with break statements // | ||
| ; // Each break statement should branch to the corresponding loop's break block // | ||
| ; //////////////////////////////////////////////////////////////////////////////// | ||
| ; | ||
| ; while (true) { | ||
| ; i++; | ||
| ; while(i<20) { | ||
| ; val = i; | ||
| ; {{break;}} | ||
| ; } | ||
| ; --i; | ||
| ; break; | ||
| ; } | ||
| ; } | ||
|
|
||
| ; CHECK: %[[#func_16:]] = OpFunction %[[#uint:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb37:]] = OpLabel | ||
| ; CHECK: OpReturnValue %[[#]] | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_17:]] = OpFunction %[[#void:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb38:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb39:]] | ||
| ; CHECK: %[[#bb39:]] = OpLabel | ||
| ; CHECK: OpLoopMerge %[[#bb40:]] %[[#bb41:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb42:]] %[[#bb40:]] | ||
| ; CHECK: %[[#bb42:]] = OpLabel | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb40:]] %[[#bb43:]] | ||
| ; CHECK: %[[#bb43:]] = OpLabel | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb40:]] %[[#bb41:]] | ||
| ; CHECK: %[[#bb40:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb44:]] None | ||
| ; CHECK: OpSwitch %[[#]] %[[#bb44:]] 1 %[[#bb44:]] 2 %[[#bb44:]] | ||
| ; CHECK: %[[#bb41:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb39:]] | ||
| ; CHECK: %[[#bb44:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb45:]] | ||
| ; CHECK: %[[#bb45:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb46:]] | ||
| ; CHECK: %[[#bb46:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb47:]] | ||
| ; CHECK: %[[#bb47:]] = OpLabel | ||
| ; CHECK: OpSelectionMerge %[[#bb48:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb49:]] %[[#bb48:]] | ||
| ; CHECK: %[[#bb49:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb48:]] | ||
| ; CHECK: %[[#bb48:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb50:]] | ||
| ; CHECK: %[[#bb50:]] = OpLabel | ||
| ; CHECK: OpReturn | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_35:]] = OpFunction %[[#void:]] None %[[#]] | ||
| ; CHECK: %[[#bb51:]] = 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 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| ret i32 1 | ||
| } | ||
|
|
||
| ; 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 internal spir_func void @main() #0 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| %val = alloca i32, align 4 | ||
| %i = alloca i32, align 4 | ||
| store i32 0, ptr %val, align 4 | ||
| store i32 0, ptr %i, align 4 | ||
| br label %while.cond | ||
|
|
||
| while.cond: ; preds = %if.end4, %entry | ||
| %1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ] | ||
| %2 = load i32, ptr %i, align 4 | ||
| %cmp = icmp slt i32 %2, 10 | ||
| br i1 %cmp, label %while.body, label %while.end | ||
|
|
||
| while.body: ; preds = %while.cond | ||
| %3 = load i32, ptr %i, align 4 | ||
| store i32 %3, ptr %val, align 4 | ||
| %4 = load i32, ptr %val, align 4 | ||
| %cmp1 = icmp sgt i32 %4, 5 | ||
| br i1 %cmp1, label %if.then, label %if.end | ||
|
|
||
| if.then: ; preds = %while.body | ||
| br label %while.end | ||
|
|
||
| if.end: ; preds = %while.body | ||
| %5 = load i32, ptr %val, align 4 | ||
| %cmp2 = icmp sgt i32 %5, 6 | ||
| br i1 %cmp2, label %if.then3, label %if.end4 | ||
|
|
||
| if.then3: ; preds = %if.end | ||
| br label %while.end | ||
|
|
||
| if.end4: ; preds = %if.end | ||
| br label %while.cond | ||
|
|
||
| while.end: ; preds = %if.then3, %if.then, %while.cond | ||
| br label %while.cond5 | ||
|
|
||
| while.cond5: ; preds = %while.end | ||
| %6 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ] | ||
| br label %while.body6 | ||
|
|
||
| while.body6: ; preds = %while.cond5 | ||
| %7 = load i32, ptr %i, align 4 | ||
| %inc = add nsw i32 %7, 1 | ||
| store i32 %inc, ptr %i, align 4 | ||
| br label %while.cond7 | ||
|
|
||
| while.cond7: ; preds = %while.body6 | ||
| %8 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %6) ] | ||
| %9 = load i32, ptr %i, align 4 | ||
| %cmp8 = icmp slt i32 %9, 20 | ||
| br i1 %cmp8, label %while.body9, label %while.end10 | ||
|
|
||
| while.body9: ; preds = %while.cond7 | ||
| %10 = load i32, ptr %i, align 4 | ||
| store i32 %10, ptr %val, align 4 | ||
| br label %while.end10 | ||
|
|
||
| while.end10: ; preds = %while.body9, %while.cond7 | ||
| %11 = load i32, ptr %i, align 4 | ||
| %dec = add nsw i32 %11, -1 | ||
| store i32 %dec, ptr %i, align 4 | ||
| br label %while.end11 | ||
|
|
||
| while.end11: ; preds = %while.end10 | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent norecurse | ||
| define void @main.1() #2 { | ||
| entry: | ||
| call void @main() | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none) | ||
| declare token @llvm.experimental.convergence.loop() #1 | ||
|
|
||
| attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "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" } | ||
|
|
||
| !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} | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,198 @@ | ||
| ; 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 %} | ||
|
|
||
| ; | ||
| ; int foo() { return true; } | ||
| ; | ||
| ; [numthreads(1, 1, 1)] | ||
| ; void main() { | ||
| ; int val = 0; | ||
| ; int i = 0; | ||
| ; | ||
| ; while (i < 10) { | ||
| ; val = i; | ||
| ; if (val > 5) { | ||
| ; continue; | ||
| ; } | ||
| ; | ||
| ; if (val > 6) { | ||
| ; {{continue;}} | ||
| ; val++; // No SPIR-V should be emitted for this statement. | ||
| ; continue; // No SPIR-V should be emitted for this statement. | ||
| ; while(true); // No SPIR-V should be emitted for this statement. | ||
| ; --i; // No SPIR-V should be emitted for this statement. | ||
| ; } | ||
| ; | ||
| ; } | ||
| ; | ||
| ; ////////////////////////////////////////////////////////////////////////////////////// | ||
| ; // Nested while loops with continue statements // | ||
| ; // Each continue statement should branch to the corresponding loop's continue block // | ||
| ; ////////////////////////////////////////////////////////////////////////////////////// | ||
| ; | ||
| ; while (true) { | ||
| ; i++; | ||
| ; | ||
| ; while(i<20) { | ||
| ; val = i; | ||
| ; continue; | ||
| ; } | ||
| ; --i; | ||
| ; continue; | ||
| ; continue; // No SPIR-V should be emitted for this statement. | ||
| ; | ||
| ; } | ||
| ; } | ||
|
|
||
| ; CHECK: %[[#func_15:]] = OpFunction %[[#uint:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb35:]] = 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: OpFunctionEnd | ||
| ; CHECK: %[[#func_33:]] = OpFunction %[[#void:]] None %[[#]] | ||
| ; CHECK: %[[#bb52:]] = 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 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| ret i32 1 | ||
| } | ||
|
|
||
| ; 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 internal spir_func void @main() #0 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| %val = alloca i32, align 4 | ||
| %i = alloca i32, align 4 | ||
| store i32 0, ptr %val, align 4 | ||
| store i32 0, ptr %i, align 4 | ||
| br label %while.cond | ||
|
|
||
| while.cond: ; preds = %if.end4, %if.then3, %if.then, %entry | ||
| %1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ] | ||
| %2 = load i32, ptr %i, align 4 | ||
| %cmp = icmp slt i32 %2, 10 | ||
| br i1 %cmp, label %while.body, label %while.end | ||
|
|
||
| while.body: ; preds = %while.cond | ||
| %3 = load i32, ptr %i, align 4 | ||
| store i32 %3, ptr %val, align 4 | ||
| %4 = load i32, ptr %val, align 4 | ||
| %cmp1 = icmp sgt i32 %4, 5 | ||
| br i1 %cmp1, label %if.then, label %if.end | ||
|
|
||
| if.then: ; preds = %while.body | ||
| br label %while.cond | ||
|
|
||
| if.end: ; preds = %while.body | ||
| %5 = load i32, ptr %val, align 4 | ||
| %cmp2 = icmp sgt i32 %5, 6 | ||
| br i1 %cmp2, label %if.then3, label %if.end4 | ||
|
|
||
| if.then3: ; preds = %if.end | ||
| br label %while.cond | ||
|
|
||
| if.end4: ; preds = %if.end | ||
| br label %while.cond | ||
|
|
||
| while.end: ; preds = %while.cond | ||
| br label %while.cond5 | ||
|
|
||
| while.cond5: ; preds = %while.end10, %while.end | ||
| %6 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ] | ||
| br label %while.body6 | ||
|
|
||
| while.body6: ; preds = %while.cond5 | ||
| %7 = load i32, ptr %i, align 4 | ||
| %inc = add nsw i32 %7, 1 | ||
| store i32 %inc, ptr %i, align 4 | ||
| br label %while.cond7 | ||
|
|
||
| while.cond7: ; preds = %while.body9, %while.body6 | ||
| %8 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %6) ] | ||
| %9 = load i32, ptr %i, align 4 | ||
| %cmp8 = icmp slt i32 %9, 20 | ||
| br i1 %cmp8, label %while.body9, label %while.end10 | ||
|
|
||
| while.body9: ; preds = %while.cond7 | ||
| %10 = load i32, ptr %i, align 4 | ||
| store i32 %10, ptr %val, align 4 | ||
| br label %while.cond7 | ||
|
|
||
| while.end10: ; preds = %while.cond7 | ||
| %11 = load i32, ptr %i, align 4 | ||
| %dec = add nsw i32 %11, -1 | ||
| store i32 %dec, ptr %i, align 4 | ||
| br label %while.cond5 | ||
| } | ||
|
|
||
| ; Function Attrs: convergent norecurse | ||
| define void @main.1() #2 { | ||
| entry: | ||
| call void @main() | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none) | ||
| declare token @llvm.experimental.convergence.loop() #1 | ||
|
|
||
| attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "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" } | ||
|
|
||
| !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} | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,157 @@ | ||
| ; 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 %} | ||
|
|
||
| ; | ||
| ; [numthreads(1, 1, 1)] | ||
| ; void main() { | ||
| ; int val=0, i=0, j=0, k=0; | ||
| ; | ||
| ; while (i < 10) { | ||
| ; val = val + i; | ||
| ; while (j < 20) { | ||
| ; while (k < 30) { | ||
| ; val = val + k; | ||
| ; ++k; | ||
| ; } | ||
| ; | ||
| ; val = val * 2; | ||
| ; ++j; | ||
| ; } | ||
| ; | ||
| ; ++i; | ||
| ; } | ||
| ; } | ||
|
|
||
| ; CHECK: %[[#func_12:]] = OpFunction %[[#void:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb39:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb40:]] | ||
| ; 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: OpReturn | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_37:]] = OpFunction %[[#void:]] None %[[#]] | ||
| ; CHECK: %[[#bb50:]] = 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 internal spir_func void @main() #0 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| %val = alloca i32, align 4 | ||
| %i = alloca i32, align 4 | ||
| %j = alloca i32, align 4 | ||
| %k = alloca i32, align 4 | ||
| store i32 0, ptr %val, align 4 | ||
| store i32 0, ptr %i, align 4 | ||
| store i32 0, ptr %j, align 4 | ||
| store i32 0, ptr %k, align 4 | ||
| br label %while.cond | ||
|
|
||
| while.cond: ; preds = %while.end9, %entry | ||
| %1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ] | ||
| %2 = load i32, ptr %i, align 4 | ||
| %cmp = icmp slt i32 %2, 10 | ||
| br i1 %cmp, label %while.body, label %while.end11 | ||
|
|
||
| while.body: ; preds = %while.cond | ||
| %3 = load i32, ptr %val, align 4 | ||
| %4 = load i32, ptr %i, align 4 | ||
| %add = add nsw i32 %3, %4 | ||
| store i32 %add, ptr %val, align 4 | ||
| br label %while.cond1 | ||
|
|
||
| while.cond1: ; preds = %while.end, %while.body | ||
| %5 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %1) ] | ||
| %6 = load i32, ptr %j, align 4 | ||
| %cmp2 = icmp slt i32 %6, 20 | ||
| br i1 %cmp2, label %while.body3, label %while.end9 | ||
|
|
||
| while.body3: ; preds = %while.cond1 | ||
| br label %while.cond4 | ||
|
|
||
| while.cond4: ; preds = %while.body6, %while.body3 | ||
| %7 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %5) ] | ||
| %8 = load i32, ptr %k, align 4 | ||
| %cmp5 = icmp slt i32 %8, 30 | ||
| br i1 %cmp5, label %while.body6, label %while.end | ||
|
|
||
| while.body6: ; preds = %while.cond4 | ||
| %9 = load i32, ptr %val, align 4 | ||
| %10 = load i32, ptr %k, align 4 | ||
| %add7 = add nsw i32 %9, %10 | ||
| store i32 %add7, ptr %val, align 4 | ||
| %11 = load i32, ptr %k, align 4 | ||
| %inc = add nsw i32 %11, 1 | ||
| store i32 %inc, ptr %k, align 4 | ||
| br label %while.cond4 | ||
|
|
||
| while.end: ; preds = %while.cond4 | ||
| %12 = load i32, ptr %val, align 4 | ||
| %mul = mul nsw i32 %12, 2 | ||
| store i32 %mul, ptr %val, align 4 | ||
| %13 = load i32, ptr %j, align 4 | ||
| %inc8 = add nsw i32 %13, 1 | ||
| store i32 %inc8, ptr %j, align 4 | ||
| br label %while.cond1 | ||
|
|
||
| while.end9: ; preds = %while.cond1 | ||
| %14 = load i32, ptr %i, align 4 | ||
| %inc10 = add nsw i32 %14, 1 | ||
| store i32 %inc10, ptr %i, align 4 | ||
| br label %while.cond | ||
|
|
||
| while.end11: ; preds = %while.cond | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent norecurse | ||
| define void @main.1() #1 { | ||
| entry: | ||
| call void @main() | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none) | ||
| declare token @llvm.experimental.convergence.entry() #2 | ||
|
|
||
| ; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none) | ||
| declare token @llvm.experimental.convergence.loop() #2 | ||
|
|
||
| attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } | ||
| attributes #1 = { convergent norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } | ||
| attributes #2 = { convergent nocallback nofree nosync nounwind willreturn memory(none) } | ||
|
|
||
| !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} | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| ; 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 %} | ||
|
|
||
| ; | ||
| ; int foo() { return true; } | ||
| ; | ||
| ; [numthreads(1, 1, 1)] | ||
| ; void main() { | ||
| ; int val = 0; | ||
| ; int i = 0; | ||
| ; | ||
| ; ////////////////////////// | ||
| ; //// Basic while loop //// | ||
| ; ////////////////////////// | ||
| ; while (i < 10) { | ||
| ; val = i; | ||
| ; } | ||
| ; | ||
| ; ////////////////////////// | ||
| ; //// infinite loop //// | ||
| ; ////////////////////////// | ||
| ; while (true) { | ||
| ; val = 0; | ||
| ; } | ||
| ; | ||
| ; ////////////////////////// | ||
| ; //// Null Body //// | ||
| ; ////////////////////////// | ||
| ; while (val < 20) | ||
| ; ; | ||
| ; | ||
| ; //////////////////////////////////////////////////////////////// | ||
| ; //// Condition variable has VarDecl //// | ||
| ; //// foo() returns an integer which must be cast to boolean //// | ||
| ; //////////////////////////////////////////////////////////////// | ||
| ; while (int a = foo()) { | ||
| ; val = a; | ||
| ; } | ||
| ; | ||
| ; } | ||
|
|
||
| ; CHECK: %[[#func_11:]] = OpFunction %[[#uint:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb20:]] = OpLabel | ||
| ; CHECK: OpReturnValue %[[#]] | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_12:]] = OpFunction %[[#void:]] DontInline %[[#]] | ||
| ; CHECK: %[[#bb21:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb22:]] | ||
| ; CHECK: %[[#bb22:]] = OpLabel | ||
| ; CHECK: OpLoopMerge %[[#bb23:]] %[[#bb24:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb24:]] %[[#bb23:]] | ||
| ; CHECK: %[[#bb24:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb22:]] | ||
| ; CHECK: %[[#bb23:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb25:]] | ||
| ; CHECK: %[[#bb25:]] = OpLabel | ||
| ; CHECK: OpLoopMerge %[[#bb26:]] %[[#bb27:]] None | ||
| ; CHECK: OpBranchConditional %[[#]] %[[#bb26:]] %[[#bb27:]] | ||
| ; CHECK: %[[#bb27:]] = OpLabel | ||
| ; CHECK: OpBranch %[[#bb25:]] | ||
| ; CHECK: %[[#bb26:]] = OpLabel | ||
| ; CHECK: OpFunctionEnd | ||
| ; CHECK: %[[#func_18:]] = OpFunction %[[#void:]] None %[[#]] | ||
| ; CHECK: %[[#bb28:]] = 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 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| ret i32 1 | ||
| } | ||
|
|
||
| ; 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 internal spir_func void @main() #0 { | ||
| entry: | ||
| %0 = call token @llvm.experimental.convergence.entry() | ||
| %val = alloca i32, align 4 | ||
| %i = alloca i32, align 4 | ||
| store i32 0, ptr %val, align 4 | ||
| store i32 0, ptr %i, align 4 | ||
| br label %while.cond | ||
|
|
||
| while.cond: ; preds = %while.body, %entry | ||
| %1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ] | ||
| %2 = load i32, ptr %i, align 4 | ||
| %cmp = icmp slt i32 %2, 10 | ||
| br i1 %cmp, label %while.body, label %while.end | ||
|
|
||
| while.body: ; preds = %while.cond | ||
| %3 = load i32, ptr %i, align 4 | ||
| store i32 %3, ptr %val, align 4 | ||
| br label %while.cond | ||
|
|
||
| while.end: ; preds = %while.cond | ||
| br label %while.cond1 | ||
|
|
||
| while.cond1: ; preds = %while.body2, %while.end | ||
| %4 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ] | ||
| br label %while.body2 | ||
|
|
||
| while.body2: ; preds = %while.cond1 | ||
| store i32 0, ptr %val, align 4 | ||
| br label %while.cond1 | ||
| } | ||
|
|
||
| ; Function Attrs: convergent norecurse | ||
| define void @main.1() #2 { | ||
| entry: | ||
| call void @main() | ||
| ret void | ||
| } | ||
|
|
||
| ; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none) | ||
| declare token @llvm.experimental.convergence.loop() #1 | ||
|
|
||
| attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "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" } | ||
|
|
||
| !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} | ||
|
|
||
|
|