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 frag. shader that increments a value in nested for loop
21
22# The test passes because shader always writes red.
23
24# Optimized using spirv-opt with the following arguments:
25# '-O'
26# spirv-opt commit hash: ab7ac60f14ae66006bed5c989a2cfd4c4881704c
27
28
29
30SHADER vertex variant_vertex_shader PASSTHROUGH
31
32# variant_fragment_shader is derived from the following GLSL:
33# #version 310 es
34# precision highp float;
35# precision highp int;
36#
37# layout(location = 0) out vec4 _GLF_color;
38#
39# layout(set = 0, binding = 0) uniform buf0 {
40#  vec2 injectionSwitch;
41# };
42#
43# // func returns 1 if "ref" > 0.
44# int func(int ref)
45# {
46#     bool alwaysFalse = gl_FragCoord.x < -1.0;
47#
48#     if (!(injectionSwitch.x < 0.0))
49#     {
50#         if (alwaysFalse)
51#             return 0;
52#
53#         // Returns on first iteration.
54#         for (int i = 1; i < ref; i++)
55#         {
56#             if (alwaysFalse)
57#                 continue;
58#
59#             // Always true.
60#             if (i > 0)
61#                 return 1;
62#         }
63#     }
64#     return 0;
65# }
66#
67# void main()
68# {
69#     bool alwaysFalse = injectionSwitch.x < -1.0;
70#     int value = 0;
71#
72#     // Iterates once.
73#     for (int i = 0; i < (gl_FragCoord.y > -1.0 ? 10 : 100); i++)
74#     {
75#         for (int k = 0; k < 2; k++)
76#         {
77#             // After 2 iterations: value == 2
78#             value += func(3);
79#
80#             if (alwaysFalse)
81#             {
82#                 while (alwaysFalse)
83#                 {
84#                     _GLF_color = vec4(i);
85#                 }
86#                 return;
87#             }
88#         }
89#
90#         if (!alwaysFalse)
91#             break;
92#     }
93#
94#     // Iterates 2 times.
95#     for (int i = 0; i < int(injectionSwitch.y + 1.0); i++)
96#     {
97#         // After 2 iterations: value == 4
98#         value += func(3);
99#         // func(0) will always return 0.
100#         if (alwaysFalse || func(0) != 0)
101#             break;
102#     }
103#
104#     if (value == 4)
105#         _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
106#     else
107#         _GLF_color = vec4(0.0, 0.0, 0.0, 0.0);
108# }
109SHADER fragment variant_fragment_shader SPIRV-ASM
110; SPIR-V
111; Version: 1.0
112; Generator: Khronos Glslang Reference Front End; 8
113; Bound: 454
114; Schema: 0
115               OpCapability Shader
116          %1 = OpExtInstImport "GLSL.std.450"
117               OpMemoryModel Logical GLSL450
118               OpEntryPoint Fragment %4 "main" %18 %110
119               OpExecutionMode %4 OriginUpperLeft
120               OpSource ESSL 310
121               OpName %4 "main"
122               OpName %18 "gl_FragCoord"
123               OpName %27 "buf0"
124               OpMemberName %27 0 "injectionSwitch"
125               OpName %29 ""
126               OpName %110 "_GLF_color"
127               OpDecorate %18 BuiltIn FragCoord
128               OpMemberDecorate %27 0 Offset 0
129               OpDecorate %27 Block
130               OpDecorate %29 DescriptorSet 0
131               OpDecorate %29 Binding 0
132               OpDecorate %110 Location 0
133          %2 = OpTypeVoid
134          %3 = OpTypeFunction %2
135          %6 = OpTypeInt 32 1
136         %12 = OpTypeBool
137         %15 = OpTypeFloat 32
138         %16 = OpTypeVector %15 4
139         %17 = OpTypePointer Input %16
140         %18 = OpVariable %17 Input
141         %19 = OpTypeInt 32 0
142         %20 = OpConstant %19 0
143         %21 = OpTypePointer Input %15
144         %24 = OpConstant %15 -1
145         %26 = OpTypeVector %15 2
146         %27 = OpTypeStruct %26
147         %28 = OpTypePointer Uniform %27
148         %29 = OpVariable %28 Uniform
149         %30 = OpConstant %6 0
150         %31 = OpTypePointer Uniform %15
151         %34 = OpConstant %15 0
152         %44 = OpConstant %6 1
153         %78 = OpConstant %19 1
154         %82 = OpConstant %6 10
155         %83 = OpConstant %6 100
156         %93 = OpConstant %6 2
157         %95 = OpConstant %6 3
158        %109 = OpTypePointer Output %16
159        %110 = OpVariable %109 Output
160        %133 = OpConstant %15 1
161        %155 = OpConstant %6 4
162        %159 = OpConstantComposite %16 %133 %34 %34 %133
163        %161 = OpConstantComposite %16 %34 %34 %34 %34
164        %166 = OpConstantFalse %12
165        %168 = OpConstantTrue %12
166        %319 = OpUndef %6
167          %4 = OpFunction %2 None %3
168          %5 = OpLabel
169               OpBranch %163
170        %163 = OpLabel
171         %67 = OpAccessChain %31 %29 %30 %20
172         %68 = OpLoad %15 %67
173         %69 = OpFOrdLessThan %12 %68 %24
174               OpLoopMerge %162 %165 None
175               OpBranch %72
176         %72 = OpLabel
177        %337 = OpPhi %12 %166 %163 %335 %75
178        %324 = OpPhi %6 %30 %163 %383 %75
179        %317 = OpPhi %6 %319 %163 %441 %75
180        %305 = OpPhi %6 %30 %163 %123 %75
181         %79 = OpAccessChain %21 %18 %78
182         %80 = OpLoad %15 %79
183         %81 = OpFOrdGreaterThan %12 %80 %24
184         %84 = OpSelect %6 %81 %82 %83
185         %85 = OpSLessThan %12 %305 %84
186               OpLoopMerge %74 %75 None
187               OpBranchConditional %85 %73 %74
188         %73 = OpLabel
189               OpBranch %87
190         %87 = OpLabel
191        %323 = OpPhi %6 %324 %73 %99 %90
192        %316 = OpPhi %6 %317 %73 %312 %90
193        %306 = OpPhi %6 %30 %73 %116 %90
194         %94 = OpSLessThan %12 %306 %93
195               OpLoopMerge %89 %90 None
196               OpBranchConditional %94 %88 %89
197         %88 = OpLabel
198               OpBranch %187
199        %187 = OpLabel
200               OpLoopMerge %188 %189 None
201               OpBranch %190
202        %190 = OpLabel
203        %191 = OpAccessChain %21 %18 %20
204        %192 = OpLoad %15 %191
205        %193 = OpFOrdLessThan %12 %192 %24
206        %196 = OpFOrdLessThan %12 %68 %34
207        %197 = OpLogicalNot %12 %196
208               OpSelectionMerge %198 None
209               OpBranchConditional %197 %199 %198
210        %199 = OpLabel
211               OpSelectionMerge %201 None
212               OpBranchConditional %193 %202 %201
213        %202 = OpLabel
214               OpBranch %188
215        %201 = OpLabel
216               OpBranch %203
217        %203 = OpLabel
218        %307 = OpPhi %6 %44 %201 %219 %205
219        %209 = OpSLessThan %12 %307 %95
220               OpLoopMerge %204 %205 None
221               OpBranchConditional %209 %210 %204
222        %210 = OpLabel
223               OpSelectionMerge %212 None
224               OpBranchConditional %193 %213 %212
225        %213 = OpLabel
226               OpBranch %205
227        %212 = OpLabel
228        %215 = OpSGreaterThan %12 %307 %30
229               OpSelectionMerge %216 None
230               OpBranchConditional %215 %217 %216
231        %217 = OpLabel
232               OpBranch %204
233        %216 = OpLabel
234               OpBranch %205
235        %205 = OpLabel
236        %219 = OpIAdd %6 %307 %44
237               OpBranch %203
238        %204 = OpLabel
239        %313 = OpPhi %6 %316 %203 %44 %217
240        %308 = OpPhi %12 %166 %203 %168 %217
241               OpSelectionMerge %221 None
242               OpBranchConditional %308 %188 %221
243        %221 = OpLabel
244               OpBranch %198
245        %198 = OpLabel
246               OpBranch %188
247        %189 = OpLabel
248               OpBranch %187
249        %188 = OpLabel
250        %312 = OpPhi %6 %30 %202 %313 %204 %30 %198
251         %99 = OpIAdd %6 %323 %312
252               OpSelectionMerge %102 None
253               OpBranchConditional %69 %101 %102
254        %101 = OpLabel
255               OpBranch %103
256        %103 = OpLabel
257               OpLoopMerge %105 %104 None
258               OpBranchConditional %69 %104 %105
259        %104 = OpLabel
260        %112 = OpConvertSToF %15 %305
261        %113 = OpCompositeConstruct %16 %112 %112 %112 %112
262               OpStore %110 %113
263               OpBranch %103
264        %105 = OpLabel
265               OpBranch %89
266        %102 = OpLabel
267               OpBranch %90
268         %90 = OpLabel
269        %116 = OpIAdd %6 %306 %44
270               OpBranch %87
271         %89 = OpLabel
272        %441 = OpPhi %6 %316 %87 %312 %105
273        %383 = OpPhi %6 %323 %87 %99 %105
274        %335 = OpPhi %12 %337 %87 %168 %105
275               OpSelectionMerge %169 None
276               OpBranchConditional %335 %74 %169
277        %169 = OpLabel
278        %118 = OpLogicalNot %12 %69
279               OpSelectionMerge %120 None
280               OpBranchConditional %118 %119 %120
281        %119 = OpLabel
282               OpBranch %74
283        %120 = OpLabel
284               OpBranch %75
285         %75 = OpLabel
286        %123 = OpIAdd %6 %305 %44
287               OpBranch %72
288         %74 = OpLabel
289        %382 = OpPhi %6 %324 %72 %383 %89 %383 %119
290        %354 = OpPhi %12 %337 %72 %335 %89 %335 %119
291               OpSelectionMerge %171 None
292               OpBranchConditional %354 %162 %171
293        %171 = OpLabel
294               OpBranch %125
295        %125 = OpLabel
296        %381 = OpPhi %6 %382 %171 %140 %128
297        %365 = OpPhi %6 %319 %171 %361 %128
298        %355 = OpPhi %6 %30 %171 %153 %128
299        %131 = OpAccessChain %31 %29 %30 %78
300        %132 = OpLoad %15 %131
301        %134 = OpFAdd %15 %132 %133
302        %135 = OpConvertFToS %6 %134
303        %136 = OpSLessThan %12 %355 %135
304               OpLoopMerge %127 %128 None
305               OpBranchConditional %136 %126 %127
306        %126 = OpLabel
307               OpBranch %228
308        %228 = OpLabel
309               OpLoopMerge %229 %230 None
310               OpBranch %231
311        %231 = OpLabel
312        %232 = OpAccessChain %21 %18 %20
313        %233 = OpLoad %15 %232
314        %234 = OpFOrdLessThan %12 %233 %24
315        %237 = OpFOrdLessThan %12 %68 %34
316        %238 = OpLogicalNot %12 %237
317               OpSelectionMerge %239 None
318               OpBranchConditional %238 %240 %239
319        %240 = OpLabel
320               OpSelectionMerge %242 None
321               OpBranchConditional %234 %243 %242
322        %243 = OpLabel
323               OpBranch %229
324        %242 = OpLabel
325               OpBranch %244
326        %244 = OpLabel
327        %356 = OpPhi %6 %44 %242 %260 %246
328        %250 = OpSLessThan %12 %356 %95
329               OpLoopMerge %245 %246 None
330               OpBranchConditional %250 %251 %245
331        %251 = OpLabel
332               OpSelectionMerge %253 None
333               OpBranchConditional %234 %254 %253
334        %254 = OpLabel
335               OpBranch %246
336        %253 = OpLabel
337        %256 = OpSGreaterThan %12 %356 %30
338               OpSelectionMerge %257 None
339               OpBranchConditional %256 %258 %257
340        %258 = OpLabel
341               OpBranch %245
342        %257 = OpLabel
343               OpBranch %246
344        %246 = OpLabel
345        %260 = OpIAdd %6 %356 %44
346               OpBranch %244
347        %245 = OpLabel
348        %362 = OpPhi %6 %365 %244 %44 %258
349        %357 = OpPhi %12 %166 %244 %168 %258
350               OpSelectionMerge %262 None
351               OpBranchConditional %357 %229 %262
352        %262 = OpLabel
353               OpBranch %239
354        %239 = OpLabel
355               OpBranch %229
356        %230 = OpLabel
357               OpBranch %228
358        %229 = OpLabel
359        %361 = OpPhi %6 %30 %243 %362 %245 %30 %239
360        %140 = OpIAdd %6 %381 %361
361        %142 = OpLogicalNot %12 %69
362        %453 = OpSelect %12 %142 %166 %69
363               OpSelectionMerge %150 None
364               OpBranchConditional %453 %149 %150
365        %149 = OpLabel
366               OpBranch %127
367        %150 = OpLabel
368               OpBranch %128
369        %128 = OpLabel
370        %153 = OpIAdd %6 %355 %44
371               OpBranch %125
372        %127 = OpLabel
373        %431 = OpPhi %6 %381 %125 %140 %149
374        %156 = OpIEqual %12 %431 %155
375               OpSelectionMerge %158 None
376               OpBranchConditional %156 %157 %160
377        %160 = OpLabel
378               OpStore %110 %161
379               OpBranch %158
380        %157 = OpLabel
381               OpStore %110 %159
382               OpBranch %158
383        %158 = OpLabel
384               OpBranch %162
385        %165 = OpLabel
386               OpBranch %163
387        %162 = OpLabel
388               OpReturn
389               OpFunctionEnd
390END
391
392# uniforms for variant
393
394# injectionSwitch
395BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
396 0.0 1.0
397END
398
399BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
400
401PIPELINE graphics variant_pipeline
402  ATTACH variant_vertex_shader
403  ATTACH variant_fragment_shader
404  FRAMEBUFFER_SIZE 256 256
405  BIND BUFFER variant_framebuffer AS color LOCATION 0
406  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
407END
408CLEAR_COLOR variant_pipeline 0 0 0 255
409
410CLEAR variant_pipeline
411RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
412
413EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
414