• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!amber
2
3# Copyright 2020 Google LLC
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17
18# A test for a bug found by GraphicsFuzz.
19
20# Short description: A fragment shader with few nested loops with fallthrough
21
22# A fragment shader with several nested loops depending on each other and switch case with fallthrough.
23# The test passes because shader always writes red.
24
25# Optimized using spirv-opt with the following arguments:
26# '-O'
27# spirv-opt commit hash: ab7ac60f14ae66006bed5c989a2cfd4c4881704c
28
29
30
31SHADER vertex variant_vertex_shader PASSTHROUGH
32
33# variant_fragment_shader is derived from the following GLSL:
34# #version 310 es
35# precision highp float;
36# precision highp int;
37#
38# layout(set = 0, binding = 0) uniform buf0
39# {
40#     float zero;
41# };
42# layout(location = 0) out vec4 _GLF_color;
43#
44# void main()
45# {
46#     float sums[9];
47#     int sum_index = 0;
48#
49#     _GLF_color = vec4(0, 0, 0, 1);
50#
51#     sums[0] = 0.0;
52#
53#     // sum_index is modified in loops A and B like this:
54#     // A: 0 -> 1, 1 -> 2
55#     // B: 2 -> 3
56#     // A: 3 -> 4, 4 -> 5
57#     // B: 5 -> 6. At this point we set red channel to 1.
58#     // A: 6: return from main.
59#     for(int i0 = 2; i0 < 5; i0++)
60#     {
61#         // Loop A: After this loop sum_index = sum_index + 2.
62#         for(int i1 = 2; i1 < 4; i1++)
63#         {
64#             for(int i2 = 0; i2 < i0; i2++)
65#             {
66#                 for(int i3 = 0; i3 < i1; i3++)
67#                 {
68#                     switch(sum_index)
69#                     {
70#                         case 0:
71#                             sums[sum_index]++;
72#                             break;
73#                         case 1:
74#                             sums[sum_index]++;
75#                             break;
76#                         case 2:
77#                             sums[sum_index]++;
78#                         case 3:
79#                             sums[sum_index]++;
80#                         case 4:
81#                             sums[sum_index]++;
82#                         case 5:
83#                             sums[sum_index]++;
84#                             break;
85#                         case 6:
86#                             // This is hit eventually.
87#                             return;
88#                         case 7:
89#                             sums[sum_index]++;
90#                             break;
91#                         case 8:
92#                             sums[sum_index]++;
93#                     }
94#                 }
95#             }
96#
97#             if(clamp(1.0, gl_FragCoord.y, gl_FragCoord.y) < 0.0) // Always false.
98#                 continue;
99#
100#             if(zero < 0.0) // Always false.
101#                 sums[sum_index]++;
102#
103#             if(gl_FragCoord.y < 0.0) // Always false.
104#                 discard;
105#
106#             sum_index++;
107#         }
108#
109#         // Loop B: After this loop sum_index = sum_index + 1.
110#         //
111#         // Cases that are not supposed to be hit set the green channel
112#         // to one to mark an error.
113#         for(int i4 = 4; i4 < 5; i4++)
114#         {
115#             for(int i5 = 0; i5 < i0; i5++)
116#             {
117#                 for(int i6 = 0; i6 < i4; i6++)
118#                 {
119#                     switch(sum_index)
120#                     {
121#                         case 0:
122#                             sums[sum_index]++;
123#                             _GLF_color.g = 1.0;
124#                         case 1:
125#                             sums[sum_index]++;
126#                             _GLF_color.g = 1.0;
127#                         case 2:
128#                             sums[sum_index]++;
129#                             break;
130#                         case 3:
131#                             sums[sum_index]++;
132#                             _GLF_color.g = 1.0;
133#                         case 4:
134#                             sums[sum_index]++;
135#                             _GLF_color.g = 1.0;
136#                             break;
137#                         case 5:
138#                             sums[sum_index]++;
139#                             if (sums[0] != 0.0) // Always true.
140#                                 _GLF_color.r = 1.0;
141#                             break;
142#                         case 6:
143#                             sums[sum_index]++;
144#                             _GLF_color.g = 1.0;
145#                         case 7:
146#                             sums[sum_index]++;
147#                             _GLF_color.g = 1.0;
148#                         case 8:
149#                             sums[sum_index]++;
150#                             _GLF_color.g = 1.0;
151#                     }
152#                 }
153#             }
154#
155#             sum_index++;
156#
157#             if (zero < 1.0) // Always true, but we run the loop only once anyway.
158#                 break;
159#         }
160#     }
161#
162#     // We never reach here. Both branches write incorrect color.
163#     if (sums[0] == 0.0)
164#         _GLF_color = vec4(0);
165#     else
166#         _GLF_color = vec4(1);
167# }
168SHADER fragment variant_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
169; SPIR-V
170; Version: 1.0
171; Generator: Khronos Glslang Reference Front End; 8
172; Bound: 358
173; Schema: 0
174               OpCapability Shader
175          %1 = OpExtInstImport "GLSL.std.450"
176               OpMemoryModel Logical GLSL450
177               OpEntryPoint Fragment %4 "main" %13 %117
178               OpExecutionMode %4 OriginUpperLeft
179               OpSource ESSL 310
180               OpName %4 "main"
181               OpName %13 "_GLF_color"
182               OpName %21 "sums"
183               OpName %117 "gl_FragCoord"
184               OpName %129 "buf0"
185               OpMemberName %129 0 "zero"
186               OpName %131 ""
187               OpDecorate %13 Location 0
188               OpDecorate %117 BuiltIn FragCoord
189               OpMemberDecorate %129 0 Offset 0
190               OpDecorate %129 Block
191               OpDecorate %131 DescriptorSet 0
192               OpDecorate %131 Binding 0
193          %2 = OpTypeVoid
194          %3 = OpTypeFunction %2
195          %6 = OpTypeInt 32 1
196          %9 = OpConstant %6 0
197         %10 = OpTypeFloat 32
198         %11 = OpTypeVector %10 4
199         %12 = OpTypePointer Output %11
200         %13 = OpVariable %12 Output
201         %14 = OpConstant %10 0
202         %15 = OpConstant %10 1
203         %16 = OpConstantComposite %11 %14 %14 %14 %15
204         %17 = OpTypeInt 32 0
205         %18 = OpConstant %17 9
206         %19 = OpTypeArray %10 %18
207         %20 = OpTypePointer Function %19
208         %22 = OpTypePointer Function %10
209         %25 = OpConstant %6 2
210         %32 = OpConstant %6 5
211         %33 = OpTypeBool
212         %42 = OpConstant %6 4
213        %112 = OpConstant %6 1
214        %116 = OpTypePointer Input %11
215        %117 = OpVariable %116 Input
216        %118 = OpConstant %17 1
217        %119 = OpTypePointer Input %10
218        %129 = OpTypeStruct %10
219        %130 = OpTypePointer Uniform %129
220        %131 = OpVariable %130 Uniform
221        %132 = OpTypePointer Uniform %10
222        %193 = OpTypePointer Output %10
223        %225 = OpConstant %17 0
224        %265 = OpConstantComposite %11 %14 %14 %14 %14
225        %267 = OpConstantComposite %11 %15 %15 %15 %15
226        %272 = OpConstantFalse %33
227        %275 = OpConstantTrue %33
228          %4 = OpFunction %2 None %3
229          %5 = OpLabel
230         %21 = OpVariable %20 Function
231               OpBranch %269
232        %269 = OpLabel
233               OpStore %13 %16
234         %23 = OpAccessChain %22 %21 %9
235               OpStore %23 %14
236               OpLoopMerge %268 %271 None
237               OpBranch %26
238         %26 = OpLabel
239        %300 = OpPhi %33 %272 %269 %312 %29
240        %295 = OpPhi %6 %9 %269 %356 %29
241        %284 = OpPhi %6 %25 %269 %259 %29
242         %34 = OpSLessThan %33 %284 %32
243               OpLoopMerge %28 %29 None
244               OpBranchConditional %34 %27 %28
245         %27 = OpLabel
246               OpBranch %36
247         %36 = OpLabel
248        %299 = OpPhi %33 %300 %27 %304 %39
249        %294 = OpPhi %6 %295 %27 %357 %39
250        %285 = OpPhi %6 %25 %27 %151 %39
251         %43 = OpSLessThan %33 %285 %42
252               OpLoopMerge %38 %39 None
253               OpBranchConditional %43 %37 %38
254         %37 = OpLabel
255               OpBranch %45
256         %45 = OpLabel
257        %298 = OpPhi %33 %299 %37 %296 %48
258        %286 = OpPhi %6 %9 %37 %115 %48
259         %52 = OpSLessThan %33 %286 %284
260               OpLoopMerge %47 %48 None
261               OpBranchConditional %52 %46 %47
262         %46 = OpLabel
263               OpBranch %54
264         %54 = OpLabel
265        %289 = OpPhi %6 %9 %46 %113 %57
266         %61 = OpSLessThan %33 %289 %285
267               OpLoopMerge %56 %57 None
268               OpBranchConditional %61 %55 %56
269         %55 = OpLabel
270               OpSelectionMerge %72 None
271               OpSwitch %294 %72 0 %63 1 %64 2 %65 3 %66 4 %67 5 %68 6 %69 7 %70 8 %71
272         %63 = OpLabel
273         %74 = OpAccessChain %22 %21 %294
274         %75 = OpLoad %10 %74
275         %76 = OpFAdd %10 %75 %15
276               OpStore %74 %76
277               OpBranch %72
278         %64 = OpLabel
279         %79 = OpAccessChain %22 %21 %294
280         %80 = OpLoad %10 %79
281         %81 = OpFAdd %10 %80 %15
282               OpStore %79 %81
283               OpBranch %72
284         %65 = OpLabel
285         %84 = OpAccessChain %22 %21 %294
286         %85 = OpLoad %10 %84
287         %86 = OpFAdd %10 %85 %15
288               OpStore %84 %86
289               OpBranch %66
290         %66 = OpLabel
291         %88 = OpAccessChain %22 %21 %294
292         %89 = OpLoad %10 %88
293         %90 = OpFAdd %10 %89 %15
294               OpStore %88 %90
295               OpBranch %67
296         %67 = OpLabel
297         %92 = OpAccessChain %22 %21 %294
298         %93 = OpLoad %10 %92
299         %94 = OpFAdd %10 %93 %15
300               OpStore %92 %94
301               OpBranch %68
302         %68 = OpLabel
303         %96 = OpAccessChain %22 %21 %294
304         %97 = OpLoad %10 %96
305         %98 = OpFAdd %10 %97 %15
306               OpStore %96 %98
307               OpBranch %72
308         %69 = OpLabel
309               OpBranch %56
310         %70 = OpLabel
311        %102 = OpAccessChain %22 %21 %294
312        %103 = OpLoad %10 %102
313        %104 = OpFAdd %10 %103 %15
314               OpStore %102 %104
315               OpBranch %72
316         %71 = OpLabel
317        %107 = OpAccessChain %22 %21 %294
318        %108 = OpLoad %10 %107
319        %109 = OpFAdd %10 %108 %15
320               OpStore %107 %109
321               OpBranch %72
322         %72 = OpLabel
323               OpBranch %57
324         %57 = OpLabel
325        %113 = OpIAdd %6 %289 %112
326               OpBranch %54
327         %56 = OpLabel
328        %296 = OpPhi %33 %298 %54 %275 %69
329               OpSelectionMerge %276 None
330               OpBranchConditional %296 %47 %276
331        %276 = OpLabel
332               OpBranch %48
333         %48 = OpLabel
334        %115 = OpIAdd %6 %286 %112
335               OpBranch %45
336         %47 = OpLabel
337        %304 = OpPhi %33 %298 %45 %296 %56
338               OpSelectionMerge %278 None
339               OpBranchConditional %304 %38 %278
340        %278 = OpLabel
341        %120 = OpAccessChain %119 %117 %118
342        %121 = OpLoad %10 %120
343        %124 = OpExtInst %10 %1 FClamp %15 %121 %121
344        %125 = OpFOrdLessThan %33 %124 %14
345               OpSelectionMerge %127 None
346               OpBranchConditional %125 %126 %127
347        %126 = OpLabel
348               OpBranch %39
349        %127 = OpLabel
350        %133 = OpAccessChain %132 %131 %9
351        %134 = OpLoad %10 %133
352        %135 = OpFOrdLessThan %33 %134 %14
353               OpSelectionMerge %137 None
354               OpBranchConditional %135 %136 %137
355        %136 = OpLabel
356        %139 = OpAccessChain %22 %21 %294
357        %140 = OpLoad %10 %139
358        %141 = OpFAdd %10 %140 %15
359               OpStore %139 %141
360               OpBranch %137
361        %137 = OpLabel
362        %144 = OpFOrdLessThan %33 %121 %14
363               OpSelectionMerge %146 None
364               OpBranchConditional %144 %145 %146
365        %145 = OpLabel
366               OpKill
367        %146 = OpLabel
368        %149 = OpIAdd %6 %294 %112
369               OpBranch %39
370         %39 = OpLabel
371        %357 = OpPhi %6 %294 %126 %149 %146
372        %151 = OpIAdd %6 %285 %112
373               OpBranch %36
374         %38 = OpLabel
375        %312 = OpPhi %33 %299 %36 %304 %47
376               OpSelectionMerge %280 None
377               OpBranchConditional %312 %28 %280
378        %280 = OpLabel
379               OpBranch %153
380        %153 = OpLabel
381        %322 = OpPhi %6 %294 %280 %249 %156
382        %313 = OpPhi %6 %42 %280 %257 %156
383        %159 = OpSLessThan %33 %313 %32
384               OpLoopMerge %155 %156 None
385               OpBranchConditional %159 %154 %155
386        %154 = OpLabel
387               OpBranch %161
388        %161 = OpLabel
389        %314 = OpPhi %6 %9 %154 %247 %164
390        %168 = OpSLessThan %33 %314 %284
391               OpLoopMerge %163 %164 None
392               OpBranchConditional %168 %162 %163
393        %162 = OpLabel
394               OpBranch %170
395        %170 = OpLabel
396        %326 = OpPhi %6 %9 %162 %245 %173
397        %177 = OpSLessThan %33 %326 %313
398               OpLoopMerge %172 %173 None
399               OpBranchConditional %177 %171 %172
400        %171 = OpLabel
401               OpSelectionMerge %188 None
402               OpSwitch %322 %188 0 %179 1 %180 2 %181 3 %182 4 %183 5 %184 6 %185 7 %186 8 %187
403        %179 = OpLabel
404        %190 = OpAccessChain %22 %21 %322
405        %191 = OpLoad %10 %190
406        %192 = OpFAdd %10 %191 %15
407               OpStore %190 %192
408        %194 = OpAccessChain %193 %13 %118
409               OpStore %194 %15
410               OpBranch %180
411        %180 = OpLabel
412        %196 = OpAccessChain %22 %21 %322
413        %197 = OpLoad %10 %196
414        %198 = OpFAdd %10 %197 %15
415               OpStore %196 %198
416        %199 = OpAccessChain %193 %13 %118
417               OpStore %199 %15
418               OpBranch %181
419        %181 = OpLabel
420        %201 = OpAccessChain %22 %21 %322
421        %202 = OpLoad %10 %201
422        %203 = OpFAdd %10 %202 %15
423               OpStore %201 %203
424               OpBranch %188
425        %182 = OpLabel
426        %206 = OpAccessChain %22 %21 %322
427        %207 = OpLoad %10 %206
428        %208 = OpFAdd %10 %207 %15
429               OpStore %206 %208
430        %209 = OpAccessChain %193 %13 %118
431               OpStore %209 %15
432               OpBranch %183
433        %183 = OpLabel
434        %211 = OpAccessChain %22 %21 %322
435        %212 = OpLoad %10 %211
436        %213 = OpFAdd %10 %212 %15
437               OpStore %211 %213
438        %214 = OpAccessChain %193 %13 %118
439               OpStore %214 %15
440               OpBranch %188
441        %184 = OpLabel
442        %217 = OpAccessChain %22 %21 %322
443        %218 = OpLoad %10 %217
444        %219 = OpFAdd %10 %218 %15
445               OpStore %217 %219
446        %221 = OpLoad %10 %23
447        %222 = OpFOrdNotEqual %33 %221 %14
448               OpSelectionMerge %224 None
449               OpBranchConditional %222 %223 %224
450        %223 = OpLabel
451        %226 = OpAccessChain %193 %13 %225
452               OpStore %226 %15
453               OpBranch %224
454        %224 = OpLabel
455               OpBranch %188
456        %185 = OpLabel
457        %229 = OpAccessChain %22 %21 %322
458        %230 = OpLoad %10 %229
459        %231 = OpFAdd %10 %230 %15
460               OpStore %229 %231
461        %232 = OpAccessChain %193 %13 %118
462               OpStore %232 %15
463               OpBranch %186
464        %186 = OpLabel
465        %234 = OpAccessChain %22 %21 %322
466        %235 = OpLoad %10 %234
467        %236 = OpFAdd %10 %235 %15
468               OpStore %234 %236
469        %237 = OpAccessChain %193 %13 %118
470               OpStore %237 %15
471               OpBranch %187
472        %187 = OpLabel
473        %239 = OpAccessChain %22 %21 %322
474        %240 = OpLoad %10 %239
475        %241 = OpFAdd %10 %240 %15
476               OpStore %239 %241
477        %242 = OpAccessChain %193 %13 %118
478               OpStore %242 %15
479               OpBranch %188
480        %188 = OpLabel
481               OpBranch %173
482        %173 = OpLabel
483        %245 = OpIAdd %6 %326 %112
484               OpBranch %170
485        %172 = OpLabel
486               OpBranch %164
487        %164 = OpLabel
488        %247 = OpIAdd %6 %314 %112
489               OpBranch %161
490        %163 = OpLabel
491        %249 = OpIAdd %6 %322 %112
492        %250 = OpAccessChain %132 %131 %9
493        %251 = OpLoad %10 %250
494        %252 = OpFOrdLessThan %33 %251 %15
495               OpSelectionMerge %254 None
496               OpBranchConditional %252 %253 %254
497        %253 = OpLabel
498               OpBranch %155
499        %254 = OpLabel
500               OpBranch %156
501        %156 = OpLabel
502        %257 = OpIAdd %6 %313 %112
503               OpBranch %153
504        %155 = OpLabel
505        %356 = OpPhi %6 %322 %153 %249 %253
506               OpBranch %29
507         %29 = OpLabel
508        %259 = OpIAdd %6 %284 %112
509               OpBranch %26
510         %28 = OpLabel
511        %342 = OpPhi %33 %300 %26 %312 %38
512               OpSelectionMerge %282 None
513               OpBranchConditional %342 %268 %282
514        %282 = OpLabel
515        %261 = OpLoad %10 %23
516        %262 = OpFOrdEqual %33 %261 %14
517               OpSelectionMerge %264 None
518               OpBranchConditional %262 %263 %266
519        %263 = OpLabel
520               OpStore %13 %265
521               OpBranch %264
522        %266 = OpLabel
523               OpStore %13 %267
524               OpBranch %264
525        %264 = OpLabel
526               OpBranch %268
527        %271 = OpLabel
528               OpBranch %269
529        %268 = OpLabel
530               OpReturn
531               OpFunctionEnd
532END
533
534# uniforms for variant
535
536# zero
537BUFFER variant_zero DATA_TYPE float DATA
538 0.0
539END
540
541BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
542
543PIPELINE graphics variant_pipeline
544  ATTACH variant_vertex_shader
545  ATTACH variant_fragment_shader
546  FRAMEBUFFER_SIZE 64 64
547  BIND BUFFER variant_framebuffer AS color LOCATION 0
548  BIND BUFFER variant_zero AS uniform DESCRIPTOR_SET 0 BINDING 0
549END
550CLEAR_COLOR variant_pipeline 0 0 0 255
551
552CLEAR variant_pipeline
553RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 64 64
554
555EXPECT variant_framebuffer IDX 0 0 SIZE 64 64 EQ_RGBA 255 0 0 255
556