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 %}
10 ; for (int i = 0; a && b; ++i) {
14 ; for (int i = 0; a || b; ++i) {
20 ; for (int i = 0; a && ((a || b) && b); ++i) {
26 ; for (int i = 0; a ? a : b; ++i) {
33 ; for (int i = 0; x + (x && y); ++i) {
40 ; [numthreads(1, 1, 1)]
45 ; CHECK: %[[#func_14:]] = OpFunction %[[#uint:]] DontInline %[[#]]
46 ; CHECK: %[[#bb87:]] = OpLabel
47 ; CHECK: OpBranch %[[#bb88:]]
48 ; CHECK: %[[#bb88:]] = OpLabel
49 ; CHECK: OpLoopMerge %[[#bb89:]] %[[#bb90:]] None
50 ; CHECK: OpBranch %[[#bb91:]]
51 ; CHECK: %[[#bb91:]] = OpLabel
52 ; CHECK: OpSelectionMerge %[[#bb92:]] None
53 ; CHECK: OpBranchConditional %[[#]] %[[#bb93:]] %[[#bb92:]]
54 ; CHECK: %[[#bb93:]] = OpLabel
55 ; CHECK: OpBranch %[[#bb92:]]
56 ; CHECK: %[[#bb92:]] = OpLabel
57 ; CHECK: OpBranchConditional %[[#]] %[[#bb94:]] %[[#bb89:]]
58 ; CHECK: %[[#bb94:]] = OpLabel
59 ; CHECK: OpBranch %[[#bb90:]]
60 ; CHECK: %[[#bb89:]] = OpLabel
61 ; CHECK: OpBranch %[[#bb95:]]
62 ; CHECK: %[[#bb90:]] = OpLabel
63 ; CHECK: OpBranch %[[#bb88:]]
64 ; CHECK: %[[#bb95:]] = OpLabel
65 ; CHECK: OpLoopMerge %[[#bb96:]] %[[#bb97:]] None
66 ; CHECK: OpBranch %[[#bb98:]]
67 ; CHECK: %[[#bb98:]] = OpLabel
68 ; CHECK: OpSelectionMerge %[[#bb99:]] None
69 ; CHECK: OpBranchConditional %[[#]] %[[#bb99:]] %[[#bb100:]]
70 ; CHECK: %[[#bb100:]] = OpLabel
71 ; CHECK: OpBranch %[[#bb99:]]
72 ; CHECK: %[[#bb99:]] = OpLabel
73 ; CHECK: OpBranchConditional %[[#]] %[[#bb101:]] %[[#bb96:]]
74 ; CHECK: %[[#bb101:]] = OpLabel
75 ; CHECK: OpBranch %[[#bb97:]]
76 ; CHECK: %[[#bb96:]] = OpLabel
77 ; CHECK: OpBranch %[[#bb102:]]
78 ; CHECK: %[[#bb97:]] = OpLabel
79 ; CHECK: OpBranch %[[#bb95:]]
80 ; CHECK: %[[#bb102:]] = OpLabel
81 ; CHECK: OpLoopMerge %[[#bb103:]] %[[#bb104:]] None
82 ; CHECK: OpBranch %[[#bb105:]]
83 ; CHECK: %[[#bb105:]] = OpLabel
84 ; CHECK: OpSelectionMerge %[[#bb106:]] None
85 ; CHECK: OpBranchConditional %[[#]] %[[#bb107:]] %[[#bb106:]]
86 ; CHECK: %[[#bb107:]] = OpLabel
87 ; CHECK: OpSelectionMerge %[[#bb108:]] None
88 ; CHECK: OpBranchConditional %[[#]] %[[#bb109:]] %[[#bb110:]]
89 ; CHECK: %[[#bb109:]] = OpLabel
90 ; CHECK: OpSelectionMerge %[[#bb111:]] None
91 ; CHECK: OpBranchConditional %[[#]] %[[#bb111:]] %[[#bb112:]]
92 ; CHECK: %[[#bb110:]] = OpLabel
93 ; CHECK: %[[#bb112:]] = OpLabel
94 ; CHECK: OpBranchConditional %[[#]] %[[#bb111:]] %[[#bb113:]]
95 ; CHECK: %[[#bb113:]] = OpLabel
96 ; CHECK: OpBranch %[[#bb111:]]
97 ; CHECK: %[[#bb111:]] = OpLabel
98 ; CHECK: OpBranchConditional %[[#]] %[[#bb114:]] %[[#bb108:]]
99 ; CHECK: %[[#bb114:]] = OpLabel
100 ; CHECK: OpBranch %[[#bb108:]]
101 ; CHECK: %[[#bb108:]] = OpLabel
102 ; CHECK: OpBranch %[[#bb106:]]
103 ; CHECK: %[[#bb106:]] = OpLabel
104 ; CHECK: OpBranchConditional %[[#]] %[[#bb115:]] %[[#bb103:]]
105 ; CHECK: %[[#bb115:]] = OpLabel
106 ; CHECK: OpBranch %[[#bb104:]]
107 ; CHECK: %[[#bb103:]] = OpLabel
108 ; CHECK: OpBranch %[[#bb116:]]
109 ; CHECK: %[[#bb104:]] = OpLabel
110 ; CHECK: OpBranch %[[#bb102:]]
111 ; CHECK: %[[#bb116:]] = OpLabel
112 ; CHECK: OpLoopMerge %[[#bb117:]] %[[#bb118:]] None
113 ; CHECK: OpBranch %[[#bb119:]]
114 ; CHECK: %[[#bb119:]] = OpLabel
115 ; CHECK: OpSelectionMerge %[[#bb120:]] None
116 ; CHECK: OpBranchConditional %[[#]] %[[#bb121:]] %[[#bb122:]]
117 ; CHECK: %[[#bb121:]] = OpLabel
118 ; CHECK: OpBranch %[[#bb120:]]
119 ; CHECK: %[[#bb122:]] = OpLabel
120 ; CHECK: OpBranch %[[#bb120:]]
121 ; CHECK: %[[#bb120:]] = OpLabel
122 ; CHECK: OpBranchConditional %[[#]] %[[#bb123:]] %[[#bb117:]]
123 ; CHECK: %[[#bb123:]] = OpLabel
124 ; CHECK: OpBranch %[[#bb118:]]
125 ; CHECK: %[[#bb117:]] = OpLabel
126 ; CHECK: OpBranch %[[#bb124:]]
127 ; CHECK: %[[#bb118:]] = OpLabel
128 ; CHECK: OpBranch %[[#bb116:]]
129 ; CHECK: %[[#bb124:]] = OpLabel
130 ; CHECK: OpLoopMerge %[[#bb125:]] %[[#bb126:]] None
131 ; CHECK: OpBranch %[[#bb127:]]
132 ; CHECK: %[[#bb127:]] = OpLabel
133 ; CHECK: OpSelectionMerge %[[#bb128:]] None
134 ; CHECK: OpBranchConditional %[[#]] %[[#bb129:]] %[[#bb128:]]
135 ; CHECK: %[[#bb129:]] = OpLabel
136 ; CHECK: OpBranch %[[#bb128:]]
137 ; CHECK: %[[#bb128:]] = OpLabel
138 ; CHECK: OpBranchConditional %[[#]] %[[#bb130:]] %[[#bb125:]]
139 ; CHECK: %[[#bb130:]] = OpLabel
140 ; CHECK: OpBranch %[[#bb126:]]
141 ; CHECK: %[[#bb126:]] = OpLabel
142 ; CHECK: OpBranch %[[#bb124:]]
143 ; CHECK: %[[#bb125:]] = OpLabel
144 ; CHECK: OpReturnValue %[[#]]
145 ; CHECK: OpFunctionEnd
146 ; CHECK: %[[#func_83:]] = OpFunction %[[#void:]] DontInline %[[#]]
147 ; CHECK: %[[#bb131:]] = OpLabel
149 ; CHECK: OpFunctionEnd
150 ; CHECK: %[[#func_85:]] = OpFunction %[[#void:]] None %[[#]]
151 ; CHECK: %[[#bb132:]] = OpLabel
153 ; CHECK: OpFunctionEnd
155 target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
156 target triple = "spirv-unknown-vulkan1.3-compute"
158 ; Function Attrs: convergent noinline norecurse nounwind optnone
159 define spir_func noundef i32 @_Z7processv() #0 {
161 %0 = call token @llvm.experimental.convergence.entry()
162 %a = alloca i32, align 4
163 %b = alloca i32, align 4
164 %val = alloca i32, align 4
165 %i = alloca i32, align 4
166 %i2 = alloca i32, align 4
167 %i11 = alloca i32, align 4
168 %i26 = alloca i32, align 4
169 %x = alloca i32, align 4
170 %y = alloca i32, align 4
171 %i35 = alloca i32, align 4
172 store i32 0, ptr %a, align 4
173 store i32 1, ptr %b, align 4
174 store i32 0, ptr %val, align 4
175 store i32 0, ptr %i, align 4
178 for.cond: ; preds = %for.inc, %entry
179 %1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ]
180 %2 = load i32, ptr %a, align 4
181 %tobool = icmp ne i32 %2, 0
182 br i1 %tobool, label %land.rhs, label %land.end
184 land.rhs: ; preds = %for.cond
185 %3 = load i32, ptr %b, align 4
186 %tobool1 = icmp ne i32 %3, 0
189 land.end: ; preds = %land.rhs, %for.cond
190 %4 = phi i1 [ false, %for.cond ], [ %tobool1, %land.rhs ]
191 br i1 %4, label %for.body, label %for.end
193 for.body: ; preds = %land.end
194 %5 = load i32, ptr %val, align 4
195 %add = add nsw i32 %5, 1
196 store i32 %add, ptr %val, align 4
199 for.inc: ; preds = %for.body
200 %6 = load i32, ptr %i, align 4
201 %inc = add nsw i32 %6, 1
202 store i32 %inc, ptr %i, align 4
205 for.end: ; preds = %land.end
206 store i32 0, ptr %i2, align 4
209 for.cond3: ; preds = %for.inc8, %for.end
210 %7 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ]
211 %8 = load i32, ptr %a, align 4
212 %tobool4 = icmp ne i32 %8, 0
213 br i1 %tobool4, label %lor.end, label %lor.rhs
215 lor.rhs: ; preds = %for.cond3
216 %9 = load i32, ptr %b, align 4
217 %tobool5 = icmp ne i32 %9, 0
220 lor.end: ; preds = %lor.rhs, %for.cond3
221 %10 = phi i1 [ true, %for.cond3 ], [ %tobool5, %lor.rhs ]
222 br i1 %10, label %for.body6, label %for.end10
224 for.body6: ; preds = %lor.end
225 %11 = load i32, ptr %val, align 4
226 %add7 = add nsw i32 %11, 1
227 store i32 %add7, ptr %val, align 4
228 store i32 0, ptr %b, align 4
231 for.inc8: ; preds = %for.body6
232 %12 = load i32, ptr %i2, align 4
233 %inc9 = add nsw i32 %12, 1
234 store i32 %inc9, ptr %i2, align 4
237 for.end10: ; preds = %lor.end
238 store i32 1, ptr %b, align 4
239 store i32 0, ptr %i11, align 4
242 for.cond12: ; preds = %for.inc23, %for.end10
243 %13 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ]
244 %14 = load i32, ptr %a, align 4
245 %tobool13 = icmp ne i32 %14, 0
246 br i1 %tobool13, label %land.rhs14, label %land.end20
248 land.rhs14: ; preds = %for.cond12
249 %15 = load i32, ptr %a, align 4
250 %tobool15 = icmp ne i32 %15, 0
251 br i1 %tobool15, label %land.rhs17, label %lor.lhs.false
253 lor.lhs.false: ; preds = %land.rhs14
254 %16 = load i32, ptr %b, align 4
255 %tobool16 = icmp ne i32 %16, 0
256 br i1 %tobool16, label %land.rhs17, label %land.end19
258 land.rhs17: ; preds = %lor.lhs.false, %land.rhs14
259 %17 = load i32, ptr %b, align 4
260 %tobool18 = icmp ne i32 %17, 0
263 land.end19: ; preds = %land.rhs17, %lor.lhs.false
264 %18 = phi i1 [ false, %lor.lhs.false ], [ %tobool18, %land.rhs17 ]
267 land.end20: ; preds = %land.end19, %for.cond12
268 %19 = phi i1 [ false, %for.cond12 ], [ %18, %land.end19 ]
269 br i1 %19, label %for.body21, label %for.end25
271 for.body21: ; preds = %land.end20
272 %20 = load i32, ptr %val, align 4
273 %add22 = add nsw i32 %20, 4
274 store i32 %add22, ptr %val, align 4
275 store i32 0, ptr %b, align 4
278 for.inc23: ; preds = %for.body21
279 %21 = load i32, ptr %i11, align 4
280 %inc24 = add nsw i32 %21, 1
281 store i32 %inc24, ptr %i11, align 4
284 for.end25: ; preds = %land.end20
285 store i32 1, ptr %b, align 4
286 store i32 0, ptr %i26, align 4
289 for.cond27: ; preds = %for.inc32, %for.end25
290 %22 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ]
291 %23 = load i32, ptr %a, align 4
292 %tobool28 = icmp ne i32 %23, 0
293 br i1 %tobool28, label %cond.true, label %cond.false
295 cond.true: ; preds = %for.cond27
296 %24 = load i32, ptr %a, align 4
299 cond.false: ; preds = %for.cond27
300 %25 = load i32, ptr %b, align 4
303 cond.end: ; preds = %cond.false, %cond.true
304 %cond = phi i32 [ %24, %cond.true ], [ %25, %cond.false ]
305 %tobool29 = icmp ne i32 %cond, 0
306 br i1 %tobool29, label %for.body30, label %for.end34
308 for.body30: ; preds = %cond.end
309 %26 = load i32, ptr %val, align 4
310 %add31 = add nsw i32 %26, 8
311 store i32 %add31, ptr %val, align 4
312 store i32 0, ptr %b, align 4
315 for.inc32: ; preds = %for.body30
316 %27 = load i32, ptr %i26, align 4
317 %inc33 = add nsw i32 %27, 1
318 store i32 %inc33, ptr %i26, align 4
321 for.end34: ; preds = %cond.end
322 store i32 0, ptr %x, align 4
323 store i32 0, ptr %y, align 4
324 store i32 0, ptr %i35, align 4
327 for.cond36: ; preds = %for.inc45, %for.end34
328 %28 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ]
329 %29 = load i32, ptr %x, align 4
330 %30 = load i32, ptr %x, align 4
331 %tobool37 = icmp ne i32 %30, 0
332 br i1 %tobool37, label %land.rhs38, label %land.end40
334 land.rhs38: ; preds = %for.cond36
335 %31 = load i32, ptr %y, align 4
336 %tobool39 = icmp ne i32 %31, 0
339 land.end40: ; preds = %land.rhs38, %for.cond36
340 %32 = phi i1 [ false, %for.cond36 ], [ %tobool39, %land.rhs38 ]
341 %conv = zext i1 %32 to i32
342 %add41 = add nsw i32 %29, %conv
343 %tobool42 = icmp ne i32 %add41, 0
344 br i1 %tobool42, label %for.body43, label %for.end47
346 for.body43: ; preds = %land.end40
347 %33 = load i32, ptr %val, align 4
348 %add44 = add nsw i32 %33, 16
349 store i32 %add44, ptr %val, align 4
352 for.inc45: ; preds = %for.body43
353 %34 = load i32, ptr %i35, align 4
354 %inc46 = add nsw i32 %34, 1
355 store i32 %inc46, ptr %i35, align 4
358 for.end47: ; preds = %land.end40
359 %35 = load i32, ptr %val, align 4
363 ; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none)
364 declare token @llvm.experimental.convergence.entry() #1
366 ; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none)
367 declare token @llvm.experimental.convergence.loop() #1
369 ; Function Attrs: convergent noinline norecurse nounwind optnone
370 define internal spir_func void @main() #0 {
372 %0 = call token @llvm.experimental.convergence.entry()
373 %call1 = call spir_func noundef i32 @_Z7processv() #3 [ "convergencectrl"(token %0) ]
377 ; Function Attrs: convergent norecurse
378 define void @main.1() #2 {
384 attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
385 attributes #1 = { convergent nocallback nofree nosync nounwind willreturn memory(none) }
386 attributes #2 = { convergent norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
387 attributes #3 = { convergent }
389 !llvm.module.flags = !{!0, !1, !2}
392 !0 = !{i32 1, !"wchar_size", i32 4}
393 !1 = !{i32 4, !"dx.disable_optimizations", i32 1}
394 !2 = !{i32 7, !"frame-pointer", i32 2}