xref: /llvm-project/llvm/test/CodeGen/SPIRV/structurizer/condition-linear.ll (revision 53326ee0cf45fce3f80e2e98638dd27edb20c516)
1; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | FileCheck %s
2; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan-compute %s -o - -filetype=obj | spirv-val %}
3
4target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
5target triple = "spirv-unknown-vulkan-compute"
6
7; Function Attrs: convergent noinline nounwind optnone
8define spir_func noundef i32 @fn() #4 {
9entry:
10  %0 = call token @llvm.experimental.convergence.entry()
11  ret i32 1
12}
13
14; Function Attrs: convergent noinline nounwind optnone
15define spir_func noundef i32 @fn1() #4 {
16entry:
17  %0 = call token @llvm.experimental.convergence.entry()
18  ret i32 0
19}
20
21; Function Attrs: convergent noinline nounwind optnone
22define spir_func noundef i32 @fn2() #4 {
23entry:
24  %0 = call token @llvm.experimental.convergence.entry()
25  ret i32 1
26}
27
28
29; CHECK-DAG:             OpName %[[#reg_0:]] "cond.reg2mem"
30; CHECK-DAG:             OpName %[[#reg_1:]] "cond9.reg2mem"
31
32define internal spir_func void @main() #0 {
33; CHECK:                  OpSelectionMerge %[[#cond1_merge:]] None
34; CHECK:                  OpBranchConditional %[[#]] %[[#cond1_true:]] %[[#cond1_false:]]
35entry:
36  %0 = call token @llvm.experimental.convergence.entry()
37  %a = alloca i32, align 4
38  %b = alloca i32, align 4
39  br i1 true, label %cond1_true, label %cond1_false
40
41; CHECK:  %[[#cond1_false]] = OpLabel
42; CHECK:                      OpStore %[[#reg_0]] %[[#]]
43; CHECK:                      OpBranch %[[#cond1_merge]]
44cond1_false:
45  %2 = load i32, ptr %b, align 4
46  br label %cond1_merge
47
48; CHECK:  %[[#cond1_true]] = OpLabel
49; CHECK:                     OpStore %[[#reg_0]] %[[#]]
50; CHECK:                     OpBranch %[[#cond1_merge]]
51cond1_true:
52  %3 = load i32, ptr %a, align 4
53  br label %cond1_merge
54
55; CHECK: %[[#cond1_merge]] = OpLabel
56; CHECK:        %[[#tmp:]] = OpLoad %[[#]] %[[#reg_0]]
57; CHECK:       %[[#cond:]] = OpINotEqual %[[#]] %[[#tmp]] %[[#]]
58; CHECK:                     OpSelectionMerge %[[#cond2_merge:]] None
59; CHECK:                     OpBranchConditional %[[#cond]] %[[#cond2_true:]] %[[#cond2_merge]]
60cond1_merge:
61  %cond = phi i32 [ %3, %cond1_true ], [ %2, %cond1_false ]
62  %tobool1 = icmp ne i32 %cond, 0
63  br i1 %tobool1, label %cond2_true, label %cond2_merge
64
65; CHECK:  %[[#cond2_true]] = OpLabel
66; CHECK:                     OpBranch %[[#cond2_merge]]
67cond2_true:
68  store i32 0, ptr %a
69  br label %cond2_merge
70
71; CHECK:    %[[#cond2_merge]] = OpLabel
72; CHECK:                        OpFunctionCall
73; CHECK:                        OpSelectionMerge %[[#cond3_merge:]] None
74; CHECK:                        OpBranchConditional %[[#]] %[[#cond3_true:]] %[[#cond3_false:]]
75cond2_merge:
76  %call2 = call spir_func noundef i32 @fn() #4 [ "convergencectrl"(token %0) ]
77  br i1 true, label %cond3_true, label %cond3_false
78
79; CHECK:  %[[#cond3_false]] = OpLabel
80; CHECK:                      OpFunctionCall
81; CHECK:                      OpStore %[[#reg_1]] %[[#]]
82; CHECK:                      OpBranch %[[#cond3_merge]]
83cond3_false:
84  %call7 = call spir_func noundef i32 @fn2() #4 [ "convergencectrl"(token %0) ]
85  br label %cond3_merge
86
87; CHECK:  %[[#cond3_true]] = OpLabel
88; CHECK:                     OpFunctionCall
89; CHECK:                     OpStore %[[#reg_1]] %[[#]]
90; CHECK:                     OpBranch %[[#cond3_merge]]
91cond3_true:
92  %call5 = call spir_func noundef i32 @fn1() #4 [ "convergencectrl"(token %0) ]
93  br label %cond3_merge
94
95; CHECK:  %[[#cond3_merge]] = OpLabel
96; CHECK:         %[[#tmp:]] = OpLoad %[[#]] %[[#reg_1]]
97; CHECK:       %[[#cond:]] = OpINotEqual %[[#]] %[[#tmp]] %[[#]]
98; CHECK:                      OpSelectionMerge %[[#cond4_merge:]] None
99; CHECK:                      OpBranchConditional %[[#cond]] %[[#cond4_true:]] %[[#cond4_merge]]
100cond3_merge:
101  %cond9 = phi i32 [ %call5, %cond3_true ], [ %call7, %cond3_false ]
102  %tobool10 = icmp ne i32 %cond9, 0
103  br i1 %tobool10, label %cond4_true, label %cond4_merge
104
105; CHECK:  %[[#cond4_true]] = OpLabel
106; CHECK:                     OpBranch %[[#cond4_merge]]
107cond4_true:
108  store i32 0, ptr %a
109  br label %cond4_merge
110
111; CHECK:  %[[#cond4_merge]] = OpLabel
112; CHECK:                  OpReturn
113cond4_merge:
114  ret void
115}
116
117declare token @llvm.experimental.convergence.entry() #2
118
119attributes #0 = { convergent noinline norecurse nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
120attributes #1 = { convergent norecurse "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
121attributes #2 = { convergent nocallback nofree nosync nounwind willreturn memory(none) }
122attributes #3 = { convergent }
123attributes #4 = { convergent noinline nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
124
125!llvm.module.flags = !{!0, !1}
126
127!0 = !{i32 1, !"wchar_size", i32 4}
128!1 = !{i32 4, !"dx.disable_optimizations", i32 1}
129