dEQP-VK.graphicsfuzz.always-discarding-function
dEQP-VK.graphicsfuzz.always-false-if-in-do-while
dEQP-VK.graphicsfuzz.always-false-if-with-discard-return
+dEQP-VK.graphicsfuzz.array-idx-multiplied-by-for-loop-idx
+dEQP-VK.graphicsfuzz.assign-array-value-to-another-array
+dEQP-VK.graphicsfuzz.assign-array-value-to-another-array-2
dEQP-VK.graphicsfuzz.barrier-in-loop-with-break
dEQP-VK.graphicsfuzz.break-in-do-while-with-nested-if
dEQP-VK.graphicsfuzz.call-function-with-discard
dEQP-VK.graphicsfuzz.continue-and-merge
dEQP-VK.graphicsfuzz.control-flow-in-function
dEQP-VK.graphicsfuzz.control-flow-switch
+dEQP-VK.graphicsfuzz.cosh-return-inf-unused
dEQP-VK.graphicsfuzz.cov-analysis-reachable-from-many
dEQP-VK.graphicsfuzz.cov-apfloat-acos-ldexp
dEQP-VK.graphicsfuzz.cov-apfloat-determinant
dEQP-VK.graphicsfuzz.cov-vector-log2-cosh
dEQP-VK.graphicsfuzz.cov-wrap-op-kill-for-loop
dEQP-VK.graphicsfuzz.cov-wrap-op-kill-two-branches
+dEQP-VK.graphicsfuzz.create-color-in-do-while-for-loop
dEQP-VK.graphicsfuzz.dead-barriers-in-loops
dEQP-VK.graphicsfuzz.dead-struct-init
dEQP-VK.graphicsfuzz.disc-and-add-in-func-in-loop
dEQP-VK.graphicsfuzz.discards-in-control-flow
dEQP-VK.graphicsfuzz.do-while-loop-in-conditionals
dEQP-VK.graphicsfuzz.do-while-with-always-true-if
+dEQP-VK.graphicsfuzz.do-while-with-if-condition
dEQP-VK.graphicsfuzz.early-return-and-barrier
+dEQP-VK.graphicsfuzz.find-msb-from-lsb
dEQP-VK.graphicsfuzz.for-condition-always-false
dEQP-VK.graphicsfuzz.for-loop-with-return
dEQP-VK.graphicsfuzz.for-with-ifs-and-return
dEQP-VK.graphicsfuzz.fragcoord-control-flow
dEQP-VK.graphicsfuzz.fragcoord-control-flow-2
+dEQP-VK.graphicsfuzz.function-with-float-comparison
dEQP-VK.graphicsfuzz.function-with-uniform-return
dEQP-VK.graphicsfuzz.global-array-loops
dEQP-VK.graphicsfuzz.if-and-switch
+dEQP-VK.graphicsfuzz.increment-value-in-nested-for-loop
dEQP-VK.graphicsfuzz.injection-switch-as-comparison
dEQP-VK.graphicsfuzz.int-mat2-struct
dEQP-VK.graphicsfuzz.loop-call-discard
dEQP-VK.graphicsfuzz.modf-gl-color
dEQP-VK.graphicsfuzz.modf-temp-modf-color
dEQP-VK.graphicsfuzz.nested-for-break-mat-color
+dEQP-VK.graphicsfuzz.nested-for-loops-switch-fallthrough
dEQP-VK.graphicsfuzz.nested-for-loops-with-return
dEQP-VK.graphicsfuzz.nested-ifs-and-return-in-for-loop
dEQP-VK.graphicsfuzz.nested-loops-switch
dEQP-VK.graphicsfuzz.return-float-from-while-loop
dEQP-VK.graphicsfuzz.return-in-loop-in-function
dEQP-VK.graphicsfuzz.return-inside-loop-in-function
+dEQP-VK.graphicsfuzz.return-mat2x3-value-from-func
dEQP-VK.graphicsfuzz.returned-boolean-in-vector
+dEQP-VK.graphicsfuzz.set-color-in-one-iteration-while-loop
dEQP-VK.graphicsfuzz.similar-nested-ifs
dEQP-VK.graphicsfuzz.smoothstep-after-loop
dEQP-VK.graphicsfuzz.struct-and-unreachable-infinite-loop
+dEQP-VK.graphicsfuzz.struct-array-data-as-loop-iterator
dEQP-VK.graphicsfuzz.struct-controlled-loop
dEQP-VK.graphicsfuzz.struct-used-as-temporary
dEQP-VK.graphicsfuzz.switch-case-with-undefined-expression
dEQP-VK.graphicsfuzz.switch-inside-while-always-return
dEQP-VK.graphicsfuzz.switch-loop-switch-if
dEQP-VK.graphicsfuzz.switch-with-empty-if-false
+dEQP-VK.graphicsfuzz.switch-with-fall-through-cases
dEQP-VK.graphicsfuzz.swizzle-struct-init-min
dEQP-VK.graphicsfuzz.transpose-rectangular-matrix
dEQP-VK.graphicsfuzz.two-2-iteration-loops
dEQP-VK.graphicsfuzz.unreachable-return-in-loop
dEQP-VK.graphicsfuzz.unreachable-switch-case-with-discards
dEQP-VK.graphicsfuzz.uv-value-comparison-as-boolean
+dEQP-VK.graphicsfuzz.vector-values-multiplied-by-fragcoord
dEQP-VK.graphicsfuzz.vectors-and-discard-in-function
dEQP-VK.graphicsfuzz.while-function-always-false
dEQP-VK.graphicsfuzz.while-inside-switch
dEQP-VK.graphicsfuzz.always-discarding-function
dEQP-VK.graphicsfuzz.always-false-if-in-do-while
dEQP-VK.graphicsfuzz.always-false-if-with-discard-return
+dEQP-VK.graphicsfuzz.array-idx-multiplied-by-for-loop-idx
+dEQP-VK.graphicsfuzz.assign-array-value-to-another-array
+dEQP-VK.graphicsfuzz.assign-array-value-to-another-array-2
dEQP-VK.graphicsfuzz.barrier-in-loop-with-break
dEQP-VK.graphicsfuzz.break-in-do-while-with-nested-if
dEQP-VK.graphicsfuzz.call-function-with-discard
dEQP-VK.graphicsfuzz.continue-and-merge
dEQP-VK.graphicsfuzz.control-flow-in-function
dEQP-VK.graphicsfuzz.control-flow-switch
+dEQP-VK.graphicsfuzz.cosh-return-inf-unused
dEQP-VK.graphicsfuzz.cov-analysis-reachable-from-many
dEQP-VK.graphicsfuzz.cov-apfloat-acos-ldexp
dEQP-VK.graphicsfuzz.cov-apfloat-determinant
dEQP-VK.graphicsfuzz.cov-vector-log2-cosh
dEQP-VK.graphicsfuzz.cov-wrap-op-kill-for-loop
dEQP-VK.graphicsfuzz.cov-wrap-op-kill-two-branches
+dEQP-VK.graphicsfuzz.create-color-in-do-while-for-loop
dEQP-VK.graphicsfuzz.dead-barriers-in-loops
dEQP-VK.graphicsfuzz.dead-struct-init
dEQP-VK.graphicsfuzz.disc-and-add-in-func-in-loop
dEQP-VK.graphicsfuzz.discards-in-control-flow
dEQP-VK.graphicsfuzz.do-while-loop-in-conditionals
dEQP-VK.graphicsfuzz.do-while-with-always-true-if
+dEQP-VK.graphicsfuzz.do-while-with-if-condition
dEQP-VK.graphicsfuzz.early-return-and-barrier
+dEQP-VK.graphicsfuzz.find-msb-from-lsb
dEQP-VK.graphicsfuzz.for-condition-always-false
dEQP-VK.graphicsfuzz.for-loop-with-return
dEQP-VK.graphicsfuzz.for-with-ifs-and-return
dEQP-VK.graphicsfuzz.fragcoord-control-flow
dEQP-VK.graphicsfuzz.fragcoord-control-flow-2
+dEQP-VK.graphicsfuzz.function-with-float-comparison
dEQP-VK.graphicsfuzz.function-with-uniform-return
dEQP-VK.graphicsfuzz.global-array-loops
dEQP-VK.graphicsfuzz.if-and-switch
+dEQP-VK.graphicsfuzz.increment-value-in-nested-for-loop
dEQP-VK.graphicsfuzz.injection-switch-as-comparison
dEQP-VK.graphicsfuzz.int-mat2-struct
dEQP-VK.graphicsfuzz.loop-call-discard
dEQP-VK.graphicsfuzz.modf-gl-color
dEQP-VK.graphicsfuzz.modf-temp-modf-color
dEQP-VK.graphicsfuzz.nested-for-break-mat-color
+dEQP-VK.graphicsfuzz.nested-for-loops-switch-fallthrough
dEQP-VK.graphicsfuzz.nested-for-loops-with-return
dEQP-VK.graphicsfuzz.nested-ifs-and-return-in-for-loop
dEQP-VK.graphicsfuzz.nested-loops-switch
dEQP-VK.graphicsfuzz.return-float-from-while-loop
dEQP-VK.graphicsfuzz.return-in-loop-in-function
dEQP-VK.graphicsfuzz.return-inside-loop-in-function
+dEQP-VK.graphicsfuzz.return-mat2x3-value-from-func
dEQP-VK.graphicsfuzz.returned-boolean-in-vector
+dEQP-VK.graphicsfuzz.set-color-in-one-iteration-while-loop
dEQP-VK.graphicsfuzz.similar-nested-ifs
dEQP-VK.graphicsfuzz.smoothstep-after-loop
dEQP-VK.graphicsfuzz.struct-and-unreachable-infinite-loop
+dEQP-VK.graphicsfuzz.struct-array-data-as-loop-iterator
dEQP-VK.graphicsfuzz.struct-controlled-loop
dEQP-VK.graphicsfuzz.struct-used-as-temporary
dEQP-VK.graphicsfuzz.switch-case-with-undefined-expression
dEQP-VK.graphicsfuzz.switch-inside-while-always-return
dEQP-VK.graphicsfuzz.switch-loop-switch-if
dEQP-VK.graphicsfuzz.switch-with-empty-if-false
+dEQP-VK.graphicsfuzz.switch-with-fall-through-cases
dEQP-VK.graphicsfuzz.swizzle-struct-init-min
dEQP-VK.graphicsfuzz.transpose-rectangular-matrix
dEQP-VK.graphicsfuzz.two-2-iteration-loops
dEQP-VK.graphicsfuzz.unreachable-return-in-loop
dEQP-VK.graphicsfuzz.unreachable-switch-case-with-discards
dEQP-VK.graphicsfuzz.uv-value-comparison-as-boolean
+dEQP-VK.graphicsfuzz.vector-values-multiplied-by-fragcoord
dEQP-VK.graphicsfuzz.vectors-and-discard-in-function
dEQP-VK.graphicsfuzz.while-function-always-false
dEQP-VK.graphicsfuzz.while-inside-switch
--- /dev/null
+#!amber
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with array index multiplied
+
+# The test passes because shader always writes red.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+# precision highp int;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+# vec2 injectionSwitch;
+# };
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# // Function always returns 5.0.
+# float func()
+# {
+# if (gl_FragCoord.x < 1.0)
+# return 5.0;
+#
+# // Always false.
+# if (injectionSwitch.x > injectionSwitch.y)
+# return 1.0;
+#
+# int x = int(injectionSwitch.x);
+#
+# x += int(clamp(injectionSwitch.x, 0.0, 1.0)) * 3;
+#
+# return 5.0 + float(x);
+# }
+#
+# void main()
+# {
+# vec2 data[17];
+#
+# for (int i = 0; i < 4 + int(injectionSwitch.x); i++)
+# {
+# // Always true.
+# if (gl_FragCoord.x >= 0.0)
+# {
+# for (int j = 0; j < 4; j++)
+# {
+# data[4 * j + i].x = func();
+#
+# // Always true.
+# if (data[0].x == 5.0 || data[15].x == 5.0)
+# _GLF_color = vec4(1, 0, 0, 1);
+# else
+# _GLF_color = vec4(0);
+#
+# // Always false.
+# if (injectionSwitch.x > injectionSwitch.y)
+# return;
+# }
+# }
+# }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 128
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %12 %111
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %8 "func("
+ OpName %12 "gl_FragCoord"
+ OpName %26 "buf0"
+ OpMemberName %26 0 "injectionSwitch"
+ OpName %28 ""
+ OpName %42 "x"
+ OpName %60 "i"
+ OpName %78 "j"
+ OpName %89 "data"
+ OpName %111 "_GLF_color"
+ OpDecorate %12 BuiltIn FragCoord
+ OpMemberDecorate %26 0 Offset 0
+ OpDecorate %26 Block
+ OpDecorate %28 DescriptorSet 0
+ OpDecorate %28 Binding 0
+ OpDecorate %111 Location 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %7 = OpTypeFunction %6
+ %10 = OpTypeVector %6 4
+ %11 = OpTypePointer Input %10
+ %12 = OpVariable %11 Input
+ %13 = OpTypeInt 32 0
+ %14 = OpConstant %13 0
+ %15 = OpTypePointer Input %6
+ %18 = OpConstant %6 1
+ %19 = OpTypeBool
+ %23 = OpConstant %6 5
+ %25 = OpTypeVector %6 2
+ %26 = OpTypeStruct %25
+ %27 = OpTypePointer Uniform %26
+ %28 = OpVariable %27 Uniform
+ %29 = OpTypeInt 32 1
+ %30 = OpConstant %29 0
+ %31 = OpTypePointer Uniform %6
+ %34 = OpConstant %13 1
+ %41 = OpTypePointer Function %29
+ %48 = OpConstant %6 0
+ %51 = OpConstant %29 3
+ %67 = OpConstant %29 4
+ %86 = OpConstant %13 17
+ %87 = OpTypeArray %25 %86
+ %88 = OpTypePointer Function %87
+ %95 = OpTypePointer Function %6
+ %103 = OpConstant %29 15
+ %110 = OpTypePointer Output %10
+ %111 = OpVariable %110 Output
+ %112 = OpConstantComposite %10 %18 %48 %48 %18
+ %114 = OpConstantComposite %10 %48 %48 %48 %48
+ %124 = OpConstant %29 1
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %60 = OpVariable %41 Function
+ %78 = OpVariable %41 Function
+ %89 = OpVariable %88 Function
+ OpStore %60 %30
+ OpBranch %61
+ %61 = OpLabel
+ OpLoopMerge %63 %64 None
+ OpBranch %65
+ %65 = OpLabel
+ %66 = OpLoad %29 %60
+ %68 = OpAccessChain %31 %28 %30 %14
+ %69 = OpLoad %6 %68
+ %70 = OpConvertFToS %29 %69
+ %71 = OpIAdd %29 %67 %70
+ %72 = OpSLessThan %19 %66 %71
+ OpBranchConditional %72 %62 %63
+ %62 = OpLabel
+ %73 = OpAccessChain %15 %12 %14
+ %74 = OpLoad %6 %73
+ %75 = OpFOrdGreaterThanEqual %19 %74 %48
+ OpSelectionMerge %77 None
+ OpBranchConditional %75 %76 %77
+ %76 = OpLabel
+ OpStore %78 %30
+ OpBranch %79
+ %79 = OpLabel
+ OpLoopMerge %81 %82 None
+ OpBranch %83
+ %83 = OpLabel
+ %84 = OpLoad %29 %78
+ %85 = OpSLessThan %19 %84 %67
+ OpBranchConditional %85 %80 %81
+ %80 = OpLabel
+ %90 = OpLoad %29 %78
+ %91 = OpIMul %29 %67 %90
+ %92 = OpLoad %29 %60
+ %93 = OpIAdd %29 %91 %92
+ %94 = OpFunctionCall %6 %8
+ %96 = OpAccessChain %95 %89 %93 %14
+ OpStore %96 %94
+ %97 = OpAccessChain %95 %89 %30 %14
+ %98 = OpLoad %6 %97
+ %99 = OpFOrdEqual %19 %98 %23
+ %100 = OpLogicalNot %19 %99
+ OpSelectionMerge %102 None
+ OpBranchConditional %100 %101 %102
+ %101 = OpLabel
+ %104 = OpAccessChain %95 %89 %103 %14
+ %105 = OpLoad %6 %104
+ %106 = OpFOrdEqual %19 %105 %23
+ OpBranch %102
+ %102 = OpLabel
+ %107 = OpPhi %19 %99 %80 %106 %101
+ OpSelectionMerge %109 None
+ OpBranchConditional %107 %108 %113
+ %108 = OpLabel
+ OpStore %111 %112
+ OpBranch %109
+ %113 = OpLabel
+ OpStore %111 %114
+ OpBranch %109
+ %109 = OpLabel
+ %115 = OpAccessChain %31 %28 %30 %14
+ %116 = OpLoad %6 %115
+ %117 = OpAccessChain %31 %28 %30 %34
+ %118 = OpLoad %6 %117
+ %119 = OpFOrdGreaterThan %19 %116 %118
+ OpSelectionMerge %121 None
+ OpBranchConditional %119 %120 %121
+ %120 = OpLabel
+ OpReturn
+ %121 = OpLabel
+ OpBranch %82
+ %82 = OpLabel
+ %123 = OpLoad %29 %78
+ %125 = OpIAdd %29 %123 %124
+ OpStore %78 %125
+ OpBranch %79
+ %81 = OpLabel
+ OpBranch %77
+ %77 = OpLabel
+ OpBranch %64
+ %64 = OpLabel
+ %126 = OpLoad %29 %60
+ %127 = OpIAdd %29 %126 %124
+ OpStore %60 %127
+ OpBranch %61
+ %63 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %8 = OpFunction %6 None %7
+ %9 = OpLabel
+ %42 = OpVariable %41 Function
+ %16 = OpAccessChain %15 %12 %14
+ %17 = OpLoad %6 %16
+ %20 = OpFOrdLessThan %19 %17 %18
+ OpSelectionMerge %22 None
+ OpBranchConditional %20 %21 %22
+ %21 = OpLabel
+ OpReturnValue %23
+ %22 = OpLabel
+ %32 = OpAccessChain %31 %28 %30 %14
+ %33 = OpLoad %6 %32
+ %35 = OpAccessChain %31 %28 %30 %34
+ %36 = OpLoad %6 %35
+ %37 = OpFOrdGreaterThan %19 %33 %36
+ OpSelectionMerge %39 None
+ OpBranchConditional %37 %38 %39
+ %38 = OpLabel
+ OpReturnValue %18
+ %39 = OpLabel
+ %43 = OpAccessChain %31 %28 %30 %14
+ %44 = OpLoad %6 %43
+ %45 = OpConvertFToS %29 %44
+ OpStore %42 %45
+ %46 = OpAccessChain %31 %28 %30 %14
+ %47 = OpLoad %6 %46
+ %49 = OpExtInst %6 %1 FClamp %47 %48 %18
+ %50 = OpConvertFToS %29 %49
+ %52 = OpIMul %29 %50 %51
+ %53 = OpLoad %29 %42
+ %54 = OpIAdd %29 %53 %52
+ OpStore %42 %54
+ %55 = OpLoad %29 %42
+ %56 = OpConvertSToF %6 %55
+ %57 = OpFAdd %6 %23 %56
+ OpReturnValue %57
+ OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+ ATTACH variant_vertex_shader
+ ATTACH variant_fragment_shader
+ FRAMEBUFFER_SIZE 256 256
+ BIND BUFFER variant_framebuffer AS color LOCATION 0
+ BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
--- /dev/null
+#!amber
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader that assigns array values to other array
+
+# The test passes because shader always writes red.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# int data[9], temp[7];
+#
+# // Returns 1.0.
+# float func(int a)
+# {
+# int b = 0;
+#
+# data[0] = 5;
+# data[2] = 0;
+# data[4] = 0;
+# data[6] = 0;
+# data[8] = 0;
+#
+# // Always true.
+# if (gl_FragCoord.x >= 0.0)
+# {
+# while (b <= a)
+# {
+# if (b <= 5) {
+# // When b == 0, a value of data[0] is given to
+# // temp[0], making it's value 5.
+# temp[b] = data[b];
+# b += 2;
+# }
+# }
+# }
+#
+# for (int i = 0; i < 3; i++)
+# // On first iteration data[0] value is set to
+# // temp[0] + 1, which will be: 5 + 1 == 6.
+# data[i] = temp[0] + 1;
+#
+# // Always true.
+# if (temp[0] == 5 && data[0] == 6)
+# return 1.0;
+# else
+# return 0.0;
+# }
+#
+# void main()
+# {
+# for (int i = 0; i < 6; i++)
+# {
+# func(i);
+#
+# // Always true.
+# if(func(i) == 1.0)
+# _GLF_color = vec4(1, 0, 0, 1);
+# else
+# _GLF_color = vec4(0);
+# }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 123
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %33 %117
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %11 "func(i1;"
+ OpName %10 "a"
+ OpName %13 "b"
+ OpName %19 "data"
+ OpName %33 "gl_FragCoord"
+ OpName %58 "temp"
+ OpName %66 "i"
+ OpName %99 "i"
+ OpName %107 "param"
+ OpName %110 "param"
+ OpName %117 "_GLF_color"
+ OpDecorate %33 BuiltIn FragCoord
+ OpDecorate %117 Location 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %7 = OpTypePointer Function %6
+ %8 = OpTypeFloat 32
+ %9 = OpTypeFunction %8 %7
+ %14 = OpConstant %6 0
+ %15 = OpTypeInt 32 0
+ %16 = OpConstant %15 9
+ %17 = OpTypeArray %6 %16
+ %18 = OpTypePointer Private %17
+ %19 = OpVariable %18 Private
+ %20 = OpConstant %6 5
+ %21 = OpTypePointer Private %6
+ %23 = OpConstant %6 2
+ %25 = OpConstant %6 4
+ %27 = OpConstant %6 6
+ %29 = OpConstant %6 8
+ %31 = OpTypeVector %8 4
+ %32 = OpTypePointer Input %31
+ %33 = OpVariable %32 Input
+ %34 = OpConstant %15 0
+ %35 = OpTypePointer Input %8
+ %38 = OpConstant %8 0
+ %39 = OpTypeBool
+ %55 = OpConstant %15 7
+ %56 = OpTypeArray %6 %55
+ %57 = OpTypePointer Private %56
+ %58 = OpVariable %57 Private
+ %73 = OpConstant %6 3
+ %78 = OpConstant %6 1
+ %94 = OpConstant %8 1
+ %116 = OpTypePointer Output %31
+ %117 = OpVariable %116 Output
+ %118 = OpConstantComposite %31 %94 %38 %38 %94
+ %120 = OpConstantComposite %31 %38 %38 %38 %38
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %99 = OpVariable %7 Function
+ %107 = OpVariable %7 Function
+ %110 = OpVariable %7 Function
+ OpStore %99 %14
+ OpBranch %100
+ %100 = OpLabel
+ OpLoopMerge %102 %103 None
+ OpBranch %104
+ %104 = OpLabel
+ %105 = OpLoad %6 %99
+ %106 = OpSLessThan %39 %105 %27
+ OpBranchConditional %106 %101 %102
+ %101 = OpLabel
+ %108 = OpLoad %6 %99
+ OpStore %107 %108
+ %109 = OpFunctionCall %8 %11 %107
+ %111 = OpLoad %6 %99
+ OpStore %110 %111
+ %112 = OpFunctionCall %8 %11 %110
+ %113 = OpFOrdEqual %39 %112 %94
+ OpSelectionMerge %115 None
+ OpBranchConditional %113 %114 %119
+ %114 = OpLabel
+ OpStore %117 %118
+ OpBranch %115
+ %119 = OpLabel
+ OpStore %117 %120
+ OpBranch %115
+ %115 = OpLabel
+ OpBranch %103
+ %103 = OpLabel
+ %121 = OpLoad %6 %99
+ %122 = OpIAdd %6 %121 %78
+ OpStore %99 %122
+ OpBranch %100
+ %102 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %11 = OpFunction %8 None %9
+ %10 = OpFunctionParameter %7
+ %12 = OpLabel
+ %13 = OpVariable %7 Function
+ %66 = OpVariable %7 Function
+ OpStore %13 %14
+ %22 = OpAccessChain %21 %19 %14
+ OpStore %22 %20
+ %24 = OpAccessChain %21 %19 %23
+ OpStore %24 %14
+ %26 = OpAccessChain %21 %19 %25
+ OpStore %26 %14
+ %28 = OpAccessChain %21 %19 %27
+ OpStore %28 %14
+ %30 = OpAccessChain %21 %19 %29
+ OpStore %30 %14
+ %36 = OpAccessChain %35 %33 %34
+ %37 = OpLoad %8 %36
+ %40 = OpFOrdGreaterThanEqual %39 %37 %38
+ OpSelectionMerge %42 None
+ OpBranchConditional %40 %41 %42
+ %41 = OpLabel
+ OpBranch %43
+ %43 = OpLabel
+ OpLoopMerge %45 %46 None
+ OpBranch %47
+ %47 = OpLabel
+ %48 = OpLoad %6 %13
+ %49 = OpLoad %6 %10
+ %50 = OpSLessThanEqual %39 %48 %49
+ OpBranchConditional %50 %44 %45
+ %44 = OpLabel
+ %51 = OpLoad %6 %13
+ %52 = OpSLessThanEqual %39 %51 %20
+ OpSelectionMerge %54 None
+ OpBranchConditional %52 %53 %54
+ %53 = OpLabel
+ %59 = OpLoad %6 %13
+ %60 = OpLoad %6 %13
+ %61 = OpAccessChain %21 %19 %60
+ %62 = OpLoad %6 %61
+ %63 = OpAccessChain %21 %58 %59
+ OpStore %63 %62
+ %64 = OpLoad %6 %13
+ %65 = OpIAdd %6 %64 %23
+ OpStore %13 %65
+ OpBranch %54
+ %54 = OpLabel
+ OpBranch %46
+ %46 = OpLabel
+ OpBranch %43
+ %45 = OpLabel
+ OpBranch %42
+ %42 = OpLabel
+ OpStore %66 %14
+ OpBranch %67
+ %67 = OpLabel
+ OpLoopMerge %69 %70 None
+ OpBranch %71
+ %71 = OpLabel
+ %72 = OpLoad %6 %66
+ %74 = OpSLessThan %39 %72 %73
+ OpBranchConditional %74 %68 %69
+ %68 = OpLabel
+ %75 = OpLoad %6 %66
+ %76 = OpAccessChain %21 %58 %14
+ %77 = OpLoad %6 %76
+ %79 = OpIAdd %6 %77 %78
+ %80 = OpAccessChain %21 %19 %75
+ OpStore %80 %79
+ OpBranch %70
+ %70 = OpLabel
+ %81 = OpLoad %6 %66
+ %82 = OpIAdd %6 %81 %78
+ OpStore %66 %82
+ OpBranch %67
+ %69 = OpLabel
+ %83 = OpAccessChain %21 %58 %14
+ %84 = OpLoad %6 %83
+ %85 = OpIEqual %39 %84 %20
+ OpSelectionMerge %87 None
+ OpBranchConditional %85 %86 %87
+ %86 = OpLabel
+ %88 = OpAccessChain %21 %19 %14
+ %89 = OpLoad %6 %88
+ %90 = OpIEqual %39 %89 %27
+ OpBranch %87
+ %87 = OpLabel
+ %91 = OpPhi %39 %85 %69 %90 %86
+ OpSelectionMerge %93 None
+ OpBranchConditional %91 %92 %96
+ %92 = OpLabel
+ OpReturnValue %94
+ %96 = OpLabel
+ OpReturnValue %38
+ %93 = OpLabel
+ OpUnreachable
+ OpFunctionEnd
+END
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+ ATTACH variant_vertex_shader
+ ATTACH variant_fragment_shader
+ FRAMEBUFFER_SIZE 256 256
+ BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
--- /dev/null
+#!amber
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader that assigns array values to other array
+
+# The test passes because shader always writes red.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void func(int x)
+# {
+# int data[9], temp[2];
+# int a = 0;
+# data[0] = 5;
+#
+# // For the values of x used in this test, the following loop
+# // runs at least twice, making temp[0] = 5 and temp[1] = 5.
+# while (a <= x)
+# {
+# // Always true.
+# if (a <= 10) {
+# // When a == 0 this sets temp[0] to data[0] == 5;
+# // otherwise it sets temp[1] to data[0] == 5.
+# temp[min(a, 1)] = data[min(a, 0)];
+# a++;
+# }
+# }
+#
+# // This loop sets data[0] and data[1] to 5 and 6.
+# for (int i = 0; i < 2; i++)
+# data[i] = temp[0] + i;
+#
+# if (data[0] == 5 && data[1] == 6)
+# _GLF_color = vec4(1, 0, 0, 1);
+# else
+# _GLF_color = vec4(0);
+# }
+#
+# void main()
+# {
+# for (int i = 1; i < 6; i++)
+# func(i);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 100
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %81
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %10 "func(i1;"
+ OpName %9 "x"
+ OpName %12 "a"
+ OpName %18 "data"
+ OpName %38 "temp"
+ OpName %49 "i"
+ OpName %81 "_GLF_color"
+ OpName %87 "i"
+ OpName %95 "param"
+ OpDecorate %81 Location 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %7 = OpTypePointer Function %6
+ %8 = OpTypeFunction %2 %7
+ %13 = OpConstant %6 0
+ %14 = OpTypeInt 32 0
+ %15 = OpConstant %14 9
+ %16 = OpTypeArray %6 %15
+ %17 = OpTypePointer Function %16
+ %19 = OpConstant %6 5
+ %28 = OpTypeBool
+ %31 = OpConstant %6 10
+ %35 = OpConstant %14 2
+ %36 = OpTypeArray %6 %35
+ %37 = OpTypePointer Function %36
+ %40 = OpConstant %6 1
+ %56 = OpConstant %6 2
+ %73 = OpConstant %6 6
+ %78 = OpTypeFloat 32
+ %79 = OpTypeVector %78 4
+ %80 = OpTypePointer Output %79
+ %81 = OpVariable %80 Output
+ %82 = OpConstant %78 1
+ %83 = OpConstant %78 0
+ %84 = OpConstantComposite %79 %82 %83 %83 %82
+ %86 = OpConstantComposite %79 %83 %83 %83 %83
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %87 = OpVariable %7 Function
+ %95 = OpVariable %7 Function
+ OpStore %87 %40
+ OpBranch %88
+ %88 = OpLabel
+ OpLoopMerge %90 %91 None
+ OpBranch %92
+ %92 = OpLabel
+ %93 = OpLoad %6 %87
+ %94 = OpSLessThan %28 %93 %73
+ OpBranchConditional %94 %89 %90
+ %89 = OpLabel
+ %96 = OpLoad %6 %87
+ OpStore %95 %96
+ %97 = OpFunctionCall %2 %10 %95
+ OpBranch %91
+ %91 = OpLabel
+ %98 = OpLoad %6 %87
+ %99 = OpIAdd %6 %98 %40
+ OpStore %87 %99
+ OpBranch %88
+ %90 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %10 = OpFunction %2 None %8
+ %9 = OpFunctionParameter %7
+ %11 = OpLabel
+ %12 = OpVariable %7 Function
+ %18 = OpVariable %17 Function
+ %38 = OpVariable %37 Function
+ %49 = OpVariable %7 Function
+ OpStore %12 %13
+ %20 = OpAccessChain %7 %18 %13
+ OpStore %20 %19
+ OpBranch %21
+ %21 = OpLabel
+ OpLoopMerge %23 %24 None
+ OpBranch %25
+ %25 = OpLabel
+ %26 = OpLoad %6 %12
+ %27 = OpLoad %6 %9
+ %29 = OpSLessThanEqual %28 %26 %27
+ OpBranchConditional %29 %22 %23
+ %22 = OpLabel
+ %30 = OpLoad %6 %12
+ %32 = OpSLessThanEqual %28 %30 %31
+ OpSelectionMerge %34 None
+ OpBranchConditional %32 %33 %34
+ %33 = OpLabel
+ %39 = OpLoad %6 %12
+ %41 = OpExtInst %6 %1 SMin %39 %40
+ %42 = OpLoad %6 %12
+ %43 = OpExtInst %6 %1 SMin %42 %13
+ %44 = OpAccessChain %7 %18 %43
+ %45 = OpLoad %6 %44
+ %46 = OpAccessChain %7 %38 %41
+ OpStore %46 %45
+ %47 = OpLoad %6 %12
+ %48 = OpIAdd %6 %47 %40
+ OpStore %12 %48
+ OpBranch %34
+ %34 = OpLabel
+ OpBranch %24
+ %24 = OpLabel
+ OpBranch %21
+ %23 = OpLabel
+ OpStore %49 %13
+ OpBranch %50
+ %50 = OpLabel
+ OpLoopMerge %52 %53 None
+ OpBranch %54
+ %54 = OpLabel
+ %55 = OpLoad %6 %49
+ %57 = OpSLessThan %28 %55 %56
+ OpBranchConditional %57 %51 %52
+ %51 = OpLabel
+ %58 = OpLoad %6 %49
+ %59 = OpAccessChain %7 %38 %13
+ %60 = OpLoad %6 %59
+ %61 = OpLoad %6 %49
+ %62 = OpIAdd %6 %60 %61
+ %63 = OpAccessChain %7 %18 %58
+ OpStore %63 %62
+ OpBranch %53
+ %53 = OpLabel
+ %64 = OpLoad %6 %49
+ %65 = OpIAdd %6 %64 %40
+ OpStore %49 %65
+ OpBranch %50
+ %52 = OpLabel
+ %66 = OpAccessChain %7 %18 %13
+ %67 = OpLoad %6 %66
+ %68 = OpIEqual %28 %67 %19
+ OpSelectionMerge %70 None
+ OpBranchConditional %68 %69 %70
+ %69 = OpLabel
+ %71 = OpAccessChain %7 %18 %40
+ %72 = OpLoad %6 %71
+ %74 = OpIEqual %28 %72 %73
+ OpBranch %70
+ %70 = OpLabel
+ %75 = OpPhi %28 %68 %52 %74 %69
+ OpSelectionMerge %77 None
+ OpBranchConditional %75 %76 %85
+ %76 = OpLabel
+ OpStore %81 %84
+ OpBranch %77
+ %85 = OpLabel
+ OpStore %81 %86
+ OpBranch %77
+ %77 = OpLabel
+ OpReturn
+ OpFunctionEnd
+END
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+ ATTACH variant_vertex_shader
+ ATTACH variant_fragment_shader
+ FRAMEBUFFER_SIZE 256 256
+ BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
--- /dev/null
+#!amber
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: Cosh returns inf for one component which is never used
+
+# The test passes because shader always writes red.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+# float zero;
+# };
+#
+# // Returns 3.0 if b > 1, otherwise returns 5.0.
+# float func(int b)
+# {
+# for (int ndx = 0; ndx < 2; ndx++)
+# {
+# // Always false.
+# if (gl_FragCoord.x < 0.0)
+# {
+# for (int i = 0; i < 2; i++)
+# {
+# // Always false.
+# if (int(cosh(vec2(1, 800)).x) <= 1)
+# discard;
+# }
+# }
+# }
+#
+# if (b > 1)
+# return 3.0;
+#
+# // Always false.
+# if (gl_FragCoord.x < 0.0)
+# _GLF_color = vec4(0);
+#
+# return 5.0;
+# }
+#
+# void main()
+# {
+# _GLF_color = vec4(1);
+# float f = 0.0;
+#
+# do
+# {
+# // Always false.
+# if (int(_GLF_color.y) < 0)
+# discard;
+# else
+# f = func(int(zero)); // f == 5.0
+#
+# // Always false.
+# if (int(_GLF_color.y) > 65)
+# discard;
+#
+# for (int x = 0; x < int(zero) + 1; x++)
+# {
+# f = func(x + 10); // f == 3.0
+# }
+#
+# } while (int(zero) > 1); // Always false.
+#
+# if (f == 3.0)
+# _GLF_color = vec4(1, 0, 0, 1);
+# else
+# _GLF_color = vec4(0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 140
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %26 %72
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %11 "func(i1;"
+ OpName %10 "b"
+ OpName %13 "ndx"
+ OpName %26 "gl_FragCoord"
+ OpName %36 "i"
+ OpName %72 "_GLF_color"
+ OpName %79 "f"
+ OpName %94 "buf0"
+ OpMemberName %94 0 "zero"
+ OpName %96 ""
+ OpName %101 "param"
+ OpName %111 "x"
+ OpName %126 "param"
+ OpDecorate %26 BuiltIn FragCoord
+ OpDecorate %72 Location 0
+ OpMemberDecorate %94 0 Offset 0
+ OpDecorate %94 Block
+ OpDecorate %96 DescriptorSet 0
+ OpDecorate %96 Binding 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %7 = OpTypePointer Function %6
+ %8 = OpTypeFloat 32
+ %9 = OpTypeFunction %8 %7
+ %14 = OpConstant %6 0
+ %21 = OpConstant %6 2
+ %22 = OpTypeBool
+ %24 = OpTypeVector %8 4
+ %25 = OpTypePointer Input %24
+ %26 = OpVariable %25 Input
+ %27 = OpTypeInt 32 0
+ %28 = OpConstant %27 0
+ %29 = OpTypePointer Input %8
+ %32 = OpConstant %8 0
+ %44 = OpTypeVector %8 2
+ %45 = OpConstant %8 1
+ %46 = OpConstant %8 800
+ %47 = OpConstantComposite %44 %45 %46
+ %51 = OpConstant %6 1
+ %64 = OpConstant %8 3
+ %71 = OpTypePointer Output %24
+ %72 = OpVariable %71 Output
+ %73 = OpConstantComposite %24 %32 %32 %32 %32
+ %74 = OpConstant %8 5
+ %77 = OpConstantComposite %24 %45 %45 %45 %45
+ %78 = OpTypePointer Function %8
+ %84 = OpConstant %27 1
+ %85 = OpTypePointer Output %8
+ %94 = OpTypeStruct %8
+ %95 = OpTypePointer Uniform %94
+ %96 = OpVariable %95 Uniform
+ %97 = OpTypePointer Uniform %8
+ %106 = OpConstant %6 65
+ %124 = OpConstant %6 10
+ %138 = OpConstantComposite %24 %45 %32 %32 %45
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %79 = OpVariable %78 Function
+ %101 = OpVariable %7 Function
+ %111 = OpVariable %7 Function
+ %126 = OpVariable %7 Function
+ OpStore %72 %77
+ OpStore %79 %32
+ OpBranch %80
+ %80 = OpLabel
+ OpLoopMerge %82 %83 None
+ OpBranch %81
+ %81 = OpLabel
+ %86 = OpAccessChain %85 %72 %84
+ %87 = OpLoad %8 %86
+ %88 = OpConvertFToS %6 %87
+ %89 = OpSLessThan %22 %88 %14
+ OpSelectionMerge %91 None
+ OpBranchConditional %89 %90 %93
+ %90 = OpLabel
+ OpKill
+ %93 = OpLabel
+ %98 = OpAccessChain %97 %96 %14
+ %99 = OpLoad %8 %98
+ %100 = OpConvertFToS %6 %99
+ OpStore %101 %100
+ %102 = OpFunctionCall %8 %11 %101
+ OpStore %79 %102
+ OpBranch %91
+ %91 = OpLabel
+ %103 = OpAccessChain %85 %72 %84
+ %104 = OpLoad %8 %103
+ %105 = OpConvertFToS %6 %104
+ %107 = OpSGreaterThan %22 %105 %106
+ OpSelectionMerge %109 None
+ OpBranchConditional %107 %108 %109
+ %108 = OpLabel
+ OpKill
+ %109 = OpLabel
+ OpStore %111 %14
+ OpBranch %112
+ %112 = OpLabel
+ OpLoopMerge %114 %115 None
+ OpBranch %116
+ %116 = OpLabel
+ %117 = OpLoad %6 %111
+ %118 = OpAccessChain %97 %96 %14
+ %119 = OpLoad %8 %118
+ %120 = OpConvertFToS %6 %119
+ %121 = OpIAdd %6 %120 %51
+ %122 = OpSLessThan %22 %117 %121
+ OpBranchConditional %122 %113 %114
+ %113 = OpLabel
+ %123 = OpLoad %6 %111
+ %125 = OpIAdd %6 %123 %124
+ OpStore %126 %125
+ %127 = OpFunctionCall %8 %11 %126
+ OpStore %79 %127
+ OpBranch %115
+ %115 = OpLabel
+ %128 = OpLoad %6 %111
+ %129 = OpIAdd %6 %128 %51
+ OpStore %111 %129
+ OpBranch %112
+ %114 = OpLabel
+ OpBranch %83
+ %83 = OpLabel
+ %130 = OpAccessChain %97 %96 %14
+ %131 = OpLoad %8 %130
+ %132 = OpConvertFToS %6 %131
+ %133 = OpSGreaterThan %22 %132 %51
+ OpBranchConditional %133 %80 %82
+ %82 = OpLabel
+ %134 = OpLoad %8 %79
+ %135 = OpFOrdEqual %22 %134 %64
+ OpSelectionMerge %137 None
+ OpBranchConditional %135 %136 %139
+ %136 = OpLabel
+ OpStore %72 %138
+ OpBranch %137
+ %139 = OpLabel
+ OpStore %72 %73
+ OpBranch %137
+ %137 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %11 = OpFunction %8 None %9
+ %10 = OpFunctionParameter %7
+ %12 = OpLabel
+ %13 = OpVariable %7 Function
+ %36 = OpVariable %7 Function
+ OpStore %13 %14
+ OpBranch %15
+ %15 = OpLabel
+ OpLoopMerge %17 %18 None
+ OpBranch %19
+ %19 = OpLabel
+ %20 = OpLoad %6 %13
+ %23 = OpSLessThan %22 %20 %21
+ OpBranchConditional %23 %16 %17
+ %16 = OpLabel
+ %30 = OpAccessChain %29 %26 %28
+ %31 = OpLoad %8 %30
+ %33 = OpFOrdLessThan %22 %31 %32
+ OpSelectionMerge %35 None
+ OpBranchConditional %33 %34 %35
+ %34 = OpLabel
+ OpStore %36 %14
+ OpBranch %37
+ %37 = OpLabel
+ OpLoopMerge %39 %40 None
+ OpBranch %41
+ %41 = OpLabel
+ %42 = OpLoad %6 %36
+ %43 = OpSLessThan %22 %42 %21
+ OpBranchConditional %43 %38 %39
+ %38 = OpLabel
+ %48 = OpExtInst %44 %1 Cosh %47
+ %49 = OpCompositeExtract %8 %48 0
+ %50 = OpConvertFToS %6 %49
+ %52 = OpSLessThanEqual %22 %50 %51
+ OpSelectionMerge %54 None
+ OpBranchConditional %52 %53 %54
+ %53 = OpLabel
+ OpKill
+ %54 = OpLabel
+ OpBranch %40
+ %40 = OpLabel
+ %56 = OpLoad %6 %36
+ %57 = OpIAdd %6 %56 %51
+ OpStore %36 %57
+ OpBranch %37
+ %39 = OpLabel
+ OpBranch %35
+ %35 = OpLabel
+ OpBranch %18
+ %18 = OpLabel
+ %58 = OpLoad %6 %13
+ %59 = OpIAdd %6 %58 %51
+ OpStore %13 %59
+ OpBranch %15
+ %17 = OpLabel
+ %60 = OpLoad %6 %10
+ %61 = OpSGreaterThan %22 %60 %51
+ OpSelectionMerge %63 None
+ OpBranchConditional %61 %62 %63
+ %62 = OpLabel
+ OpReturnValue %64
+ %63 = OpLabel
+ %66 = OpAccessChain %29 %26 %28
+ %67 = OpLoad %8 %66
+ %68 = OpFOrdLessThan %22 %67 %32
+ OpSelectionMerge %70 None
+ OpBranchConditional %68 %69 %70
+ %69 = OpLabel
+ OpStore %72 %73
+ OpBranch %70
+ %70 = OpLabel
+ OpReturnValue %74
+ OpFunctionEnd
+END
+
+# uniforms for variant
+
+# zero
+BUFFER variant_zero DATA_TYPE float DATA
+ 0.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+ ATTACH variant_vertex_shader
+ ATTACH variant_fragment_shader
+ FRAMEBUFFER_SIZE 256 256
+ BIND BUFFER variant_framebuffer AS color LOCATION 0
+ BIND BUFFER variant_zero AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
--- /dev/null
+#!amber
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader that creates the color inside two loops
+
+# The test passes because shader always writes red.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+# precision highp int;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+# vec2 injectionSwitch;
+# };
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+# vec2 v = vec2(0);
+# float floats[9];
+# floats[1] = 0.0;
+# int one = int(injectionSwitch.y);
+#
+# // Iterates once.
+# do
+# {
+# for (int i = 0; i < one; i++)
+# {
+# if (i == 0)
+# {
+# bool alwaysFalse = injectionSwitch.x > injectionSwitch.y;
+#
+# if (!alwaysFalse)
+# {
+# floats[one] = 1.0;
+# _GLF_color = vec4(1.0, 1.0, 0.0, 1.0);
+# }
+#
+# v[one] = 1.0;
+#
+# if (alwaysFalse)
+# discard;
+#
+# // Always false.
+# if (injectionSwitch.y < 0.0)
+# _GLF_color = vec4(0.0, 1.0, 0.0, 1.0);
+# }
+# }
+# } while (one < 0);
+#
+# // Always true.
+# if (gl_FragCoord.y >= 0.0)
+# {
+# // Always true.
+# if (v.y == 1.0 && floats[1] == 1.0)
+# _GLF_color = vec4(1, 0, 0, 1);
+# }
+# else
+# _GLF_color = vec4(0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 107
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %67 %86
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %9 "v"
+ OpName %16 "floats"
+ OpName %22 "one"
+ OpName %23 "buf0"
+ OpMemberName %23 0 "injectionSwitch"
+ OpName %25 ""
+ OpName %36 "i"
+ OpName %51 "alwaysFalse"
+ OpName %67 "_GLF_color"
+ OpName %86 "gl_FragCoord"
+ OpMemberDecorate %23 0 Offset 0
+ OpDecorate %23 Block
+ OpDecorate %25 DescriptorSet 0
+ OpDecorate %25 Binding 0
+ OpDecorate %67 Location 0
+ OpDecorate %86 BuiltIn FragCoord
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %7 = OpTypeVector %6 2
+ %8 = OpTypePointer Function %7
+ %10 = OpConstant %6 0
+ %11 = OpConstantComposite %7 %10 %10
+ %12 = OpTypeInt 32 0
+ %13 = OpConstant %12 9
+ %14 = OpTypeArray %6 %13
+ %15 = OpTypePointer Function %14
+ %17 = OpTypeInt 32 1
+ %18 = OpConstant %17 1
+ %19 = OpTypePointer Function %6
+ %21 = OpTypePointer Function %17
+ %23 = OpTypeStruct %7
+ %24 = OpTypePointer Uniform %23
+ %25 = OpVariable %24 Uniform
+ %26 = OpConstant %17 0
+ %27 = OpConstant %12 1
+ %28 = OpTypePointer Uniform %6
+ %44 = OpTypeBool
+ %50 = OpTypePointer Function %44
+ %52 = OpConstant %12 0
+ %63 = OpConstant %6 1
+ %65 = OpTypeVector %6 4
+ %66 = OpTypePointer Output %65
+ %67 = OpVariable %66 Output
+ %68 = OpConstantComposite %65 %63 %63 %10 %63
+ %80 = OpConstantComposite %65 %10 %63 %10 %63
+ %85 = OpTypePointer Input %65
+ %86 = OpVariable %85 Input
+ %87 = OpTypePointer Input %6
+ %104 = OpConstantComposite %65 %63 %10 %10 %63
+ %106 = OpConstantComposite %65 %10 %10 %10 %10
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %9 = OpVariable %8 Function
+ %16 = OpVariable %15 Function
+ %22 = OpVariable %21 Function
+ %36 = OpVariable %21 Function
+ %51 = OpVariable %50 Function
+ OpStore %9 %11
+ %20 = OpAccessChain %19 %16 %18
+ OpStore %20 %10
+ %29 = OpAccessChain %28 %25 %26 %27
+ %30 = OpLoad %6 %29
+ %31 = OpConvertFToS %17 %30
+ OpStore %22 %31
+ OpBranch %32
+ %32 = OpLabel
+ OpLoopMerge %34 %35 None
+ OpBranch %33
+ %33 = OpLabel
+ OpStore %36 %26
+ OpBranch %37
+ %37 = OpLabel
+ OpLoopMerge %39 %40 None
+ OpBranch %41
+ %41 = OpLabel
+ %42 = OpLoad %17 %36
+ %43 = OpLoad %17 %22
+ %45 = OpSLessThan %44 %42 %43
+ OpBranchConditional %45 %38 %39
+ %38 = OpLabel
+ %46 = OpLoad %17 %36
+ %47 = OpIEqual %44 %46 %26
+ OpSelectionMerge %49 None
+ OpBranchConditional %47 %48 %49
+ %48 = OpLabel
+ %53 = OpAccessChain %28 %25 %26 %52
+ %54 = OpLoad %6 %53
+ %55 = OpAccessChain %28 %25 %26 %27
+ %56 = OpLoad %6 %55
+ %57 = OpFOrdGreaterThan %44 %54 %56
+ OpStore %51 %57
+ %58 = OpLoad %44 %51
+ %59 = OpLogicalNot %44 %58
+ OpSelectionMerge %61 None
+ OpBranchConditional %59 %60 %61
+ %60 = OpLabel
+ %62 = OpLoad %17 %22
+ %64 = OpAccessChain %19 %16 %62
+ OpStore %64 %63
+ OpStore %67 %68
+ OpBranch %61
+ %61 = OpLabel
+ %69 = OpLoad %17 %22
+ %70 = OpAccessChain %19 %9 %69
+ OpStore %70 %63
+ %71 = OpLoad %44 %51
+ OpSelectionMerge %73 None
+ OpBranchConditional %71 %72 %73
+ %72 = OpLabel
+ OpKill
+ %73 = OpLabel
+ %75 = OpAccessChain %28 %25 %26 %27
+ %76 = OpLoad %6 %75
+ %77 = OpFOrdLessThan %44 %76 %10
+ OpSelectionMerge %79 None
+ OpBranchConditional %77 %78 %79
+ %78 = OpLabel
+ OpStore %67 %80
+ OpBranch %79
+ %79 = OpLabel
+ OpBranch %49
+ %49 = OpLabel
+ OpBranch %40
+ %40 = OpLabel
+ %81 = OpLoad %17 %36
+ %82 = OpIAdd %17 %81 %18
+ OpStore %36 %82
+ OpBranch %37
+ %39 = OpLabel
+ OpBranch %35
+ %35 = OpLabel
+ %83 = OpLoad %17 %22
+ %84 = OpSLessThan %44 %83 %26
+ OpBranchConditional %84 %32 %34
+ %34 = OpLabel
+ %88 = OpAccessChain %87 %86 %27
+ %89 = OpLoad %6 %88
+ %90 = OpFOrdGreaterThanEqual %44 %89 %10
+ OpSelectionMerge %92 None
+ OpBranchConditional %90 %91 %105
+ %91 = OpLabel
+ %93 = OpAccessChain %19 %9 %27
+ %94 = OpLoad %6 %93
+ %95 = OpFOrdEqual %44 %94 %63
+ OpSelectionMerge %97 None
+ OpBranchConditional %95 %96 %97
+ %96 = OpLabel
+ %98 = OpAccessChain %19 %16 %18
+ %99 = OpLoad %6 %98
+ %100 = OpFOrdEqual %44 %99 %63
+ OpBranch %97
+ %97 = OpLabel
+ %101 = OpPhi %44 %95 %91 %100 %96
+ OpSelectionMerge %103 None
+ OpBranchConditional %101 %102 %103
+ %102 = OpLabel
+ OpStore %67 %104
+ OpBranch %103
+ %103 = OpLabel
+ OpBranch %92
+ %105 = OpLabel
+ OpStore %67 %106
+ OpBranch %92
+ %92 = OpLabel
+ OpReturn
+ OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+ ATTACH variant_vertex_shader
+ ATTACH variant_fragment_shader
+ FRAMEBUFFER_SIZE 256 256
+ BIND BUFFER variant_framebuffer AS color LOCATION 0
+ BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
--- /dev/null
+#!amber
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader that has nested if condition in do while
+
+# The test passes because shader always writes red.
+
+# Optimized using spirv-opt with the following arguments:
+# '--eliminate-dead-code-aggressive'
+# '--copy-propagate-arrays'
+# '--copy-propagate-arrays'
+# '--vector-dce'
+# '--redundancy-elimination'
+# '--eliminate-local-single-block'
+# '--redundancy-elimination'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--combine-access-chains'
+# '--redundancy-elimination'
+# '--private-to-local'
+# '--simplify-instructions'
+# '--ccp'
+# '--eliminate-local-multi-store'
+# '--inline-entry-points-exhaustive'
+# '--if-conversion'
+# '--eliminate-dead-inserts'
+# spirv-opt commit hash: ab7ac60f14ae66006bed5c989a2cfd4c4881704c
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# float one()
+# {
+# return 1.0;
+# }
+#
+# void main()
+# {
+# vec2 v = vec2(0);
+# bool alwaysFalse = gl_FragCoord.x < -1.0;
+#
+# do
+# {
+# if (v.x < 2.0) // Always true
+# {
+# if (!alwaysFalse)
+# v[int(one())] = 1.0;
+# }
+# } while (alwaysFalse);
+#
+# if (v[0] == 0.0 && v[1] == 1.0)
+# _GLF_color = vec4(1, 0, 0, 1);
+# else
+# _GLF_color = vec4(0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 72
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %23 %64
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %8 "one("
+ OpName %15 "v"
+ OpName %20 "alwaysFalse"
+ OpName %23 "gl_FragCoord"
+ OpName %64 "_GLF_color"
+ OpDecorate %23 BuiltIn FragCoord
+ OpDecorate %64 Location 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %7 = OpTypeFunction %6
+ %10 = OpConstant %6 1
+ %13 = OpTypeVector %6 2
+ %14 = OpTypePointer Function %13
+ %16 = OpConstant %6 0
+ %17 = OpConstantComposite %13 %16 %16
+ %18 = OpTypeBool
+ %19 = OpTypePointer Function %18
+ %21 = OpTypeVector %6 4
+ %22 = OpTypePointer Input %21
+ %23 = OpVariable %22 Input
+ %24 = OpTypeInt 32 0
+ %25 = OpConstant %24 0
+ %26 = OpTypePointer Input %6
+ %29 = OpConstant %6 -1
+ %35 = OpTypePointer Function %6
+ %38 = OpConstant %6 2
+ %47 = OpTypeInt 32 1
+ %56 = OpConstant %24 1
+ %63 = OpTypePointer Output %21
+ %64 = OpVariable %63 Output
+ %65 = OpConstantComposite %21 %10 %16 %16 %10
+ %67 = OpConstantComposite %21 %16 %16 %16 %16
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %71 = OpVariable %35 Function
+ %15 = OpVariable %14 Function
+ %20 = OpVariable %19 Function
+ OpStore %15 %17
+ %27 = OpAccessChain %26 %23 %25
+ %28 = OpLoad %6 %27
+ %30 = OpFOrdLessThan %18 %28 %29
+ OpStore %20 %30
+ OpBranch %31
+ %31 = OpLabel
+ OpLoopMerge %33 %34 None
+ OpBranch %32
+ %32 = OpLabel
+ %36 = OpAccessChain %35 %15 %25
+ %37 = OpLoad %6 %36
+ %39 = OpFOrdLessThan %18 %37 %38
+ OpSelectionMerge %41 None
+ OpBranchConditional %39 %40 %41
+ %40 = OpLabel
+ %43 = OpLogicalNot %18 %30
+ OpSelectionMerge %45 None
+ OpBranchConditional %43 %44 %45
+ %44 = OpLabel
+ OpStore %71 %10
+ %46 = OpLoad %6 %71
+ %48 = OpConvertFToS %47 %46
+ %49 = OpAccessChain %35 %15 %48
+ OpStore %49 %10
+ OpBranch %45
+ %45 = OpLabel
+ OpBranch %41
+ %41 = OpLabel
+ OpBranch %34
+ %34 = OpLabel
+ OpBranchConditional %30 %31 %33
+ %33 = OpLabel
+ %52 = OpLoad %6 %36
+ %53 = OpFOrdEqual %18 %52 %16
+ OpSelectionMerge %55 None
+ OpBranchConditional %53 %54 %55
+ %54 = OpLabel
+ %57 = OpAccessChain %35 %15 %56
+ %58 = OpLoad %6 %57
+ %59 = OpFOrdEqual %18 %58 %10
+ OpBranch %55
+ %55 = OpLabel
+ %60 = OpPhi %18 %53 %33 %59 %54
+ OpSelectionMerge %62 None
+ OpBranchConditional %60 %61 %66
+ %61 = OpLabel
+ OpStore %64 %65
+ OpBranch %62
+ %66 = OpLabel
+ OpStore %64 %67
+ OpBranch %62
+ %62 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %8 = OpFunction %6 None %7
+ %9 = OpLabel
+ OpReturnValue %10
+ OpFunctionEnd
+END
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+ ATTACH variant_vertex_shader
+ ATTACH variant_fragment_shader
+ FRAMEBUFFER_SIZE 256 256
+ BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
--- /dev/null
+#!amber
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader that finds MSB from LSB
+
+# The test passes because shader always writes red.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+# // State of variables/expressions after "result += x;".
+# //
+# // i x i >> x findLSB findMSB result
+# // 0 0 0 -1 -1 0
+# // 0 1 0 -1 -1 1
+# // 1 0 1 0 -1 1
+# // 1 1 0 -1 -1 2
+#
+# int result = 0;
+# for (int i = 0; i < 2; i++)
+# {
+# for (int x = 0; x < 2; x++)
+# {
+# // findMSB(findLSB(i >> x)) is always -1.
+# for ( ; x > findMSB(findLSB(i >> x)) && x < 2; x++)
+# {
+# result += x;
+# }
+# }
+# }
+# if (result == 2)
+# _GLF_color = vec4(1, 0, 0, 1);
+# else
+# _GLF_color = vec4(0, 0, 0, 1);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 66
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %60
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %8 "result"
+ OpName %10 "i"
+ OpName %20 "x"
+ OpName %60 "_GLF_color"
+ OpDecorate %60 Location 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %7 = OpTypePointer Function %6
+ %9 = OpConstant %6 0
+ %17 = OpConstant %6 2
+ %18 = OpTypeBool
+ %47 = OpConstant %6 1
+ %57 = OpTypeFloat 32
+ %58 = OpTypeVector %57 4
+ %59 = OpTypePointer Output %58
+ %60 = OpVariable %59 Output
+ %61 = OpConstant %57 1
+ %62 = OpConstant %57 0
+ %63 = OpConstantComposite %58 %61 %62 %62 %61
+ %65 = OpConstantComposite %58 %62 %62 %62 %61
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %8 = OpVariable %7 Function
+ %10 = OpVariable %7 Function
+ %20 = OpVariable %7 Function
+ OpStore %8 %9
+ OpStore %10 %9
+ OpBranch %11
+ %11 = OpLabel
+ OpLoopMerge %13 %14 None
+ OpBranch %15
+ %15 = OpLabel
+ %16 = OpLoad %6 %10
+ %19 = OpSLessThan %18 %16 %17
+ OpBranchConditional %19 %12 %13
+ %12 = OpLabel
+ OpStore %20 %9
+ OpBranch %21
+ %21 = OpLabel
+ OpLoopMerge %23 %24 None
+ OpBranch %25
+ %25 = OpLabel
+ %26 = OpLoad %6 %20
+ %27 = OpSLessThan %18 %26 %17
+ OpBranchConditional %27 %22 %23
+ %22 = OpLabel
+ OpBranch %28
+ %28 = OpLabel
+ OpLoopMerge %30 %31 None
+ OpBranch %32
+ %32 = OpLabel
+ %33 = OpLoad %6 %20
+ %34 = OpLoad %6 %10
+ %35 = OpLoad %6 %20
+ %36 = OpShiftRightArithmetic %6 %34 %35
+ %37 = OpExtInst %6 %1 FindILsb %36
+ %38 = OpExtInst %6 %1 FindSMsb %37
+ %39 = OpSGreaterThan %18 %33 %38
+ %40 = OpLoad %6 %20
+ %41 = OpSLessThan %18 %40 %17
+ %42 = OpLogicalAnd %18 %39 %41
+ OpBranchConditional %42 %29 %30
+ %29 = OpLabel
+ %43 = OpLoad %6 %20
+ %44 = OpLoad %6 %8
+ %45 = OpIAdd %6 %44 %43
+ OpStore %8 %45
+ OpBranch %31
+ %31 = OpLabel
+ %46 = OpLoad %6 %20
+ %48 = OpIAdd %6 %46 %47
+ OpStore %20 %48
+ OpBranch %28
+ %30 = OpLabel
+ OpBranch %24
+ %24 = OpLabel
+ %49 = OpLoad %6 %20
+ %50 = OpIAdd %6 %49 %47
+ OpStore %20 %50
+ OpBranch %21
+ %23 = OpLabel
+ OpBranch %14
+ %14 = OpLabel
+ %51 = OpLoad %6 %10
+ %52 = OpIAdd %6 %51 %47
+ OpStore %10 %52
+ OpBranch %11
+ %13 = OpLabel
+ %53 = OpLoad %6 %8
+ %54 = OpIEqual %18 %53 %17
+ OpSelectionMerge %56 None
+ OpBranchConditional %54 %55 %64
+ %55 = OpLabel
+ OpStore %60 %63
+ OpBranch %56
+ %64 = OpLabel
+ OpStore %60 %65
+ OpBranch %56
+ %56 = OpLabel
+ OpReturn
+ OpFunctionEnd
+END
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+ ATTACH variant_vertex_shader
+ ATTACH variant_fragment_shader
+ FRAMEBUFFER_SIZE 256 256
+ BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
--- /dev/null
+#!amber
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader that compares a float and a coordinate
+
+# The test passes because shader always writes red.
+
+# Optimized using spirv-opt with the following arguments:
+# '--redundancy-elimination'
+# '--redundancy-elimination'
+# '--private-to-local'
+# '--eliminate-dead-inserts'
+# '--eliminate-dead-code-aggressive'
+# '--combine-access-chains'
+# '--reduce-load-size'
+# '--inline-entry-points-exhaustive'
+# '--vector-dce'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--copy-propagate-arrays'
+# '--vector-dce'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--combine-access-chains'
+# '--eliminate-dead-inserts'
+# '--eliminate-dead-branches'
+# '--if-conversion'
+# '--inline-entry-points-exhaustive'
+# '--simplify-instructions'
+# '--eliminate-local-single-store'
+# '--eliminate-dead-branches'
+# '--eliminate-local-single-block'
+# '--eliminate-local-multi-store'
+# '--convert-local-access-chains'
+# '--ccp'
+# spirv-opt commit hash: ab7ac60f14ae66006bed5c989a2cfd4c4881704c
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+# precision highp int;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+# vec2 injectionSwitch;
+# };
+# layout(location = 0) out vec4 _GLF_color;
+#
+# // Always returns 5.
+# float func()
+# {
+# float zero = 0.0;
+# bool alwaysFalse = gl_FragCoord.x < 0.0;
+#
+# do
+# {
+# if (injectionSwitch.x < injectionSwitch.y) // Always true
+# {
+# while (int(zero) <= bitfieldInsert(101, 0, 0, 0))
+# {
+# if (zero <= gl_FragCoord.x)
+# return 5.0; // Always returns here
+#
+# zero++;
+# }
+# }
+# } while (alwaysFalse);
+#
+# for (int u = 0; u < 1; u++)
+# {
+# if (!alwaysFalse)
+# return zero;
+# }
+#
+# return 0.0;
+# }
+#
+# void main()
+# {
+# float c = 0.0;
+# for (int i = 0; i < 1; i++)
+# {
+# if (!(gl_FragCoord.x < 0.0)) // Always true
+# c = func();
+# }
+#
+# if (c == 5.0)
+# _GLF_color = vec4(1, 0, 0, 1);
+# else
+# _GLF_color = vec4(0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 261
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %18 %109
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %8 "func("
+ OpName %11 "zero"
+ OpName %15 "alwaysFalse"
+ OpName %18 "gl_FragCoord"
+ OpName %30 "buf0"
+ OpMemberName %30 0 "injectionSwitch"
+ OpName %32 ""
+ OpName %67 "u"
+ OpName %86 "c"
+ OpName %87 "i"
+ OpName %109 "_GLF_color"
+ OpDecorate %18 BuiltIn FragCoord
+ OpMemberDecorate %30 0 Offset 0
+ OpDecorate %30 Block
+ OpDecorate %32 DescriptorSet 0
+ OpDecorate %32 Binding 0
+ OpDecorate %109 Location 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %7 = OpTypeFunction %6
+ %10 = OpTypePointer Function %6
+ %12 = OpConstant %6 0
+ %13 = OpTypeBool
+ %14 = OpTypePointer Function %13
+ %16 = OpTypeVector %6 4
+ %17 = OpTypePointer Input %16
+ %18 = OpVariable %17 Input
+ %19 = OpTypeInt 32 0
+ %20 = OpConstant %19 0
+ %21 = OpTypePointer Input %6
+ %29 = OpTypeVector %6 2
+ %30 = OpTypeStruct %29
+ %31 = OpTypePointer Uniform %30
+ %32 = OpVariable %31 Uniform
+ %33 = OpTypeInt 32 1
+ %34 = OpConstant %33 0
+ %35 = OpTypePointer Uniform %6
+ %38 = OpConstant %19 1
+ %51 = OpConstant %33 101
+ %60 = OpConstant %6 5
+ %63 = OpConstant %6 1
+ %66 = OpTypePointer Function %33
+ %74 = OpConstant %33 1
+ %108 = OpTypePointer Output %16
+ %109 = OpVariable %108 Output
+ %110 = OpConstantComposite %16 %63 %12 %12 %63
+ %112 = OpConstantComposite %16 %12 %12 %12 %12
+ %119 = OpConstantFalse %13
+ %121 = OpConstantTrue %13
+ %211 = OpUndef %6
+ %226 = OpUndef %13
+ %228 = OpUndef %33
+ %256 = OpUndef %6
+ %260 = OpUndef %13
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %128 = OpVariable %14 Function %119
+ %129 = OpVariable %10 Function
+ %130 = OpVariable %10 Function
+ %131 = OpVariable %14 Function
+ %132 = OpVariable %66 Function
+ %133 = OpVariable %10 Function
+ %86 = OpVariable %10 Function
+ %87 = OpVariable %66 Function
+ OpStore %86 %12
+ OpStore %87 %34
+ OpBranch %88
+ %88 = OpLabel
+ %210 = OpPhi %6 %211 %5 %227 %91
+ %188 = OpPhi %6 %12 %5 %225 %91
+ %187 = OpPhi %33 %34 %5 %103 %91
+ %94 = OpSLessThan %13 %187 %74
+ OpLoopMerge %90 %91 None
+ OpBranchConditional %94 %89 %90
+ %89 = OpLabel
+ %95 = OpAccessChain %21 %18 %20
+ %96 = OpLoad %6 %95
+ %97 = OpFOrdLessThan %13 %96 %12
+ %98 = OpLogicalNot %13 %97
+ OpSelectionMerge %100 None
+ OpBranchConditional %98 %99 %100
+ %99 = OpLabel
+ OpStore %128 %119
+ OpBranch %134
+ %134 = OpLabel
+ %221 = OpPhi %33 %187 %99 %228 %136
+ %209 = OpPhi %6 %210 %99 %211 %136
+ %194 = OpPhi %13 %119 %99 %226 %136
+ OpLoopMerge %135 %136 None
+ OpBranch %137
+ %137 = OpLabel
+ OpStore %130 %12
+ %138 = OpAccessChain %21 %18 %20
+ %139 = OpLoad %6 %138
+ %140 = OpFOrdLessThan %13 %139 %12
+ OpStore %131 %140
+ OpBranch %141
+ %141 = OpLabel
+ %193 = OpPhi %13 %119 %137 %196 %143
+ %190 = OpPhi %6 %12 %137 %201 %143
+ %220 = OpPhi %33 %221 %137 %222 %143
+ %208 = OpPhi %6 %209 %137 %212 %143
+ OpLoopMerge %142 %143 None
+ OpBranch %144
+ %144 = OpLabel
+ %145 = OpAccessChain %35 %32 %34 %20
+ %146 = OpLoad %6 %145
+ %147 = OpAccessChain %35 %32 %34 %38
+ %148 = OpLoad %6 %147
+ %149 = OpFOrdLessThan %13 %146 %148
+ OpSelectionMerge %150 None
+ OpBranchConditional %149 %151 %150
+ %151 = OpLabel
+ OpBranch %152
+ %152 = OpLabel
+ %189 = OpPhi %6 %190 %151 %165 %158
+ %154 = OpConvertFToS %33 %189
+ %155 = OpBitFieldInsert %33 %51 %34 %34 %34
+ %156 = OpSLessThanEqual %13 %154 %155
+ OpLoopMerge %157 %158 None
+ OpBranchConditional %156 %159 %157
+ %159 = OpLabel
+ %161 = OpFOrdLessThanEqual %13 %189 %139
+ OpSelectionMerge %162 None
+ OpBranchConditional %161 %163 %162
+ %163 = OpLabel
+ OpStore %128 %121
+ OpStore %129 %60
+ OpBranch %157
+ %162 = OpLabel
+ %165 = OpFAdd %6 %189 %63
+ OpStore %130 %165
+ OpBranch %158
+ %158 = OpLabel
+ OpBranch %152
+ %157 = OpLabel
+ %206 = OpPhi %6 %208 %152 %60 %163
+ %191 = OpPhi %13 %193 %152 %121 %163
+ OpSelectionMerge %167 None
+ OpBranchConditional %191 %142 %167
+ %167 = OpLabel
+ OpBranch %150
+ %150 = OpLabel
+ %222 = OpPhi %33 %220 %144 %220 %167
+ %212 = OpPhi %6 %208 %144 %206 %167
+ %201 = OpPhi %6 %190 %144 %189 %167
+ %196 = OpPhi %13 %193 %144 %191 %167
+ OpBranch %143
+ %143 = OpLabel
+ OpBranchConditional %140 %141 %142
+ %142 = OpLabel
+ %217 = OpPhi %33 %220 %157 %222 %143
+ %205 = OpPhi %6 %206 %157 %212 %143
+ %199 = OpPhi %6 %189 %157 %201 %143
+ %195 = OpPhi %13 %191 %157 %196 %143
+ OpSelectionMerge %170 None
+ OpBranchConditional %195 %135 %170
+ %170 = OpLabel
+ OpStore %132 %34
+ OpBranch %171
+ %171 = OpLabel
+ %197 = OpPhi %33 %34 %170 %183 %175
+ %173 = OpSLessThan %13 %197 %74
+ OpLoopMerge %174 %175 None
+ OpBranchConditional %173 %176 %174
+ %176 = OpLabel
+ %178 = OpLogicalNot %13 %140
+ OpSelectionMerge %179 None
+ OpBranchConditional %178 %180 %179
+ %180 = OpLabel
+ OpStore %128 %121
+ OpStore %129 %199
+ OpBranch %174
+ %179 = OpLabel
+ OpBranch %175
+ %175 = OpLabel
+ %183 = OpIAdd %33 %197 %74
+ OpStore %132 %183
+ OpBranch %171
+ %174 = OpLabel
+ %213 = OpPhi %6 %205 %171 %199 %180
+ %202 = OpPhi %13 %195 %171 %121 %180
+ OpSelectionMerge %185 None
+ OpBranchConditional %202 %135 %185
+ %185 = OpLabel
+ OpStore %128 %121
+ OpStore %129 %12
+ OpBranch %135
+ %136 = OpLabel
+ OpBranch %134
+ %135 = OpLabel
+ %204 = OpPhi %6 %205 %142 %213 %174 %12 %185
+ OpStore %133 %204
+ OpStore %86 %204
+ OpBranch %100
+ %100 = OpLabel
+ %227 = OpPhi %6 %210 %89 %204 %135
+ %225 = OpPhi %6 %188 %89 %204 %135
+ %215 = OpPhi %33 %187 %89 %217 %135
+ OpBranch %91
+ %91 = OpLabel
+ %103 = OpIAdd %33 %215 %74
+ OpStore %87 %103
+ OpBranch %88
+ %90 = OpLabel
+ %105 = OpFOrdEqual %13 %188 %60
+ OpSelectionMerge %107 None
+ OpBranchConditional %105 %106 %111
+ %106 = OpLabel
+ OpStore %109 %110
+ OpBranch %107
+ %111 = OpLabel
+ OpStore %109 %112
+ OpBranch %107
+ %107 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %8 = OpFunction %6 None %7
+ %9 = OpLabel
+ %120 = OpVariable %14 Function %119
+ %114 = OpVariable %10 Function
+ %11 = OpVariable %10 Function
+ %15 = OpVariable %14 Function
+ %67 = OpVariable %66 Function
+ OpBranch %116
+ %116 = OpLabel
+ %234 = OpPhi %13 %119 %9 %260 %118
+ OpLoopMerge %113 %118 None
+ OpBranch %117
+ %117 = OpLabel
+ OpStore %11 %12
+ %22 = OpAccessChain %21 %18 %20
+ %23 = OpLoad %6 %22
+ %24 = OpFOrdLessThan %13 %23 %12
+ OpStore %15 %24
+ OpBranch %25
+ %25 = OpLabel
+ %233 = OpPhi %13 %234 %117 %240 %28
+ %230 = OpPhi %6 %12 %117 %247 %28
+ %254 = OpPhi %6 %256 %117 %257 %28
+ OpLoopMerge %27 %28 None
+ OpBranch %26
+ %26 = OpLabel
+ %36 = OpAccessChain %35 %32 %34 %20
+ %37 = OpLoad %6 %36
+ %39 = OpAccessChain %35 %32 %34 %38
+ %40 = OpLoad %6 %39
+ %41 = OpFOrdLessThan %13 %37 %40
+ OpSelectionMerge %43 None
+ OpBranchConditional %41 %42 %43
+ %42 = OpLabel
+ OpBranch %44
+ %44 = OpLabel
+ %229 = OpPhi %6 %230 %42 %64 %47
+ %50 = OpConvertFToS %33 %229
+ %52 = OpBitFieldInsert %33 %51 %34 %34 %34
+ %53 = OpSLessThanEqual %13 %50 %52
+ OpLoopMerge %46 %47 None
+ OpBranchConditional %53 %45 %46
+ %45 = OpLabel
+ %57 = OpFOrdLessThanEqual %13 %229 %23
+ OpSelectionMerge %59 None
+ OpBranchConditional %57 %58 %59
+ %58 = OpLabel
+ OpStore %120 %121
+ OpStore %114 %60
+ OpBranch %46
+ %59 = OpLabel
+ %64 = OpFAdd %6 %229 %63
+ OpStore %11 %64
+ OpBranch %47
+ %47 = OpLabel
+ OpBranch %44
+ %46 = OpLabel
+ %252 = OpPhi %6 %254 %44 %60 %58
+ %231 = OpPhi %13 %233 %44 %121 %58
+ OpSelectionMerge %122 None
+ OpBranchConditional %231 %27 %122
+ %122 = OpLabel
+ OpBranch %43
+ %43 = OpLabel
+ %257 = OpPhi %6 %254 %26 %252 %122
+ %247 = OpPhi %6 %230 %26 %229 %122
+ %240 = OpPhi %13 %233 %26 %231 %122
+ OpBranch %28
+ %28 = OpLabel
+ OpBranchConditional %24 %25 %27
+ %27 = OpLabel
+ %251 = OpPhi %6 %252 %46 %257 %28
+ %245 = OpPhi %6 %229 %46 %247 %28
+ %239 = OpPhi %13 %231 %46 %240 %28
+ OpSelectionMerge %124 None
+ OpBranchConditional %239 %113 %124
+ %124 = OpLabel
+ OpStore %67 %34
+ OpBranch %68
+ %68 = OpLabel
+ %241 = OpPhi %33 %34 %124 %83 %71
+ %75 = OpSLessThan %13 %241 %74
+ OpLoopMerge %70 %71 None
+ OpBranchConditional %75 %69 %70
+ %69 = OpLabel
+ %77 = OpLogicalNot %13 %24
+ OpSelectionMerge %79 None
+ OpBranchConditional %77 %78 %79
+ %78 = OpLabel
+ OpStore %120 %121
+ OpStore %114 %245
+ OpBranch %70
+ %79 = OpLabel
+ OpBranch %71
+ %71 = OpLabel
+ %83 = OpIAdd %33 %241 %74
+ OpStore %67 %83
+ OpBranch %68
+ %70 = OpLabel
+ %258 = OpPhi %6 %251 %68 %245 %78
+ %248 = OpPhi %13 %239 %68 %121 %78
+ OpSelectionMerge %126 None
+ OpBranchConditional %248 %113 %126
+ %126 = OpLabel
+ OpStore %120 %121
+ OpStore %114 %12
+ OpBranch %113
+ %118 = OpLabel
+ OpBranch %116
+ %113 = OpLabel
+ %250 = OpPhi %6 %251 %27 %258 %70 %12 %126
+ OpReturnValue %250
+ OpFunctionEnd
+END
+
+# uniforms for variant
+
+# resolution
+BUFFER variant_resolution DATA_TYPE vec2<float> DATA
+ 256.0 256.0
+END
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+ ATTACH variant_vertex_shader
+ ATTACH variant_fragment_shader
+ FRAMEBUFFER_SIZE 256 256
+ BIND BUFFER variant_framebuffer AS color LOCATION 0
+ BIND BUFFER variant_resolution AS uniform DESCRIPTOR_SET 0 BINDING 1
+ BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
--- /dev/null
+#!amber
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A frag. shader that increments a value in nested for loop
+
+# The test passes because shader always writes red.
+
+# Optimized using spirv-opt with the following arguments:
+# '-O'
+# spirv-opt commit hash: ab7ac60f14ae66006bed5c989a2cfd4c4881704c
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0 {
+# vec2 injectionSwitch;
+# };
+#
+# // func returns 1 if "ref" > 0.
+# int func(int ref)
+# {
+# bool alwaysFalse = gl_FragCoord.x < -1.0;
+#
+# if (!(injectionSwitch.x < 0.0))
+# {
+# if (alwaysFalse)
+# return 0;
+#
+# // Returns on first iteration.
+# for (int i = 1; i < ref; i++)
+# {
+# if (alwaysFalse)
+# continue;
+#
+# // Always true.
+# if (i > 0)
+# return 1;
+# }
+# }
+# return 0;
+# }
+#
+# void main()
+# {
+# bool alwaysFalse = injectionSwitch.x < -1.0;
+# int value = 0;
+#
+# // Iterates once.
+# for (int i = 0; i < (gl_FragCoord.y > -1.0 ? 10 : 100); i++)
+# {
+# for (int k = 0; k < 2; k++)
+# {
+# // After 2 iterations: value == 2
+# value += func(3);
+#
+# if (alwaysFalse)
+# {
+# while (alwaysFalse)
+# {
+# _GLF_color = vec4(i);
+# }
+# return;
+# }
+# }
+#
+# if (!alwaysFalse)
+# break;
+# }
+#
+# // Iterates 2 times.
+# for (int i = 0; i < int(injectionSwitch.y + 1.0); i++)
+# {
+# // After 2 iterations: value == 4
+# value += func(3);
+# // func(0) will always return 0.
+# if (alwaysFalse || func(0) != 0)
+# break;
+# }
+#
+# if (value == 4)
+# _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+# else
+# _GLF_color = vec4(0.0, 0.0, 0.0, 0.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 454
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %18 %110
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %18 "gl_FragCoord"
+ OpName %27 "buf0"
+ OpMemberName %27 0 "injectionSwitch"
+ OpName %29 ""
+ OpName %110 "_GLF_color"
+ OpDecorate %18 BuiltIn FragCoord
+ OpMemberDecorate %27 0 Offset 0
+ OpDecorate %27 Block
+ OpDecorate %29 DescriptorSet 0
+ OpDecorate %29 Binding 0
+ OpDecorate %110 Location 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %12 = OpTypeBool
+ %15 = OpTypeFloat 32
+ %16 = OpTypeVector %15 4
+ %17 = OpTypePointer Input %16
+ %18 = OpVariable %17 Input
+ %19 = OpTypeInt 32 0
+ %20 = OpConstant %19 0
+ %21 = OpTypePointer Input %15
+ %24 = OpConstant %15 -1
+ %26 = OpTypeVector %15 2
+ %27 = OpTypeStruct %26
+ %28 = OpTypePointer Uniform %27
+ %29 = OpVariable %28 Uniform
+ %30 = OpConstant %6 0
+ %31 = OpTypePointer Uniform %15
+ %34 = OpConstant %15 0
+ %44 = OpConstant %6 1
+ %78 = OpConstant %19 1
+ %82 = OpConstant %6 10
+ %83 = OpConstant %6 100
+ %93 = OpConstant %6 2
+ %95 = OpConstant %6 3
+ %109 = OpTypePointer Output %16
+ %110 = OpVariable %109 Output
+ %133 = OpConstant %15 1
+ %155 = OpConstant %6 4
+ %159 = OpConstantComposite %16 %133 %34 %34 %133
+ %161 = OpConstantComposite %16 %34 %34 %34 %34
+ %166 = OpConstantFalse %12
+ %168 = OpConstantTrue %12
+ %319 = OpUndef %6
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpBranch %163
+ %163 = OpLabel
+ %67 = OpAccessChain %31 %29 %30 %20
+ %68 = OpLoad %15 %67
+ %69 = OpFOrdLessThan %12 %68 %24
+ OpLoopMerge %162 %165 None
+ OpBranch %72
+ %72 = OpLabel
+ %337 = OpPhi %12 %166 %163 %335 %75
+ %324 = OpPhi %6 %30 %163 %383 %75
+ %317 = OpPhi %6 %319 %163 %441 %75
+ %305 = OpPhi %6 %30 %163 %123 %75
+ %79 = OpAccessChain %21 %18 %78
+ %80 = OpLoad %15 %79
+ %81 = OpFOrdGreaterThan %12 %80 %24
+ %84 = OpSelect %6 %81 %82 %83
+ %85 = OpSLessThan %12 %305 %84
+ OpLoopMerge %74 %75 None
+ OpBranchConditional %85 %73 %74
+ %73 = OpLabel
+ OpBranch %87
+ %87 = OpLabel
+ %323 = OpPhi %6 %324 %73 %99 %90
+ %316 = OpPhi %6 %317 %73 %312 %90
+ %306 = OpPhi %6 %30 %73 %116 %90
+ %94 = OpSLessThan %12 %306 %93
+ OpLoopMerge %89 %90 None
+ OpBranchConditional %94 %88 %89
+ %88 = OpLabel
+ OpBranch %187
+ %187 = OpLabel
+ OpLoopMerge %188 %189 None
+ OpBranch %190
+ %190 = OpLabel
+ %191 = OpAccessChain %21 %18 %20
+ %192 = OpLoad %15 %191
+ %193 = OpFOrdLessThan %12 %192 %24
+ %196 = OpFOrdLessThan %12 %68 %34
+ %197 = OpLogicalNot %12 %196
+ OpSelectionMerge %198 None
+ OpBranchConditional %197 %199 %198
+ %199 = OpLabel
+ OpSelectionMerge %201 None
+ OpBranchConditional %193 %202 %201
+ %202 = OpLabel
+ OpBranch %188
+ %201 = OpLabel
+ OpBranch %203
+ %203 = OpLabel
+ %307 = OpPhi %6 %44 %201 %219 %205
+ %209 = OpSLessThan %12 %307 %95
+ OpLoopMerge %204 %205 None
+ OpBranchConditional %209 %210 %204
+ %210 = OpLabel
+ OpSelectionMerge %212 None
+ OpBranchConditional %193 %213 %212
+ %213 = OpLabel
+ OpBranch %205
+ %212 = OpLabel
+ %215 = OpSGreaterThan %12 %307 %30
+ OpSelectionMerge %216 None
+ OpBranchConditional %215 %217 %216
+ %217 = OpLabel
+ OpBranch %204
+ %216 = OpLabel
+ OpBranch %205
+ %205 = OpLabel
+ %219 = OpIAdd %6 %307 %44
+ OpBranch %203
+ %204 = OpLabel
+ %313 = OpPhi %6 %316 %203 %44 %217
+ %308 = OpPhi %12 %166 %203 %168 %217
+ OpSelectionMerge %221 None
+ OpBranchConditional %308 %188 %221
+ %221 = OpLabel
+ OpBranch %198
+ %198 = OpLabel
+ OpBranch %188
+ %189 = OpLabel
+ OpBranch %187
+ %188 = OpLabel
+ %312 = OpPhi %6 %30 %202 %313 %204 %30 %198
+ %99 = OpIAdd %6 %323 %312
+ OpSelectionMerge %102 None
+ OpBranchConditional %69 %101 %102
+ %101 = OpLabel
+ OpBranch %103
+ %103 = OpLabel
+ OpLoopMerge %105 %104 None
+ OpBranchConditional %69 %104 %105
+ %104 = OpLabel
+ %112 = OpConvertSToF %15 %305
+ %113 = OpCompositeConstruct %16 %112 %112 %112 %112
+ OpStore %110 %113
+ OpBranch %103
+ %105 = OpLabel
+ OpBranch %89
+ %102 = OpLabel
+ OpBranch %90
+ %90 = OpLabel
+ %116 = OpIAdd %6 %306 %44
+ OpBranch %87
+ %89 = OpLabel
+ %441 = OpPhi %6 %316 %87 %312 %105
+ %383 = OpPhi %6 %323 %87 %99 %105
+ %335 = OpPhi %12 %337 %87 %168 %105
+ OpSelectionMerge %169 None
+ OpBranchConditional %335 %74 %169
+ %169 = OpLabel
+ %118 = OpLogicalNot %12 %69
+ OpSelectionMerge %120 None
+ OpBranchConditional %118 %119 %120
+ %119 = OpLabel
+ OpBranch %74
+ %120 = OpLabel
+ OpBranch %75
+ %75 = OpLabel
+ %123 = OpIAdd %6 %305 %44
+ OpBranch %72
+ %74 = OpLabel
+ %382 = OpPhi %6 %324 %72 %383 %89 %383 %119
+ %354 = OpPhi %12 %337 %72 %335 %89 %335 %119
+ OpSelectionMerge %171 None
+ OpBranchConditional %354 %162 %171
+ %171 = OpLabel
+ OpBranch %125
+ %125 = OpLabel
+ %381 = OpPhi %6 %382 %171 %140 %128
+ %365 = OpPhi %6 %319 %171 %361 %128
+ %355 = OpPhi %6 %30 %171 %153 %128
+ %131 = OpAccessChain %31 %29 %30 %78
+ %132 = OpLoad %15 %131
+ %134 = OpFAdd %15 %132 %133
+ %135 = OpConvertFToS %6 %134
+ %136 = OpSLessThan %12 %355 %135
+ OpLoopMerge %127 %128 None
+ OpBranchConditional %136 %126 %127
+ %126 = OpLabel
+ OpBranch %228
+ %228 = OpLabel
+ OpLoopMerge %229 %230 None
+ OpBranch %231
+ %231 = OpLabel
+ %232 = OpAccessChain %21 %18 %20
+ %233 = OpLoad %15 %232
+ %234 = OpFOrdLessThan %12 %233 %24
+ %237 = OpFOrdLessThan %12 %68 %34
+ %238 = OpLogicalNot %12 %237
+ OpSelectionMerge %239 None
+ OpBranchConditional %238 %240 %239
+ %240 = OpLabel
+ OpSelectionMerge %242 None
+ OpBranchConditional %234 %243 %242
+ %243 = OpLabel
+ OpBranch %229
+ %242 = OpLabel
+ OpBranch %244
+ %244 = OpLabel
+ %356 = OpPhi %6 %44 %242 %260 %246
+ %250 = OpSLessThan %12 %356 %95
+ OpLoopMerge %245 %246 None
+ OpBranchConditional %250 %251 %245
+ %251 = OpLabel
+ OpSelectionMerge %253 None
+ OpBranchConditional %234 %254 %253
+ %254 = OpLabel
+ OpBranch %246
+ %253 = OpLabel
+ %256 = OpSGreaterThan %12 %356 %30
+ OpSelectionMerge %257 None
+ OpBranchConditional %256 %258 %257
+ %258 = OpLabel
+ OpBranch %245
+ %257 = OpLabel
+ OpBranch %246
+ %246 = OpLabel
+ %260 = OpIAdd %6 %356 %44
+ OpBranch %244
+ %245 = OpLabel
+ %362 = OpPhi %6 %365 %244 %44 %258
+ %357 = OpPhi %12 %166 %244 %168 %258
+ OpSelectionMerge %262 None
+ OpBranchConditional %357 %229 %262
+ %262 = OpLabel
+ OpBranch %239
+ %239 = OpLabel
+ OpBranch %229
+ %230 = OpLabel
+ OpBranch %228
+ %229 = OpLabel
+ %361 = OpPhi %6 %30 %243 %362 %245 %30 %239
+ %140 = OpIAdd %6 %381 %361
+ %142 = OpLogicalNot %12 %69
+ %453 = OpSelect %12 %142 %166 %69
+ OpSelectionMerge %150 None
+ OpBranchConditional %453 %149 %150
+ %149 = OpLabel
+ OpBranch %127
+ %150 = OpLabel
+ OpBranch %128
+ %128 = OpLabel
+ %153 = OpIAdd %6 %355 %44
+ OpBranch %125
+ %127 = OpLabel
+ %431 = OpPhi %6 %381 %125 %140 %149
+ %156 = OpIEqual %12 %431 %155
+ OpSelectionMerge %158 None
+ OpBranchConditional %156 %157 %160
+ %160 = OpLabel
+ OpStore %110 %161
+ OpBranch %158
+ %157 = OpLabel
+ OpStore %110 %159
+ OpBranch %158
+ %158 = OpLabel
+ OpBranch %162
+ %165 = OpLabel
+ OpBranch %163
+ %162 = OpLabel
+ OpReturn
+ OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+ ATTACH variant_vertex_shader
+ ATTACH variant_fragment_shader
+ FRAMEBUFFER_SIZE 256 256
+ BIND BUFFER variant_framebuffer AS color LOCATION 0
+ BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
{ "always-discarding-function.amber", "always-discarding-function", "A fragment shader with an always discarding main function" },
{ "always-false-if-in-do-while.amber", "always-false-if-in-do-while", "A fragment shader with an always false if." },
{ "always-false-if-with-discard-return.amber", "always-false-if-with-discard-return", "A fragment shader with discard keyword and a return" },
+{ "array-idx-multiplied-by-for-loop-idx.amber", "array-idx-multiplied-by-for-loop-idx", "A fragment shader with array index multiplied" },
+{ "assign-array-value-to-another-array.amber", "assign-array-value-to-another-array", "A fragment shader that assigns array values to other array" },
+{ "assign-array-value-to-another-array-2.amber", "assign-array-value-to-another-array-2", "A fragment shader that assigns array values to other array" },
{ "barrier-in-loop-with-break.amber", "barrier-in-loop-with-break", "A compute shader with a barrier in a loop with a break" },
{ "break-in-do-while-with-nested-if.amber", "break-in-do-while-with-nested-if", "A fragment shader with nested if" },
{ "call-function-with-discard.amber", "call-function-with-discard", "Calls a function containing a discard" },
{ "continue-and-merge.amber", "continue-and-merge", "A fragment shader with two nested loops" },
{ "control-flow-in-function.amber", "control-flow-in-function", "A fragment shader with a lot of control flow" },
{ "control-flow-switch.amber", "control-flow-switch", "A fragment shader with somewhat complex control flow and a switch" },
+{ "cosh-return-inf-unused.amber", "cosh-return-inf-unused", "Cosh returns inf for one component which is never used" },
{ "cov-analysis-reachable-from-many.amber", "cov-analysis-reachable-from-many", "A fragment shader that covers a specific LLVM analysis code path." },
{ "cov-apfloat-acos-ldexp.amber", "cov-apfloat-acos-ldexp", "A fragment shader that covers a specific AP float code path." },
{ "cov-apfloat-determinant.amber", "cov-apfloat-determinant", "A fragment shader that covers a specific arbitrary precision float usage." },
{ "cov-vector-log2-cosh.amber", "cov-vector-log2-cosh", "A fragment shader that covers a specific vector log2 and cosh code path." },
{ "cov-wrap-op-kill-for-loop.amber", "cov-wrap-op-kill-for-loop", "A fragment shader that covers a specific OpKill wrapping code path" },
{ "cov-wrap-op-kill-two-branches.amber", "cov-wrap-op-kill-two-branches", "A fragment shader that covers a specific OpKill wrapping path." },
+{ "create-color-in-do-while-for-loop.amber", "create-color-in-do-while-for-loop", "A fragment shader that creates the color inside two loops" },
{ "dead-barriers-in-loops.amber", "dead-barriers-in-loops", "A compute shader with dead barriers" },
{ "dead-struct-init.amber", "dead-struct-init", "A fragment shader that uses struct initializers" },
{ "disc-and-add-in-func-in-loop.amber", "disc-and-add-in-func-in-loop", "A fragment shader with discard and add in function in loop" },
{ "discards-in-control-flow.amber", "discards-in-control-flow", "A fragment shader with discards in loops and conditionals" },
{ "do-while-loop-in-conditionals.amber", "do-while-loop-in-conditionals", "A fragment shader with do-while loop in conditional nest" },
{ "do-while-with-always-true-if.amber", "do-while-with-always-true-if", "A fragment shader with a do while that always returns" },
+{ "do-while-with-if-condition.amber", "do-while-with-if-condition", "A fragment shader that has nested if condition in do while" },
{ "early-return-and-barrier.amber", "early-return-and-barrier", "A compute shader with an early return and a barrier" },
+{ "find-msb-from-lsb.amber", "find-msb-from-lsb", "A fragment shader that finds MSB from LSB" },
{ "for-condition-always-false.amber", "for-condition-always-false", "A fragment shader that uses a for loop with condition always false" },
{ "for-loop-with-return.amber", "for-loop-with-return", "A fragment shader with a for loop that loops only once" },
{ "for-with-ifs-and-return.amber", "for-with-ifs-and-return", "A fragment shader with two ifs and return/continue inside a for loop" },
{ "fragcoord-control-flow.amber", "fragcoord-control-flow", "A fragment shader that uses FragCoord and somewhat complex control flow" },
{ "fragcoord-control-flow-2.amber", "fragcoord-control-flow-2", "A fragment shader that uses FragCoord and somewhat complex control flow" },
+{ "function-with-float-comparison.amber", "function-with-float-comparison", "A fragment shader that compares a float and a coordinate" },
{ "function-with-uniform-return.amber", "function-with-uniform-return", "A fragment shader with uniform value as a return" },
{ "global-array-loops.amber", "global-array-loops", "A loop that writes then reads a global array" },
{ "if-and-switch.amber", "if-and-switch", "A fragment shader with a switch and some data flow" },
+{ "increment-value-in-nested-for-loop.amber", "increment-value-in-nested-for-loop", "A frag. shader that increments a value in nested for loop" },
{ "injection-switch-as-comparison.amber", "injection-switch-as-comparison", "A fragment shader with uniform comparison in loop" },
{ "int-mat2-struct.amber", "int-mat2-struct", "Fragment shader using (int, mat2) struct" },
{ "loop-call-discard.amber", "loop-call-discard", "A fragment shader with nested loops and a function call" },
{ "modf-gl-color.amber", "modf-gl-color", "A fragment shader with modf of gl color" },
{ "modf-temp-modf-color.amber", "modf-temp-modf-color", "A fragment shader that calls modf twice, once with color" },
{ "nested-for-break-mat-color.amber", "nested-for-break-mat-color", "Two nested for loops modify a mat4 then writes red" },
+{ "nested-for-loops-switch-fallthrough.amber", "nested-for-loops-switch-fallthrough", "A fragment shader with few nested loops with fallthrough" },
{ "nested-for-loops-with-return.amber", "nested-for-loops-with-return", "A fragment shader with two nested for loops with return" },
{ "nested-ifs-and-return-in-for-loop.amber", "nested-ifs-and-return-in-for-loop", "A fragment shader with return in nest of ifs, inside loop" },
{ "nested-loops-switch.amber", "nested-loops-switch", "A fragment shader with nested loops and a switch" },
{ "return-float-from-while-loop.amber", "return-float-from-while-loop", "A fragment shader with unreachable while loop" },
{ "return-in-loop-in-function.amber", "return-in-loop-in-function", "A fragment shader with early return from loop in function" },
{ "return-inside-loop-in-function.amber", "return-inside-loop-in-function", "A fragment shader with return inside loop" },
+{ "return-mat2x3-value-from-func.amber", "return-mat2x3-value-from-func", "A fragment shader that has a function with mat2x3" },
{ "returned-boolean-in-vector.amber", "returned-boolean-in-vector", "A fragment shader with returned boolean in vector" },
+{ "set-color-in-one-iteration-while-loop.amber", "set-color-in-one-iteration-while-loop", "A frag shader that sets the color in one iter while loop" },
{ "similar-nested-ifs.amber", "similar-nested-ifs", "A fragment shader with similar nested ifs and loops" },
{ "smoothstep-after-loop.amber", "smoothstep-after-loop", "Fragment shader with 1-iteration loop and smoothstep" },
{ "struct-and-unreachable-infinite-loop.amber", "struct-and-unreachable-infinite-loop", "Fragment shader with struct and unreachable infinite loop" },
+{ "struct-array-data-as-loop-iterator.amber", "struct-array-data-as-loop-iterator", "A fragment shader that uses struct array data for loop iterator value" },
{ "struct-controlled-loop.amber", "struct-controlled-loop", "Shader with loop controlled by struct" },
{ "struct-used-as-temporary.amber", "struct-used-as-temporary", "A fragment shader that uses a temporary struct variable" },
{ "switch-case-with-undefined-expression.amber", "switch-case-with-undefined-expression","A fragment shader with undefined expression" },
{ "switch-inside-while-always-return.amber", "switch-inside-while-always-return", "A fragment shader with a switch inside while always return" },
{ "switch-loop-switch-if.amber", "switch-loop-switch-if", "A nested switch-loop-switch" },
{ "switch-with-empty-if-false.amber", "switch-with-empty-if-false", "A fragment shader with always false if in switch statement" },
+{ "switch-with-fall-through-cases.amber", "switch-with-fall-through-cases", "A fragment shader with switch cases that fall through" },
{ "swizzle-struct-init-min.amber", "swizzle-struct-init-min", "A fragment shader that uses vector swizzles, struct initializers, and min" },
{ "transpose-rectangular-matrix.amber", "transpose-rectangular-matrix", "Fragment shader that uses 'transpose'" },
{ "two-2-iteration-loops.amber", "two-2-iteration-loops", "Fragment shader with pair of outer loops" },
{ "unreachable-return-in-loop.amber", "unreachable-return-in-loop", "A fragment shader with an unreachable return in a loop" },
{ "unreachable-switch-case-with-discards.amber", "unreachable-switch-case-with-discards","A shader with a switch statement containing unreachable discards" },
{ "uv-value-comparison-as-boolean.amber", "uv-value-comparison-as-boolean", "A fragment shader with uv value comparison as boolean" },
+{ "vector-values-multiplied-by-fragcoord.amber", "vector-values-multiplied-by-fragcoord", "A shader that multiplies a vector by fragcoord" },
{ "vectors-and-discard-in-function.amber", "vectors-and-discard-in-function", "A fragment shader that assigns vector values" },
{ "while-function-always-false.amber", "while-function-always-false", "A fragment shader with an always false while function" },
{ "while-inside-switch.amber", "while-inside-switch", "A fragment shader that uses a while loop inside a switch" },
--- /dev/null
+#!amber
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with few nested loops with fallthrough
+
+# A fragment shader with several nested loops depending on each other and switch case with fallthrough.
+# The test passes because shader always writes red.
+
+# Optimized using spirv-opt with the following arguments:
+# '-O'
+# spirv-opt commit hash: ab7ac60f14ae66006bed5c989a2cfd4c4881704c
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+# precision highp int;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+# float zero;
+# };
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+# float sums[9];
+# int sum_index = 0;
+#
+# _GLF_color = vec4(0, 0, 0, 1);
+#
+# sums[0] = 0.0;
+#
+# // sum_index is modified in loops A and B like this:
+# // A: 0 -> 1, 1 -> 2
+# // B: 2 -> 3
+# // A: 3 -> 4, 4 -> 5
+# // B: 5 -> 6. At this point we set red channel to 1.
+# // A: 6: return from main.
+# for(int i0 = 2; i0 < 5; i0++)
+# {
+# // Loop A: After this loop sum_index = sum_index + 2.
+# for(int i1 = 2; i1 < 4; i1++)
+# {
+# for(int i2 = 0; i2 < i0; i2++)
+# {
+# for(int i3 = 0; i3 < i1; i3++)
+# {
+# switch(sum_index)
+# {
+# case 0:
+# sums[sum_index]++;
+# break;
+# case 1:
+# sums[sum_index]++;
+# break;
+# case 2:
+# sums[sum_index]++;
+# case 3:
+# sums[sum_index]++;
+# case 4:
+# sums[sum_index]++;
+# case 5:
+# sums[sum_index]++;
+# break;
+# case 6:
+# // This is hit eventually.
+# return;
+# case 7:
+# sums[sum_index]++;
+# break;
+# case 8:
+# sums[sum_index]++;
+# }
+# }
+# }
+#
+# if(clamp(1.0, gl_FragCoord.y, gl_FragCoord.y) < 0.0) // Always false.
+# continue;
+#
+# if(zero < 0.0) // Always false.
+# sums[sum_index]++;
+#
+# if(gl_FragCoord.y < 0.0) // Always false.
+# discard;
+#
+# sum_index++;
+# }
+#
+# // Loop B: After this loop sum_index = sum_index + 1.
+# //
+# // Cases that are not supposed to be hit set the green channel
+# // to one to mark an error.
+# for(int i4 = 4; i4 < 5; i4++)
+# {
+# for(int i5 = 0; i5 < i0; i5++)
+# {
+# for(int i6 = 0; i6 < i4; i6++)
+# {
+# switch(sum_index)
+# {
+# case 0:
+# sums[sum_index]++;
+# _GLF_color.g = 1.0;
+# case 1:
+# sums[sum_index]++;
+# _GLF_color.g = 1.0;
+# case 2:
+# sums[sum_index]++;
+# break;
+# case 3:
+# sums[sum_index]++;
+# _GLF_color.g = 1.0;
+# case 4:
+# sums[sum_index]++;
+# _GLF_color.g = 1.0;
+# break;
+# case 5:
+# sums[sum_index]++;
+# if (sums[0] != 0.0) // Always true.
+# _GLF_color.r = 1.0;
+# break;
+# case 6:
+# sums[sum_index]++;
+# _GLF_color.g = 1.0;
+# case 7:
+# sums[sum_index]++;
+# _GLF_color.g = 1.0;
+# case 8:
+# sums[sum_index]++;
+# _GLF_color.g = 1.0;
+# }
+# }
+# }
+#
+# sum_index++;
+#
+# if (zero < 1.0) // Always true, but we run the loop only once anyway.
+# break;
+# }
+# }
+#
+# // We never reach here. Both branches write incorrect color.
+# if (sums[0] == 0.0)
+# _GLF_color = vec4(0);
+# else
+# _GLF_color = vec4(1);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 358
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %13 %117
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %13 "_GLF_color"
+ OpName %21 "sums"
+ OpName %117 "gl_FragCoord"
+ OpName %129 "buf0"
+ OpMemberName %129 0 "zero"
+ OpName %131 ""
+ OpDecorate %13 Location 0
+ OpDecorate %117 BuiltIn FragCoord
+ OpMemberDecorate %129 0 Offset 0
+ OpDecorate %129 Block
+ OpDecorate %131 DescriptorSet 0
+ OpDecorate %131 Binding 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %9 = OpConstant %6 0
+ %10 = OpTypeFloat 32
+ %11 = OpTypeVector %10 4
+ %12 = OpTypePointer Output %11
+ %13 = OpVariable %12 Output
+ %14 = OpConstant %10 0
+ %15 = OpConstant %10 1
+ %16 = OpConstantComposite %11 %14 %14 %14 %15
+ %17 = OpTypeInt 32 0
+ %18 = OpConstant %17 9
+ %19 = OpTypeArray %10 %18
+ %20 = OpTypePointer Function %19
+ %22 = OpTypePointer Function %10
+ %25 = OpConstant %6 2
+ %32 = OpConstant %6 5
+ %33 = OpTypeBool
+ %42 = OpConstant %6 4
+ %112 = OpConstant %6 1
+ %116 = OpTypePointer Input %11
+ %117 = OpVariable %116 Input
+ %118 = OpConstant %17 1
+ %119 = OpTypePointer Input %10
+ %129 = OpTypeStruct %10
+ %130 = OpTypePointer Uniform %129
+ %131 = OpVariable %130 Uniform
+ %132 = OpTypePointer Uniform %10
+ %193 = OpTypePointer Output %10
+ %225 = OpConstant %17 0
+ %265 = OpConstantComposite %11 %14 %14 %14 %14
+ %267 = OpConstantComposite %11 %15 %15 %15 %15
+ %272 = OpConstantFalse %33
+ %275 = OpConstantTrue %33
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %21 = OpVariable %20 Function
+ OpBranch %269
+ %269 = OpLabel
+ OpStore %13 %16
+ %23 = OpAccessChain %22 %21 %9
+ OpStore %23 %14
+ OpLoopMerge %268 %271 None
+ OpBranch %26
+ %26 = OpLabel
+ %300 = OpPhi %33 %272 %269 %312 %29
+ %295 = OpPhi %6 %9 %269 %356 %29
+ %284 = OpPhi %6 %25 %269 %259 %29
+ %34 = OpSLessThan %33 %284 %32
+ OpLoopMerge %28 %29 None
+ OpBranchConditional %34 %27 %28
+ %27 = OpLabel
+ OpBranch %36
+ %36 = OpLabel
+ %299 = OpPhi %33 %300 %27 %304 %39
+ %294 = OpPhi %6 %295 %27 %357 %39
+ %285 = OpPhi %6 %25 %27 %151 %39
+ %43 = OpSLessThan %33 %285 %42
+ OpLoopMerge %38 %39 None
+ OpBranchConditional %43 %37 %38
+ %37 = OpLabel
+ OpBranch %45
+ %45 = OpLabel
+ %298 = OpPhi %33 %299 %37 %296 %48
+ %286 = OpPhi %6 %9 %37 %115 %48
+ %52 = OpSLessThan %33 %286 %284
+ OpLoopMerge %47 %48 None
+ OpBranchConditional %52 %46 %47
+ %46 = OpLabel
+ OpBranch %54
+ %54 = OpLabel
+ %289 = OpPhi %6 %9 %46 %113 %57
+ %61 = OpSLessThan %33 %289 %285
+ OpLoopMerge %56 %57 None
+ OpBranchConditional %61 %55 %56
+ %55 = OpLabel
+ OpSelectionMerge %72 None
+ OpSwitch %294 %72 0 %63 1 %64 2 %65 3 %66 4 %67 5 %68 6 %69 7 %70 8 %71
+ %63 = OpLabel
+ %74 = OpAccessChain %22 %21 %294
+ %75 = OpLoad %10 %74
+ %76 = OpFAdd %10 %75 %15
+ OpStore %74 %76
+ OpBranch %72
+ %64 = OpLabel
+ %79 = OpAccessChain %22 %21 %294
+ %80 = OpLoad %10 %79
+ %81 = OpFAdd %10 %80 %15
+ OpStore %79 %81
+ OpBranch %72
+ %65 = OpLabel
+ %84 = OpAccessChain %22 %21 %294
+ %85 = OpLoad %10 %84
+ %86 = OpFAdd %10 %85 %15
+ OpStore %84 %86
+ OpBranch %66
+ %66 = OpLabel
+ %88 = OpAccessChain %22 %21 %294
+ %89 = OpLoad %10 %88
+ %90 = OpFAdd %10 %89 %15
+ OpStore %88 %90
+ OpBranch %67
+ %67 = OpLabel
+ %92 = OpAccessChain %22 %21 %294
+ %93 = OpLoad %10 %92
+ %94 = OpFAdd %10 %93 %15
+ OpStore %92 %94
+ OpBranch %68
+ %68 = OpLabel
+ %96 = OpAccessChain %22 %21 %294
+ %97 = OpLoad %10 %96
+ %98 = OpFAdd %10 %97 %15
+ OpStore %96 %98
+ OpBranch %72
+ %69 = OpLabel
+ OpBranch %56
+ %70 = OpLabel
+ %102 = OpAccessChain %22 %21 %294
+ %103 = OpLoad %10 %102
+ %104 = OpFAdd %10 %103 %15
+ OpStore %102 %104
+ OpBranch %72
+ %71 = OpLabel
+ %107 = OpAccessChain %22 %21 %294
+ %108 = OpLoad %10 %107
+ %109 = OpFAdd %10 %108 %15
+ OpStore %107 %109
+ OpBranch %72
+ %72 = OpLabel
+ OpBranch %57
+ %57 = OpLabel
+ %113 = OpIAdd %6 %289 %112
+ OpBranch %54
+ %56 = OpLabel
+ %296 = OpPhi %33 %298 %54 %275 %69
+ OpSelectionMerge %276 None
+ OpBranchConditional %296 %47 %276
+ %276 = OpLabel
+ OpBranch %48
+ %48 = OpLabel
+ %115 = OpIAdd %6 %286 %112
+ OpBranch %45
+ %47 = OpLabel
+ %304 = OpPhi %33 %298 %45 %296 %56
+ OpSelectionMerge %278 None
+ OpBranchConditional %304 %38 %278
+ %278 = OpLabel
+ %120 = OpAccessChain %119 %117 %118
+ %121 = OpLoad %10 %120
+ %124 = OpExtInst %10 %1 FClamp %15 %121 %121
+ %125 = OpFOrdLessThan %33 %124 %14
+ OpSelectionMerge %127 None
+ OpBranchConditional %125 %126 %127
+ %126 = OpLabel
+ OpBranch %39
+ %127 = OpLabel
+ %133 = OpAccessChain %132 %131 %9
+ %134 = OpLoad %10 %133
+ %135 = OpFOrdLessThan %33 %134 %14
+ OpSelectionMerge %137 None
+ OpBranchConditional %135 %136 %137
+ %136 = OpLabel
+ %139 = OpAccessChain %22 %21 %294
+ %140 = OpLoad %10 %139
+ %141 = OpFAdd %10 %140 %15
+ OpStore %139 %141
+ OpBranch %137
+ %137 = OpLabel
+ %144 = OpFOrdLessThan %33 %121 %14
+ OpSelectionMerge %146 None
+ OpBranchConditional %144 %145 %146
+ %145 = OpLabel
+ OpKill
+ %146 = OpLabel
+ %149 = OpIAdd %6 %294 %112
+ OpBranch %39
+ %39 = OpLabel
+ %357 = OpPhi %6 %294 %126 %149 %146
+ %151 = OpIAdd %6 %285 %112
+ OpBranch %36
+ %38 = OpLabel
+ %312 = OpPhi %33 %299 %36 %304 %47
+ OpSelectionMerge %280 None
+ OpBranchConditional %312 %28 %280
+ %280 = OpLabel
+ OpBranch %153
+ %153 = OpLabel
+ %322 = OpPhi %6 %294 %280 %249 %156
+ %313 = OpPhi %6 %42 %280 %257 %156
+ %159 = OpSLessThan %33 %313 %32
+ OpLoopMerge %155 %156 None
+ OpBranchConditional %159 %154 %155
+ %154 = OpLabel
+ OpBranch %161
+ %161 = OpLabel
+ %314 = OpPhi %6 %9 %154 %247 %164
+ %168 = OpSLessThan %33 %314 %284
+ OpLoopMerge %163 %164 None
+ OpBranchConditional %168 %162 %163
+ %162 = OpLabel
+ OpBranch %170
+ %170 = OpLabel
+ %326 = OpPhi %6 %9 %162 %245 %173
+ %177 = OpSLessThan %33 %326 %313
+ OpLoopMerge %172 %173 None
+ OpBranchConditional %177 %171 %172
+ %171 = OpLabel
+ OpSelectionMerge %188 None
+ OpSwitch %322 %188 0 %179 1 %180 2 %181 3 %182 4 %183 5 %184 6 %185 7 %186 8 %187
+ %179 = OpLabel
+ %190 = OpAccessChain %22 %21 %322
+ %191 = OpLoad %10 %190
+ %192 = OpFAdd %10 %191 %15
+ OpStore %190 %192
+ %194 = OpAccessChain %193 %13 %118
+ OpStore %194 %15
+ OpBranch %180
+ %180 = OpLabel
+ %196 = OpAccessChain %22 %21 %322
+ %197 = OpLoad %10 %196
+ %198 = OpFAdd %10 %197 %15
+ OpStore %196 %198
+ %199 = OpAccessChain %193 %13 %118
+ OpStore %199 %15
+ OpBranch %181
+ %181 = OpLabel
+ %201 = OpAccessChain %22 %21 %322
+ %202 = OpLoad %10 %201
+ %203 = OpFAdd %10 %202 %15
+ OpStore %201 %203
+ OpBranch %188
+ %182 = OpLabel
+ %206 = OpAccessChain %22 %21 %322
+ %207 = OpLoad %10 %206
+ %208 = OpFAdd %10 %207 %15
+ OpStore %206 %208
+ %209 = OpAccessChain %193 %13 %118
+ OpStore %209 %15
+ OpBranch %183
+ %183 = OpLabel
+ %211 = OpAccessChain %22 %21 %322
+ %212 = OpLoad %10 %211
+ %213 = OpFAdd %10 %212 %15
+ OpStore %211 %213
+ %214 = OpAccessChain %193 %13 %118
+ OpStore %214 %15
+ OpBranch %188
+ %184 = OpLabel
+ %217 = OpAccessChain %22 %21 %322
+ %218 = OpLoad %10 %217
+ %219 = OpFAdd %10 %218 %15
+ OpStore %217 %219
+ %221 = OpLoad %10 %23
+ %222 = OpFOrdNotEqual %33 %221 %14
+ OpSelectionMerge %224 None
+ OpBranchConditional %222 %223 %224
+ %223 = OpLabel
+ %226 = OpAccessChain %193 %13 %225
+ OpStore %226 %15
+ OpBranch %224
+ %224 = OpLabel
+ OpBranch %188
+ %185 = OpLabel
+ %229 = OpAccessChain %22 %21 %322
+ %230 = OpLoad %10 %229
+ %231 = OpFAdd %10 %230 %15
+ OpStore %229 %231
+ %232 = OpAccessChain %193 %13 %118
+ OpStore %232 %15
+ OpBranch %186
+ %186 = OpLabel
+ %234 = OpAccessChain %22 %21 %322
+ %235 = OpLoad %10 %234
+ %236 = OpFAdd %10 %235 %15
+ OpStore %234 %236
+ %237 = OpAccessChain %193 %13 %118
+ OpStore %237 %15
+ OpBranch %187
+ %187 = OpLabel
+ %239 = OpAccessChain %22 %21 %322
+ %240 = OpLoad %10 %239
+ %241 = OpFAdd %10 %240 %15
+ OpStore %239 %241
+ %242 = OpAccessChain %193 %13 %118
+ OpStore %242 %15
+ OpBranch %188
+ %188 = OpLabel
+ OpBranch %173
+ %173 = OpLabel
+ %245 = OpIAdd %6 %326 %112
+ OpBranch %170
+ %172 = OpLabel
+ OpBranch %164
+ %164 = OpLabel
+ %247 = OpIAdd %6 %314 %112
+ OpBranch %161
+ %163 = OpLabel
+ %249 = OpIAdd %6 %322 %112
+ %250 = OpAccessChain %132 %131 %9
+ %251 = OpLoad %10 %250
+ %252 = OpFOrdLessThan %33 %251 %15
+ OpSelectionMerge %254 None
+ OpBranchConditional %252 %253 %254
+ %253 = OpLabel
+ OpBranch %155
+ %254 = OpLabel
+ OpBranch %156
+ %156 = OpLabel
+ %257 = OpIAdd %6 %313 %112
+ OpBranch %153
+ %155 = OpLabel
+ %356 = OpPhi %6 %322 %153 %249 %253
+ OpBranch %29
+ %29 = OpLabel
+ %259 = OpIAdd %6 %284 %112
+ OpBranch %26
+ %28 = OpLabel
+ %342 = OpPhi %33 %300 %26 %312 %38
+ OpSelectionMerge %282 None
+ OpBranchConditional %342 %268 %282
+ %282 = OpLabel
+ %261 = OpLoad %10 %23
+ %262 = OpFOrdEqual %33 %261 %14
+ OpSelectionMerge %264 None
+ OpBranchConditional %262 %263 %266
+ %263 = OpLabel
+ OpStore %13 %265
+ OpBranch %264
+ %266 = OpLabel
+ OpStore %13 %267
+ OpBranch %264
+ %264 = OpLabel
+ OpBranch %268
+ %271 = OpLabel
+ OpBranch %269
+ %268 = OpLabel
+ OpReturn
+ OpFunctionEnd
+END
+
+# uniforms for variant
+
+# zero
+BUFFER variant_zero DATA_TYPE float DATA
+ 0.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+ ATTACH variant_vertex_shader
+ ATTACH variant_fragment_shader
+ FRAMEBUFFER_SIZE 256 256
+ BIND BUFFER variant_framebuffer AS color LOCATION 0
+ BIND BUFFER variant_zero AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
--- /dev/null
+#!amber
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader that has a function with mat2x3
+
+# The test passes because shader always writes red.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# float a = 22.0;
+#
+# // Returns variable "a" clamped to 0..25.
+# int func()
+# {
+# float b;
+# // Despite b being uninitialized,
+# // the result of the clamp will be 1.
+# int c = clamp(int(b), 1, 1);
+#
+# // Always true.
+# if (gl_FragCoord.x > -1.0)
+# c = int(mat2x3(vec4(0), clamp(a, 0.0, 25.0), b)[c][c]);
+# else
+# c = 2;
+#
+# return c;
+# }
+#
+# void main()
+# {
+# // a becomes 23.0.
+# a = float(func() + 1);
+#
+# do
+# {
+# if (func() == 23)
+# _GLF_color = vec4(1, 0, 0, 1);
+# else
+# _GLF_color = vec4(0, 0, 0, 0);
+# }
+# while(a > 23.0); // Always false
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 82
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %24 %76
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %8 "func("
+ OpName %12 "a"
+ OpName %15 "c"
+ OpName %17 "b"
+ OpName %24 "gl_FragCoord"
+ OpName %54 "indexable"
+ OpName %76 "_GLF_color"
+ OpDecorate %24 BuiltIn FragCoord
+ OpDecorate %76 Location 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %7 = OpTypeFunction %6
+ %10 = OpTypeFloat 32
+ %11 = OpTypePointer Private %10
+ %12 = OpVariable %11 Private
+ %13 = OpConstant %10 22
+ %14 = OpTypePointer Function %6
+ %16 = OpTypePointer Function %10
+ %20 = OpConstant %6 1
+ %22 = OpTypeVector %10 4
+ %23 = OpTypePointer Input %22
+ %24 = OpVariable %23 Input
+ %25 = OpTypeInt 32 0
+ %26 = OpConstant %25 0
+ %27 = OpTypePointer Input %10
+ %30 = OpConstant %10 -1
+ %31 = OpTypeBool
+ %35 = OpConstant %10 0
+ %36 = OpConstantComposite %22 %35 %35 %35 %35
+ %38 = OpConstant %10 25
+ %41 = OpTypeVector %10 3
+ %42 = OpTypeMatrix %41 2
+ %43 = OpConstant %10 1
+ %53 = OpTypePointer Function %42
+ %59 = OpConstant %6 2
+ %71 = OpConstant %6 23
+ %75 = OpTypePointer Output %22
+ %76 = OpVariable %75 Output
+ %77 = OpConstantComposite %22 %43 %35 %35 %43
+ %80 = OpConstant %10 23
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpStore %12 %13
+ %63 = OpFunctionCall %6 %8
+ %64 = OpIAdd %6 %63 %20
+ %65 = OpConvertSToF %10 %64
+ OpStore %12 %65
+ OpBranch %66
+ %66 = OpLabel
+ OpLoopMerge %68 %69 None
+ OpBranch %67
+ %67 = OpLabel
+ %70 = OpFunctionCall %6 %8
+ %72 = OpIEqual %31 %70 %71
+ OpSelectionMerge %74 None
+ OpBranchConditional %72 %73 %78
+ %73 = OpLabel
+ OpStore %76 %77
+ OpBranch %74
+ %78 = OpLabel
+ OpStore %76 %36
+ OpBranch %74
+ %74 = OpLabel
+ OpBranch %69
+ %69 = OpLabel
+ %79 = OpLoad %10 %12
+ %81 = OpFOrdGreaterThan %31 %79 %80
+ OpBranchConditional %81 %66 %68
+ %68 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %8 = OpFunction %6 None %7
+ %9 = OpLabel
+ %15 = OpVariable %14 Function
+ %17 = OpVariable %16 Function
+ %54 = OpVariable %53 Function
+ %18 = OpLoad %10 %17
+ %19 = OpConvertFToS %6 %18
+ %21 = OpExtInst %6 %1 SClamp %19 %20 %20
+ OpStore %15 %21
+ %28 = OpAccessChain %27 %24 %26
+ %29 = OpLoad %10 %28
+ %32 = OpFOrdGreaterThan %31 %29 %30
+ OpSelectionMerge %34 None
+ OpBranchConditional %32 %33 %58
+ %33 = OpLabel
+ %37 = OpLoad %10 %12
+ %39 = OpExtInst %10 %1 FClamp %37 %35 %38
+ %40 = OpLoad %10 %17
+ %44 = OpCompositeExtract %10 %36 0
+ %45 = OpCompositeExtract %10 %36 1
+ %46 = OpCompositeExtract %10 %36 2
+ %47 = OpCompositeExtract %10 %36 3
+ %48 = OpCompositeConstruct %41 %44 %45 %46
+ %49 = OpCompositeConstruct %41 %47 %39 %40
+ %50 = OpCompositeConstruct %42 %48 %49
+ %51 = OpLoad %6 %15
+ %52 = OpLoad %6 %15
+ OpStore %54 %50
+ %55 = OpAccessChain %16 %54 %51 %52
+ %56 = OpLoad %10 %55
+ %57 = OpConvertFToS %6 %56
+ OpStore %15 %57
+ OpBranch %34
+ %58 = OpLabel
+ OpStore %15 %59
+ OpBranch %34
+ %34 = OpLabel
+ %60 = OpLoad %6 %15
+ OpReturnValue %60
+ OpFunctionEnd
+END
+
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+ ATTACH variant_vertex_shader
+ ATTACH variant_fragment_shader
+ FRAMEBUFFER_SIZE 256 256
+ BIND BUFFER variant_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
--- /dev/null
+#!amber
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A frag shader that sets the color in one iter while loop
+
+# The test passes because shader always writes red.
+
+# Optimized using spirv-opt with the following arguments:
+# '-O'
+# spirv-opt commit hash: ab7ac60f14ae66006bed5c989a2cfd4c4881704c
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0 {
+# vec2 injectionSwitch;
+# };
+#
+# void main()
+# {
+# // Variable "val" will always end up as 1.0 or 0.0.
+# int val = int(clamp(gl_FragCoord.x, 0.0, 1.0));
+# vec4 color = vec4(0);
+# _GLF_color = color;
+#
+# do
+# {
+# // Loop iterates at least once.
+# // Body of the loop is idempotent.
+# for (int i = 0; i < val + int(injectionSwitch.y); i++)
+# {
+# // Always false.
+# if (val < 0)
+# return;
+# else
+# {
+# if(val == 1)
+# // Set red and alpha to 1.0.
+# color.ra = vec2(val);
+# else
+# // Set red and alpha to 1.0.
+# color.ra = vec2(val + 1);
+# }
+# }
+# }
+# while(val < 0); // Always false.
+#
+# _GLF_color = color;
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 106
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %12 %26
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %12 "gl_FragCoord"
+ OpName %26 "_GLF_color"
+ OpName %42 "buf0"
+ OpMemberName %42 0 "injectionSwitch"
+ OpName %44 ""
+ OpDecorate %12 BuiltIn FragCoord
+ OpDecorate %26 Location 0
+ OpMemberDecorate %42 0 Offset 0
+ OpDecorate %42 Block
+ OpDecorate %44 DescriptorSet 0
+ OpDecorate %44 Binding 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %9 = OpTypeFloat 32
+ %10 = OpTypeVector %9 4
+ %11 = OpTypePointer Input %10
+ %12 = OpVariable %11 Input
+ %13 = OpTypeInt 32 0
+ %14 = OpConstant %13 0
+ %15 = OpTypePointer Input %9
+ %18 = OpConstant %9 0
+ %19 = OpConstant %9 1
+ %24 = OpConstantComposite %10 %18 %18 %18 %18
+ %25 = OpTypePointer Output %10
+ %26 = OpVariable %25 Output
+ %33 = OpConstant %6 0
+ %41 = OpTypeVector %9 2
+ %42 = OpTypeStruct %41
+ %43 = OpTypePointer Uniform %42
+ %44 = OpVariable %43 Uniform
+ %45 = OpConstant %13 1
+ %46 = OpTypePointer Uniform %9
+ %51 = OpTypeBool
+ %60 = OpConstant %6 1
+ %85 = OpConstantFalse %51
+ %88 = OpConstantTrue %51
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpBranch %82
+ %82 = OpLabel
+ %16 = OpAccessChain %15 %12 %14
+ %17 = OpLoad %9 %16
+ %20 = OpExtInst %9 %1 FClamp %17 %18 %19
+ %21 = OpConvertFToS %6 %20
+ OpStore %26 %24
+ OpLoopMerge %81 %84 None
+ OpBranch %28
+ %28 = OpLabel
+ %99 = OpPhi %51 %85 %82 %97 %31
+ %95 = OpPhi %10 %24 %82 %94 %31
+ OpLoopMerge %30 %31 None
+ OpBranch %34
+ %34 = OpLabel
+ %94 = OpPhi %10 %95 %28 %105 %37
+ %93 = OpPhi %6 %33 %28 %77 %37
+ %47 = OpAccessChain %46 %44 %33 %45
+ %48 = OpLoad %9 %47
+ %49 = OpConvertFToS %6 %48
+ %50 = OpIAdd %6 %21 %49
+ %52 = OpSLessThan %51 %93 %50
+ OpLoopMerge %36 %37 None
+ OpBranchConditional %52 %35 %36
+ %35 = OpLabel
+ %54 = OpSLessThan %51 %21 %33
+ OpSelectionMerge %56 None
+ OpBranchConditional %54 %55 %58
+ %55 = OpLabel
+ OpBranch %36
+ %58 = OpLabel
+ %61 = OpIEqual %51 %21 %60
+ OpSelectionMerge %63 None
+ OpBranchConditional %61 %62 %69
+ %62 = OpLabel
+ %65 = OpConvertSToF %9 %21
+ %66 = OpCompositeConstruct %41 %65 %65
+ %68 = OpVectorShuffle %10 %94 %66 4 1 2 5
+ OpBranch %63
+ %69 = OpLabel
+ %71 = OpIAdd %6 %21 %60
+ %72 = OpConvertSToF %9 %71
+ %73 = OpCompositeConstruct %41 %72 %72
+ %75 = OpVectorShuffle %10 %94 %73 4 1 2 5
+ OpBranch %63
+ %63 = OpLabel
+ %105 = OpPhi %10 %68 %62 %75 %69
+ OpBranch %56
+ %56 = OpLabel
+ OpBranch %37
+ %37 = OpLabel
+ %77 = OpIAdd %6 %93 %60
+ OpBranch %34
+ %36 = OpLabel
+ %97 = OpPhi %51 %99 %34 %88 %55
+ OpSelectionMerge %89 None
+ OpBranchConditional %97 %30 %89
+ %89 = OpLabel
+ OpBranch %31
+ %31 = OpLabel
+ %79 = OpSLessThan %51 %21 %33
+ OpBranchConditional %79 %28 %30
+ %30 = OpLabel
+ OpSelectionMerge %91 None
+ OpBranchConditional %97 %81 %91
+ %91 = OpLabel
+ OpStore %26 %94
+ OpBranch %81
+ %84 = OpLabel
+ OpBranch %82
+ %81 = OpLabel
+ OpReturn
+ OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+ ATTACH variant_vertex_shader
+ ATTACH variant_fragment_shader
+ FRAMEBUFFER_SIZE 256 256
+ BIND BUFFER variant_framebuffer AS color LOCATION 0
+ BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
--- /dev/null
+#!amber
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader that uses struct array data for loop iterator value
+
+# The test passes because shader always writes red.
+
+# Optimized using spirv-opt with the following arguments:
+# '-O'
+# spirv-opt commit hash: ab7ac60f14ae66006bed5c989a2cfd4c4881704c
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+# float zero;
+# };
+#
+# struct S
+# {
+# int a;
+# };
+#
+# // Always returns given parameter value.
+# int func(int x)
+# {
+# S arr[9];
+# arr[0].a = 1;
+#
+# for (int i = 0; i < 1 + int(zero); i++)
+# {
+# // Always true.
+# if (zero < 1.0)
+# return x;
+#
+# i = arr[i].a;
+# }
+#
+# return -1;
+# }
+#
+# void main()
+# {
+# for (int i = 0; i < 2; i++)
+# {
+# switch (func(i))
+# {
+# case -1:
+# return;
+# case 0:
+# if (func(5) == 5)
+# _GLF_color = vec4(1, 0, 0, 1);
+# else
+# _GLF_color = vec4(0);
+# return;
+# }
+# }
+# _GLF_color = vec4(0); // Should never be reached.
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 204
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %79
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %12 "S"
+ OpMemberName %12 0 "a"
+ OpName %29 "buf0"
+ OpMemberName %29 0 "zero"
+ OpName %31 ""
+ OpName %79 "_GLF_color"
+ OpMemberDecorate %29 0 Offset 0
+ OpDecorate %29 Block
+ OpDecorate %31 DescriptorSet 0
+ OpDecorate %31 Binding 0
+ OpDecorate %79 Location 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %7 = OpTypePointer Function %6
+ %12 = OpTypeStruct %6
+ %13 = OpTypeInt 32 0
+ %14 = OpConstant %13 9
+ %15 = OpTypeArray %12 %14
+ %16 = OpTypePointer Function %15
+ %18 = OpConstant %6 0
+ %19 = OpConstant %6 1
+ %28 = OpTypeFloat 32
+ %29 = OpTypeStruct %28
+ %30 = OpTypePointer Uniform %29
+ %31 = OpVariable %30 Uniform
+ %32 = OpTypePointer Uniform %28
+ %37 = OpTypeBool
+ %41 = OpConstant %28 1
+ %52 = OpConstant %6 -1
+ %62 = OpConstant %6 2
+ %71 = OpConstant %6 5
+ %77 = OpTypeVector %28 4
+ %78 = OpTypePointer Output %77
+ %79 = OpVariable %78 Output
+ %80 = OpConstant %28 0
+ %81 = OpConstantComposite %77 %41 %80 %80 %41
+ %83 = OpConstantComposite %77 %80 %80 %80 %80
+ %92 = OpConstantFalse %37
+ %95 = OpConstantTrue %37
+ %188 = OpUndef %6
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %144 = OpVariable %16 Function
+ %109 = OpVariable %16 Function
+ OpBranch %89
+ %89 = OpLabel
+ OpLoopMerge %88 %91 None
+ OpBranch %56
+ %56 = OpLabel
+ %186 = OpPhi %6 %188 %89 %182 %59
+ %177 = OpPhi %6 %18 %89 %87 %59
+ %63 = OpSLessThan %37 %177 %62
+ OpLoopMerge %58 %59 None
+ OpBranchConditional %63 %57 %58
+ %57 = OpLabel
+ OpBranch %112
+ %112 = OpLabel
+ %116 = OpAccessChain %7 %109 %18 %18
+ OpStore %116 %19
+ OpLoopMerge %113 %114 None
+ OpBranch %117
+ %117 = OpLabel
+ %178 = OpPhi %6 %18 %112 %138 %119
+ %122 = OpAccessChain %32 %31 %18
+ %123 = OpLoad %28 %122
+ %124 = OpConvertFToS %6 %123
+ %125 = OpIAdd %6 %19 %124
+ %126 = OpSLessThan %37 %178 %125
+ OpLoopMerge %118 %119 None
+ OpBranchConditional %126 %127 %118
+ %127 = OpLabel
+ %130 = OpFOrdLessThan %37 %123 %41
+ OpSelectionMerge %131 None
+ OpBranchConditional %130 %132 %131
+ %132 = OpLabel
+ OpBranch %118
+ %131 = OpLabel
+ %135 = OpAccessChain %7 %109 %178 %18
+ %136 = OpLoad %6 %135
+ OpBranch %119
+ %119 = OpLabel
+ %138 = OpIAdd %6 %136 %19
+ OpBranch %117
+ %118 = OpLabel
+ %183 = OpPhi %6 %186 %117 %177 %132
+ %179 = OpPhi %37 %92 %117 %95 %132
+ OpSelectionMerge %140 None
+ OpBranchConditional %179 %113 %140
+ %140 = OpLabel
+ OpBranch %113
+ %114 = OpLabel
+ OpBranch %112
+ %113 = OpLabel
+ %182 = OpPhi %6 %183 %118 %52 %140
+ OpSelectionMerge %69 None
+ OpSwitch %182 %69 -1 %67 0 %68
+ %68 = OpLabel
+ OpBranch %147
+ %147 = OpLabel
+ %151 = OpAccessChain %7 %144 %18 %18
+ OpStore %151 %19
+ OpLoopMerge %148 %149 None
+ OpBranch %152
+ %152 = OpLabel
+ %189 = OpPhi %6 %18 %147 %173 %154
+ %161 = OpSLessThan %37 %189 %125
+ OpLoopMerge %153 %154 None
+ OpBranchConditional %161 %162 %153
+ %162 = OpLabel
+ %165 = OpFOrdLessThan %37 %123 %41
+ OpSelectionMerge %166 None
+ OpBranchConditional %165 %167 %166
+ %167 = OpLabel
+ OpBranch %153
+ %166 = OpLabel
+ %170 = OpAccessChain %7 %144 %189 %18
+ %171 = OpLoad %6 %170
+ OpBranch %154
+ %154 = OpLabel
+ %173 = OpIAdd %6 %171 %19
+ OpBranch %152
+ %153 = OpLabel
+ %194 = OpPhi %6 %188 %152 %71 %167
+ %190 = OpPhi %37 %92 %152 %95 %167
+ OpSelectionMerge %175 None
+ OpBranchConditional %190 %148 %175
+ %175 = OpLabel
+ OpBranch %148
+ %149 = OpLabel
+ OpBranch %147
+ %148 = OpLabel
+ %193 = OpPhi %6 %194 %153 %52 %175
+ %74 = OpIEqual %37 %193 %71
+ OpSelectionMerge %76 None
+ OpBranchConditional %74 %75 %82
+ %82 = OpLabel
+ OpStore %79 %83
+ OpBranch %76
+ %75 = OpLabel
+ OpStore %79 %81
+ OpBranch %76
+ %76 = OpLabel
+ OpBranch %58
+ %67 = OpLabel
+ OpBranch %58
+ %69 = OpLabel
+ OpBranch %59
+ %59 = OpLabel
+ %87 = OpIAdd %6 %177 %19
+ OpBranch %56
+ %58 = OpLabel
+ %203 = OpPhi %37 %92 %56 %95 %67 %95 %76
+ OpSelectionMerge %96 None
+ OpBranchConditional %203 %88 %96
+ %96 = OpLabel
+ OpStore %79 %83
+ OpBranch %88
+ %91 = OpLabel
+ OpBranch %89
+ %88 = OpLabel
+ OpReturn
+ OpFunctionEnd
+END
+
+# uniforms for variant
+
+# zero
+BUFFER variant_zero DATA_TYPE float DATA
+ 0.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+ ATTACH variant_vertex_shader
+ ATTACH variant_fragment_shader
+ FRAMEBUFFER_SIZE 256 256
+ BIND BUFFER variant_framebuffer AS color LOCATION 0
+ BIND BUFFER variant_zero AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
--- /dev/null
+#!amber
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A fragment shader with switch cases that fall through
+
+# The test passes because shader always writes red.
+
+# Optimized using spirv-opt with the following arguments:
+# '--ccp'
+# '--eliminate-local-single-block'
+# '--combine-access-chains'
+# '--copy-propagate-arrays'
+# '--eliminate-local-single-store'
+# '--eliminate-local-multi-store'
+# '--eliminate-local-single-block'
+# '--private-to-local'
+# spirv-opt commit hash: ab7ac60f14ae66006bed5c989a2cfd4c4881704c
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0 {
+# vec2 injectionSwitch;
+# };
+#
+# void main()
+# {
+# for(int i = 0; i < 2 + int(injectionSwitch.x); i++)
+# {
+# int value = i;
+# float y = 0.5;
+#
+# switch(value)
+# {
+# case 0:
+# y += 0.5;
+# // Always falls through.
+# case 1:
+# y = clamp(1.0, 0.5, y);
+# // Always falls through.
+# case 2:
+# default:
+# // Always ends up here.
+# // Always true.
+# if (y == 1.0)
+# {
+# _GLF_color = vec4(value + 1, 0, 0, 1);
+# return;
+# }
+# }
+# }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 66
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %52
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %8 "i"
+ OpName %19 "buf0"
+ OpMemberName %19 0 "injectionSwitch"
+ OpName %21 ""
+ OpName %31 "value"
+ OpName %34 "y"
+ OpName %52 "_GLF_color"
+ OpMemberDecorate %19 0 Offset 0
+ OpDecorate %19 Block
+ OpDecorate %21 DescriptorSet 0
+ OpDecorate %21 Binding 0
+ OpDecorate %52 Location 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %7 = OpTypePointer Function %6
+ %9 = OpConstant %6 0
+ %16 = OpConstant %6 2
+ %17 = OpTypeFloat 32
+ %18 = OpTypeVector %17 2
+ %19 = OpTypeStruct %18
+ %20 = OpTypePointer Uniform %19
+ %21 = OpVariable %20 Uniform
+ %22 = OpTypeInt 32 0
+ %23 = OpConstant %22 0
+ %24 = OpTypePointer Uniform %17
+ %29 = OpTypeBool
+ %33 = OpTypePointer Function %17
+ %35 = OpConstant %17 0.5
+ %43 = OpConstant %17 1
+ %50 = OpTypeVector %17 4
+ %51 = OpTypePointer Output %50
+ %52 = OpVariable %51 Output
+ %54 = OpConstant %6 1
+ %57 = OpConstant %17 0
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %8 = OpVariable %7 Function
+ %31 = OpVariable %7 Function
+ %34 = OpVariable %33 Function
+ OpStore %8 %9
+ OpBranch %10
+ %10 = OpLabel
+ %63 = OpPhi %6 %9 %5 %62 %13
+ OpLoopMerge %12 %13 None
+ OpBranch %14
+ %14 = OpLabel
+ %25 = OpAccessChain %24 %21 %9 %23
+ %26 = OpLoad %17 %25
+ %27 = OpConvertFToS %6 %26
+ %28 = OpIAdd %6 %16 %27
+ %30 = OpSLessThan %29 %63 %28
+ OpBranchConditional %30 %11 %12
+ %11 = OpLabel
+ OpStore %31 %63
+ OpStore %34 %35
+ OpSelectionMerge %40 None
+ OpSwitch %63 %39 0 %37 1 %38 2 %39
+ %39 = OpLabel
+ %65 = OpPhi %17 %35 %11 %45 %38
+ %47 = OpFOrdEqual %29 %65 %43
+ OpSelectionMerge %49 None
+ OpBranchConditional %47 %48 %49
+ %48 = OpLabel
+ %55 = OpIAdd %6 %63 %54
+ %56 = OpConvertSToF %17 %55
+ %58 = OpCompositeConstruct %50 %56 %57 %57 %43
+ OpStore %52 %58
+ OpReturn
+ %49 = OpLabel
+ OpBranch %40
+ %37 = OpLabel
+ %42 = OpFAdd %17 %35 %35
+ OpStore %34 %42
+ OpBranch %38
+ %38 = OpLabel
+ %64 = OpPhi %17 %35 %11 %42 %37
+ %45 = OpExtInst %17 %1 FClamp %43 %35 %64
+ OpStore %34 %45
+ OpBranch %39
+ %40 = OpLabel
+ OpBranch %13
+ %13 = OpLabel
+ %62 = OpIAdd %6 %63 %54
+ OpStore %8 %62
+ OpBranch %10
+ %12 = OpLabel
+ OpReturn
+ OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+ ATTACH variant_vertex_shader
+ ATTACH variant_fragment_shader
+ FRAMEBUFFER_SIZE 256 256
+ BIND BUFFER variant_framebuffer AS color LOCATION 0
+ BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
--- /dev/null
+#!amber
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# A test for a bug found by GraphicsFuzz.
+
+# Short description: A shader that multiplies a vector by fragcoord
+
+# The test passes because shader always writes red.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 310 es
+# precision highp float;
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+# vec2 injectionSwitch;
+# };
+#
+# // Returns 1.
+# float func()
+# {
+# vec4 value;
+# bool alwaysFalse = gl_FragCoord.x < -1.0;
+#
+# if (alwaysFalse)
+# {
+# vec2 a;
+# value.xy = a;
+# }
+#
+# if (!alwaysFalse)
+# {
+# value.xy = injectionSwitch.xy; // x == 0.0, y == 1.0
+# }
+#
+# //At this point all components of value are guaranteed to be initialized.
+# value.zw = gl_FragCoord.xy * value.xy * vec2(2) + value.xy;
+#
+# // Iterates twice.
+# for (int i = 0; i < int(injectionSwitch.y) + 1; i++)
+# {
+# value.x = float(i);
+# }
+#
+# // Always true.
+# if (value.x == 1.0 && value.y == 1.0)
+# return 1.0;
+# else
+# return 0.0;
+# }
+#
+# void main()
+# {
+# int count = 0;
+#
+# // Iterates twice.
+# for (int i = 0; i < int(injectionSwitch.y) + 1; i++)
+# {
+# count += int(func());
+# }
+#
+# // Always true.
+# if (count == 2)
+# _GLF_color = vec4(1, 0, 0, 1);
+# else
+# _GLF_color = vec4(0, 0, 0, 1);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 8
+; Bound: 129
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %15 %125
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %8 "func("
+ OpName %12 "alwaysFalse"
+ OpName %15 "gl_FragCoord"
+ OpName %27 "value"
+ OpName %30 "a"
+ OpName %38 "buf0"
+ OpMemberName %38 0 "injectionSwitch"
+ OpName %40 ""
+ OpName %62 "i"
+ OpName %100 "count"
+ OpName %101 "i"
+ OpName %125 "_GLF_color"
+ OpDecorate %15 BuiltIn FragCoord
+ OpMemberDecorate %38 0 Offset 0
+ OpDecorate %38 Block
+ OpDecorate %40 DescriptorSet 0
+ OpDecorate %40 Binding 0
+ OpDecorate %125 Location 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %7 = OpTypeFunction %6
+ %10 = OpTypeBool
+ %11 = OpTypePointer Function %10
+ %13 = OpTypeVector %6 4
+ %14 = OpTypePointer Input %13
+ %15 = OpVariable %14 Input
+ %16 = OpTypeInt 32 0
+ %17 = OpConstant %16 0
+ %18 = OpTypePointer Input %6
+ %21 = OpConstant %6 -1
+ %26 = OpTypePointer Function %13
+ %28 = OpTypeVector %6 2
+ %29 = OpTypePointer Function %28
+ %38 = OpTypeStruct %28
+ %39 = OpTypePointer Uniform %38
+ %40 = OpVariable %39 Uniform
+ %41 = OpTypeInt 32 1
+ %42 = OpConstant %41 0
+ %43 = OpTypePointer Uniform %28
+ %53 = OpConstant %6 2
+ %54 = OpConstantComposite %28 %53 %53
+ %61 = OpTypePointer Function %41
+ %69 = OpConstant %16 1
+ %70 = OpTypePointer Uniform %6
+ %74 = OpConstant %41 1
+ %79 = OpTypePointer Function %6
+ %85 = OpConstant %6 1
+ %97 = OpConstant %6 0
+ %120 = OpConstant %41 2
+ %124 = OpTypePointer Output %13
+ %125 = OpVariable %124 Output
+ %126 = OpConstantComposite %13 %85 %97 %97 %85
+ %128 = OpConstantComposite %13 %97 %97 %97 %85
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %100 = OpVariable %61 Function
+ %101 = OpVariable %61 Function
+ OpStore %100 %42
+ OpStore %101 %42
+ OpBranch %102
+ %102 = OpLabel
+ OpLoopMerge %104 %105 None
+ OpBranch %106
+ %106 = OpLabel
+ %107 = OpLoad %41 %101
+ %108 = OpAccessChain %70 %40 %42 %69
+ %109 = OpLoad %6 %108
+ %110 = OpConvertFToS %41 %109
+ %111 = OpIAdd %41 %110 %74
+ %112 = OpSLessThan %10 %107 %111
+ OpBranchConditional %112 %103 %104
+ %103 = OpLabel
+ %113 = OpFunctionCall %6 %8
+ %114 = OpConvertFToS %41 %113
+ %115 = OpLoad %41 %100
+ %116 = OpIAdd %41 %115 %114
+ OpStore %100 %116
+ OpBranch %105
+ %105 = OpLabel
+ %117 = OpLoad %41 %101
+ %118 = OpIAdd %41 %117 %74
+ OpStore %101 %118
+ OpBranch %102
+ %104 = OpLabel
+ %119 = OpLoad %41 %100
+ %121 = OpIEqual %10 %119 %120
+ OpSelectionMerge %123 None
+ OpBranchConditional %121 %122 %127
+ %122 = OpLabel
+ OpStore %125 %126
+ OpBranch %123
+ %127 = OpLabel
+ OpStore %125 %128
+ OpBranch %123
+ %123 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %8 = OpFunction %6 None %7
+ %9 = OpLabel
+ %12 = OpVariable %11 Function
+ %27 = OpVariable %26 Function
+ %30 = OpVariable %29 Function
+ %62 = OpVariable %61 Function
+ %19 = OpAccessChain %18 %15 %17
+ %20 = OpLoad %6 %19
+ %22 = OpFOrdLessThan %10 %20 %21
+ OpStore %12 %22
+ %23 = OpLoad %10 %12
+ OpSelectionMerge %25 None
+ OpBranchConditional %23 %24 %25
+ %24 = OpLabel
+ %31 = OpLoad %28 %30
+ %32 = OpLoad %13 %27
+ %33 = OpVectorShuffle %13 %32 %31 4 5 2 3
+ OpStore %27 %33
+ OpBranch %25
+ %25 = OpLabel
+ %34 = OpLoad %10 %12
+ %35 = OpLogicalNot %10 %34
+ OpSelectionMerge %37 None
+ OpBranchConditional %35 %36 %37
+ %36 = OpLabel
+ %44 = OpAccessChain %43 %40 %42
+ %45 = OpLoad %28 %44
+ %46 = OpLoad %13 %27
+ %47 = OpVectorShuffle %13 %46 %45 4 5 2 3
+ OpStore %27 %47
+ OpBranch %37
+ %37 = OpLabel
+ %48 = OpLoad %13 %15
+ %49 = OpVectorShuffle %28 %48 %48 0 1
+ %50 = OpLoad %13 %27
+ %51 = OpVectorShuffle %28 %50 %50 0 1
+ %52 = OpFMul %28 %49 %51
+ %55 = OpFMul %28 %52 %54
+ %56 = OpLoad %13 %27
+ %57 = OpVectorShuffle %28 %56 %56 0 1
+ %58 = OpFAdd %28 %55 %57
+ %59 = OpLoad %13 %27
+ %60 = OpVectorShuffle %13 %59 %58 0 1 4 5
+ OpStore %27 %60
+ OpStore %62 %42
+ OpBranch %63
+ %63 = OpLabel
+ OpLoopMerge %65 %66 None
+ OpBranch %67
+ %67 = OpLabel
+ %68 = OpLoad %41 %62
+ %71 = OpAccessChain %70 %40 %42 %69
+ %72 = OpLoad %6 %71
+ %73 = OpConvertFToS %41 %72
+ %75 = OpIAdd %41 %73 %74
+ %76 = OpSLessThan %10 %68 %75
+ OpBranchConditional %76 %64 %65
+ %64 = OpLabel
+ %77 = OpLoad %41 %62
+ %78 = OpConvertSToF %6 %77
+ %80 = OpAccessChain %79 %27 %17
+ OpStore %80 %78
+ OpBranch %66
+ %66 = OpLabel
+ %81 = OpLoad %41 %62
+ %82 = OpIAdd %41 %81 %74
+ OpStore %62 %82
+ OpBranch %63
+ %65 = OpLabel
+ %83 = OpAccessChain %79 %27 %17
+ %84 = OpLoad %6 %83
+ %86 = OpFOrdEqual %10 %84 %85
+ OpSelectionMerge %88 None
+ OpBranchConditional %86 %87 %88
+ %87 = OpLabel
+ %89 = OpAccessChain %79 %27 %69
+ %90 = OpLoad %6 %89
+ %91 = OpFOrdEqual %10 %90 %85
+ OpBranch %88
+ %88 = OpLabel
+ %92 = OpPhi %10 %86 %65 %91 %87
+ OpSelectionMerge %94 None
+ OpBranchConditional %92 %93 %96
+ %93 = OpLabel
+ OpReturnValue %85
+ %96 = OpLabel
+ OpReturnValue %97
+ %94 = OpLabel
+ OpUnreachable
+ OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+ ATTACH variant_vertex_shader
+ ATTACH variant_fragment_shader
+ FRAMEBUFFER_SIZE 256 256
+ BIND BUFFER variant_framebuffer AS color LOCATION 0
+ BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
dEQP-VK.graphicsfuzz.always-discarding-function
dEQP-VK.graphicsfuzz.always-false-if-in-do-while
dEQP-VK.graphicsfuzz.always-false-if-with-discard-return
+dEQP-VK.graphicsfuzz.array-idx-multiplied-by-for-loop-idx
+dEQP-VK.graphicsfuzz.assign-array-value-to-another-array
+dEQP-VK.graphicsfuzz.assign-array-value-to-another-array-2
dEQP-VK.graphicsfuzz.barrier-in-loop-with-break
dEQP-VK.graphicsfuzz.break-in-do-while-with-nested-if
dEQP-VK.graphicsfuzz.call-function-with-discard
dEQP-VK.graphicsfuzz.continue-and-merge
dEQP-VK.graphicsfuzz.control-flow-in-function
dEQP-VK.graphicsfuzz.control-flow-switch
+dEQP-VK.graphicsfuzz.cosh-return-inf-unused
dEQP-VK.graphicsfuzz.cov-analysis-reachable-from-many
dEQP-VK.graphicsfuzz.cov-apfloat-acos-ldexp
dEQP-VK.graphicsfuzz.cov-apfloat-determinant
dEQP-VK.graphicsfuzz.cov-vector-log2-cosh
dEQP-VK.graphicsfuzz.cov-wrap-op-kill-for-loop
dEQP-VK.graphicsfuzz.cov-wrap-op-kill-two-branches
+dEQP-VK.graphicsfuzz.create-color-in-do-while-for-loop
dEQP-VK.graphicsfuzz.dead-barriers-in-loops
dEQP-VK.graphicsfuzz.dead-struct-init
dEQP-VK.graphicsfuzz.disc-and-add-in-func-in-loop
dEQP-VK.graphicsfuzz.discards-in-control-flow
dEQP-VK.graphicsfuzz.do-while-loop-in-conditionals
dEQP-VK.graphicsfuzz.do-while-with-always-true-if
+dEQP-VK.graphicsfuzz.do-while-with-if-condition
dEQP-VK.graphicsfuzz.early-return-and-barrier
+dEQP-VK.graphicsfuzz.find-msb-from-lsb
dEQP-VK.graphicsfuzz.for-condition-always-false
dEQP-VK.graphicsfuzz.for-loop-with-return
dEQP-VK.graphicsfuzz.for-with-ifs-and-return
dEQP-VK.graphicsfuzz.fragcoord-control-flow
dEQP-VK.graphicsfuzz.fragcoord-control-flow-2
+dEQP-VK.graphicsfuzz.function-with-float-comparison
dEQP-VK.graphicsfuzz.function-with-uniform-return
dEQP-VK.graphicsfuzz.global-array-loops
dEQP-VK.graphicsfuzz.if-and-switch
+dEQP-VK.graphicsfuzz.increment-value-in-nested-for-loop
dEQP-VK.graphicsfuzz.injection-switch-as-comparison
dEQP-VK.graphicsfuzz.int-mat2-struct
dEQP-VK.graphicsfuzz.loop-call-discard
dEQP-VK.graphicsfuzz.modf-gl-color
dEQP-VK.graphicsfuzz.modf-temp-modf-color
dEQP-VK.graphicsfuzz.nested-for-break-mat-color
+dEQP-VK.graphicsfuzz.nested-for-loops-switch-fallthrough
dEQP-VK.graphicsfuzz.nested-for-loops-with-return
dEQP-VK.graphicsfuzz.nested-ifs-and-return-in-for-loop
dEQP-VK.graphicsfuzz.nested-loops-switch
dEQP-VK.graphicsfuzz.return-float-from-while-loop
dEQP-VK.graphicsfuzz.return-in-loop-in-function
dEQP-VK.graphicsfuzz.return-inside-loop-in-function
+dEQP-VK.graphicsfuzz.return-mat2x3-value-from-func
dEQP-VK.graphicsfuzz.returned-boolean-in-vector
+dEQP-VK.graphicsfuzz.set-color-in-one-iteration-while-loop
dEQP-VK.graphicsfuzz.similar-nested-ifs
dEQP-VK.graphicsfuzz.smoothstep-after-loop
dEQP-VK.graphicsfuzz.struct-and-unreachable-infinite-loop
+dEQP-VK.graphicsfuzz.struct-array-data-as-loop-iterator
dEQP-VK.graphicsfuzz.struct-controlled-loop
dEQP-VK.graphicsfuzz.struct-used-as-temporary
dEQP-VK.graphicsfuzz.switch-case-with-undefined-expression
dEQP-VK.graphicsfuzz.switch-inside-while-always-return
dEQP-VK.graphicsfuzz.switch-loop-switch-if
dEQP-VK.graphicsfuzz.switch-with-empty-if-false
+dEQP-VK.graphicsfuzz.switch-with-fall-through-cases
dEQP-VK.graphicsfuzz.swizzle-struct-init-min
dEQP-VK.graphicsfuzz.transpose-rectangular-matrix
dEQP-VK.graphicsfuzz.two-2-iteration-loops
dEQP-VK.graphicsfuzz.unreachable-return-in-loop
dEQP-VK.graphicsfuzz.unreachable-switch-case-with-discards
dEQP-VK.graphicsfuzz.uv-value-comparison-as-boolean
+dEQP-VK.graphicsfuzz.vector-values-multiplied-by-fragcoord
dEQP-VK.graphicsfuzz.vectors-and-discard-in-function
dEQP-VK.graphicsfuzz.while-function-always-false
dEQP-VK.graphicsfuzz.while-inside-switch