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 TARGET_ENV spv1.0 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