Add a batch of GraphicsFuzz tests
authorToni Salmivalli <toni.salmivalli@siru.fi>
Thu, 26 Nov 2020 13:30:02 +0000 (15:30 +0200)
committerAlexander Galazin <alexander.galazin@arm.com>
Wed, 10 Feb 2021 08:39:15 +0000 (09:39 +0100)
Components: Vulkan

New Tests:

dEQP-VK.graphicsfuzz.do-while-if-return
dEQP-VK.graphicsfuzz.flag-always-false-if
dEQP-VK.graphicsfuzz.stable-binarysearch-tree-false-if-discard-loop
dEQP-VK.graphicsfuzz.stable-binarysearch-tree-nested-if-and-conditional
dEQP-VK.graphicsfuzz.stable-collatz-push-constant-with-nested-min-max
dEQP-VK.graphicsfuzz.stable-mergesort-reversed-for-loop
dEQP-VK.graphicsfuzz.stable-triangle-array-nested-loop
dEQP-VK.graphicsfuzz.stable-triangle-nested-for-loop-and-true-if
dEQP-VK.graphicsfuzz.vec2-modf

Change-Id: Ifb56713b08c8cb0351733929c20f5b18a3f6c68e

13 files changed:
android/cts/master/vk-master-2020-03-01.txt
android/cts/master/vk-master.txt
external/vulkancts/data/vulkan/amber/graphicsfuzz/do-while-if-return.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/graphicsfuzz/flag-always-false-if.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/graphicsfuzz/index.txt
external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-binarysearch-tree-false-if-discard-loop.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-binarysearch-tree-nested-if-and-conditional.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-collatz-push-constant-with-nested-min-max.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-mergesort-reversed-for-loop.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-triangle-array-nested-loop.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-triangle-nested-for-loop-and-true-if.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/graphicsfuzz/vec2-modf.amber [new file with mode: 0644]
external/vulkancts/mustpass/master/vk-default.txt

index 671a324..dbcb58d 100644 (file)
@@ -344022,11 +344022,13 @@ dEQP-VK.graphicsfuzz.discard-in-loop
 dEQP-VK.graphicsfuzz.discard-in-loop-in-function
 dEQP-VK.graphicsfuzz.discards-in-control-flow
 dEQP-VK.graphicsfuzz.do-while-false-loops
+dEQP-VK.graphicsfuzz.do-while-if-return
 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.flag-always-false-if
 dEQP-VK.graphicsfuzz.for-condition-always-false
 dEQP-VK.graphicsfuzz.for-loop-with-return
 dEQP-VK.graphicsfuzz.for-with-ifs-and-return
@@ -344093,14 +344095,20 @@ dEQP-VK.graphicsfuzz.spv-stable-orbit-Os-access-chain-mutate-pointer
 dEQP-VK.graphicsfuzz.spv-stable-pillars-O-op-select-to-op-phi
 dEQP-VK.graphicsfuzz.spv-stable-quicksort-mat-func-param
 dEQP-VK.graphicsfuzz.spv-stable-rects-Os-mutate-var-push-through-var
+dEQP-VK.graphicsfuzz.stable-binarysearch-tree-false-if-discard-loop
+dEQP-VK.graphicsfuzz.stable-binarysearch-tree-nested-if-and-conditional
 dEQP-VK.graphicsfuzz.stable-binarysearch-tree-with-loop-read-write-global
+dEQP-VK.graphicsfuzz.stable-collatz-push-constant-with-nested-min-max
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-injected-conditional-true
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-true-conditional-simple-loop
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-vec3-values-from-matrix
+dEQP-VK.graphicsfuzz.stable-mergesort-reversed-for-loop
 dEQP-VK.graphicsfuzz.stable-quicksort-for-loop-with-injection
 dEQP-VK.graphicsfuzz.stable-quicksort-if-false-else-return
 dEQP-VK.graphicsfuzz.stable-quicksort-max-value-as-index
 dEQP-VK.graphicsfuzz.stable-rects-vec4-clamp-conditional-min-mix
+dEQP-VK.graphicsfuzz.stable-triangle-array-nested-loop
+dEQP-VK.graphicsfuzz.stable-triangle-nested-for-loop-and-true-if
 dEQP-VK.graphicsfuzz.struct-and-unreachable-infinite-loop
 dEQP-VK.graphicsfuzz.struct-array-data-as-loop-iterator
 dEQP-VK.graphicsfuzz.struct-controlled-loop
@@ -344135,6 +344143,7 @@ dEQP-VK.graphicsfuzz.unreachable-loops-in-switch
 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.vec2-modf
 dEQP-VK.graphicsfuzz.vector-values-multiplied-by-fragcoord
 dEQP-VK.graphicsfuzz.vectors-and-discard-in-function
 dEQP-VK.graphicsfuzz.while-function-always-false
index bb9f0fe..9d53165 100644 (file)
@@ -754215,11 +754215,13 @@ dEQP-VK.graphicsfuzz.discard-in-loop
 dEQP-VK.graphicsfuzz.discard-in-loop-in-function
 dEQP-VK.graphicsfuzz.discards-in-control-flow
 dEQP-VK.graphicsfuzz.do-while-false-loops
+dEQP-VK.graphicsfuzz.do-while-if-return
 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.flag-always-false-if
 dEQP-VK.graphicsfuzz.for-condition-always-false
 dEQP-VK.graphicsfuzz.for-loop-with-return
 dEQP-VK.graphicsfuzz.for-with-ifs-and-return
@@ -754286,14 +754288,20 @@ dEQP-VK.graphicsfuzz.spv-stable-orbit-Os-access-chain-mutate-pointer
 dEQP-VK.graphicsfuzz.spv-stable-pillars-O-op-select-to-op-phi
 dEQP-VK.graphicsfuzz.spv-stable-quicksort-mat-func-param
 dEQP-VK.graphicsfuzz.spv-stable-rects-Os-mutate-var-push-through-var
+dEQP-VK.graphicsfuzz.stable-binarysearch-tree-false-if-discard-loop
+dEQP-VK.graphicsfuzz.stable-binarysearch-tree-nested-if-and-conditional
 dEQP-VK.graphicsfuzz.stable-binarysearch-tree-with-loop-read-write-global
+dEQP-VK.graphicsfuzz.stable-collatz-push-constant-with-nested-min-max
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-injected-conditional-true
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-true-conditional-simple-loop
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-vec3-values-from-matrix
+dEQP-VK.graphicsfuzz.stable-mergesort-reversed-for-loop
 dEQP-VK.graphicsfuzz.stable-quicksort-for-loop-with-injection
 dEQP-VK.graphicsfuzz.stable-quicksort-if-false-else-return
 dEQP-VK.graphicsfuzz.stable-quicksort-max-value-as-index
 dEQP-VK.graphicsfuzz.stable-rects-vec4-clamp-conditional-min-mix
+dEQP-VK.graphicsfuzz.stable-triangle-array-nested-loop
+dEQP-VK.graphicsfuzz.stable-triangle-nested-for-loop-and-true-if
 dEQP-VK.graphicsfuzz.struct-and-unreachable-infinite-loop
 dEQP-VK.graphicsfuzz.struct-array-data-as-loop-iterator
 dEQP-VK.graphicsfuzz.struct-controlled-loop
@@ -754328,6 +754336,7 @@ dEQP-VK.graphicsfuzz.unreachable-loops-in-switch
 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.vec2-modf
 dEQP-VK.graphicsfuzz.vector-values-multiplied-by-fragcoord
 dEQP-VK.graphicsfuzz.vectors-and-discard-in-function
 dEQP-VK.graphicsfuzz.while-function-always-false
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/do-while-if-return.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/do-while-if-return.amber
new file mode 100644 (file)
index 0000000..81113bf
--- /dev/null
@@ -0,0 +1,231 @@
+#!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 the GraphicsFuzz project.
+
+# Short description: A fragment shader with true if in a nested do while loop
+
+# The test passes because the shader always writes color red.
+
+# Optimized using spirv-opt with the following arguments:
+# '--simplify-instructions'
+# '--private-to-local'
+# '--eliminate-local-multi-store'
+# '--convert-local-access-chains'
+# '--inline-entry-points-exhaustive'
+# '--simplify-instructions'
+# '--eliminate-dead-inserts'
+# '--vector-dce'
+# '--combine-access-chains'
+# '--convert-local-access-chains'
+# '--if-conversion'
+# '--private-to-local'
+# '--eliminate-local-single-store'
+# '--copy-propagate-arrays'
+# spirv-opt commit hash: 230f363e6da32791f640b02205e0645cc67c3f1d
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch;   // x == 0.0, y == 1.0
+# };
+#
+# int func()
+# {
+#     const int loop_limit = 100;
+#     int loop_count = 0;
+#     do
+#     {
+#         loop_count++;
+#         do
+#         {
+#             loop_count++;
+#             // Always true.
+#             if (injectionSwitch.x < injectionSwitch.y)
+#             {
+#                 return 1;
+#             }
+#             // Always true.
+#             if (injectionSwitch.x < injectionSwitch.y)
+#             {
+#                 break;
+#             }
+#         } while (loop_count < loop_limit);
+#     } while (loop_count < loop_limit);
+#     return 0;
+# }
+# void main()
+# {
+#     if(func() == 1)
+#     {
+#         _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#     }
+#     else
+#     {
+#         _GLF_color = vec4(1.0);
+#     }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 73
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %65
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %8 "func("
+               OpName %11 "loop_count"
+               OpName %28 "buf0"
+               OpMemberName %28 0 "injectionSwitch"
+               OpName %30 ""
+               OpName %65 "_GLF_color"
+               OpMemberDecorate %28 0 Offset 0
+               OpDecorate %28 Block
+               OpDecorate %30 DescriptorSet 0
+               OpDecorate %30 Binding 0
+               OpDecorate %65 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypeFunction %6
+         %10 = OpTypePointer Function %6
+         %12 = OpConstant %6 0
+         %18 = OpConstant %6 1
+         %26 = OpTypeFloat 32
+         %27 = OpTypeVector %26 2
+         %28 = OpTypeStruct %27
+         %29 = OpTypePointer Uniform %28
+         %30 = OpVariable %29 Uniform
+         %31 = OpTypeInt 32 0
+         %32 = OpConstant %31 0
+         %33 = OpTypePointer Uniform %26
+         %36 = OpConstant %31 1
+         %39 = OpTypeBool
+         %53 = OpConstant %6 100
+         %63 = OpTypeVector %26 4
+         %64 = OpTypePointer Output %63
+         %65 = OpVariable %64 Output
+         %66 = OpConstant %26 1
+         %67 = OpConstant %26 0
+         %68 = OpConstantComposite %63 %66 %67 %67 %66
+         %70 = OpConstantComposite %63 %66 %66 %66 %66
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %59 = OpFunctionCall %6 %8
+         %60 = OpIEqual %39 %59 %18
+               OpSelectionMerge %62 None
+               OpBranchConditional %60 %61 %69
+         %61 = OpLabel
+               OpStore %65 %68
+               OpBranch %62
+         %69 = OpLabel
+               OpStore %65 %70
+               OpBranch %62
+         %62 = OpLabel
+               OpReturn
+               OpFunctionEnd
+          %8 = OpFunction %6 None %7
+          %9 = OpLabel
+         %11 = OpVariable %10 Function
+               OpStore %11 %12
+               OpBranch %13
+         %13 = OpLabel
+         %71 = OpPhi %6 %12 %9 %25 %16
+               OpLoopMerge %15 %16 None
+               OpBranch %14
+         %14 = OpLabel
+         %19 = OpIAdd %6 %71 %18
+               OpStore %11 %19
+               OpBranch %20
+         %20 = OpLabel
+         %72 = OpPhi %6 %19 %14 %25 %23
+               OpLoopMerge %22 %23 None
+               OpBranch %21
+         %21 = OpLabel
+         %25 = OpIAdd %6 %72 %18
+               OpStore %11 %25
+         %34 = OpAccessChain %33 %30 %12 %32
+         %35 = OpLoad %26 %34
+         %37 = OpAccessChain %33 %30 %12 %36
+         %38 = OpLoad %26 %37
+         %40 = OpFOrdLessThan %39 %35 %38
+               OpSelectionMerge %42 None
+               OpBranchConditional %40 %41 %42
+         %41 = OpLabel
+               OpReturnValue %18
+         %42 = OpLabel
+         %44 = OpAccessChain %33 %30 %12 %32
+         %45 = OpLoad %26 %44
+         %46 = OpAccessChain %33 %30 %12 %36
+         %47 = OpLoad %26 %46
+         %48 = OpFOrdLessThan %39 %45 %47
+               OpSelectionMerge %50 None
+               OpBranchConditional %48 %49 %50
+         %49 = OpLabel
+               OpBranch %22
+         %50 = OpLabel
+               OpBranch %23
+         %23 = OpLabel
+         %54 = OpSLessThan %39 %25 %53
+               OpBranchConditional %54 %20 %22
+         %22 = OpLabel
+               OpBranch %16
+         %16 = OpLabel
+         %56 = OpSLessThan %39 %25 %53
+               OpBranchConditional %56 %13 %15
+         %15 = OpLabel
+               OpReturnValue %12
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> STD140 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
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/flag-always-false-if.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/flag-always-false-if.amber
new file mode 100644 (file)
index 0000000..27acd10
--- /dev/null
@@ -0,0 +1,299 @@
+#!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 the GraphicsFuzz project.
+
+# Short description: A fragment shader with recurrent always false if statement
+
+# The test passes because the shader always writes color red.
+
+# Optimized using spirv-opt with the following arguments:
+# '--vector-dce'
+# '--vector-dce'
+# '--scalar-replacement=100'
+# '--redundancy-elimination'
+# '--redundancy-elimination'
+# '--eliminate-dead-branches'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--scalar-replacement=100'
+# '--reduce-load-size'
+# '--copy-propagate-arrays'
+# '--eliminate-dead-branches'
+# '--merge-blocks'
+# '--eliminate-dead-code-aggressive'
+# '--inline-entry-points-exhaustive'
+# '--simplify-instructions'
+# '--redundancy-elimination'
+# '--ccp'
+# '--eliminate-local-single-block'
+# '--scalar-replacement=100'
+# '--reduce-load-size'
+# '--eliminate-local-single-block'
+# '--reduce-load-size'
+# '--eliminate-local-single-store'
+# '--inline-entry-points-exhaustive'
+# spirv-opt commit hash: 230f363e6da32791f640b02205e0645cc67c3f1d
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch; // x == 0.0, y == 1.0
+# };
+# void main()
+# {
+#     const int loop_limit = 100;
+#     int loop_count = 0;
+#     // Always false.
+#     if (injectionSwitch.x > injectionSwitch.y)
+#     {
+#         return;
+#     }
+#     // Always false.
+#     gl_FragCoord.x < log(1.0);
+#     for (; loop_count < loop_limit; loop_count++)
+#     {
+#         // Always false.
+#         if (injectionSwitch.x > injectionSwitch.y)
+#         {
+#             break;
+#         }
+#         // Always false.
+#         if (injectionSwitch.x > injectionSwitch.y)
+#         {
+#             _GLF_color = vec4(1.0);
+#         }
+#         else
+#         {
+#             // Always false.
+#             if (gl_FragCoord.x < 0.0)
+#             {
+#                 return;
+#             }
+#         }
+#         // Always false.
+#         if (injectionSwitch.x > injectionSwitch.y)
+#         {
+#             _GLF_color = vec4(1.0);
+#         }
+#         else
+#         {
+#             _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#         }
+#         // Always false.
+#         if (injectionSwitch.x > injectionSwitch.y)
+#         {
+#             return;
+#         }
+#         // Always false.
+#         if (gl_FragCoord.x < 0.0)
+#         {
+#             for (;  loop_count < loop_limit; loop_count++)
+#             {
+#             }
+#         }
+#     }
+#     if(loop_count >= loop_limit)
+#     {
+#         _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#     }
+#     else
+#     {
+#         _GLF_color = vec4(1.0);
+#     }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 109
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %30 %60
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %8 "loop_count"
+               OpName %12 "buf0"
+               OpMemberName %12 0 "injectionSwitch"
+               OpName %14 ""
+               OpName %30 "gl_FragCoord"
+               OpName %60 "_GLF_color"
+               OpMemberDecorate %12 0 Offset 0
+               OpDecorate %12 Block
+               OpDecorate %14 DescriptorSet 0
+               OpDecorate %14 Binding 0
+               OpDecorate %30 BuiltIn FragCoord
+               OpDecorate %60 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypePointer Function %6
+          %9 = OpConstant %6 0
+         %10 = OpTypeFloat 32
+         %11 = OpTypeVector %10 2
+         %12 = OpTypeStruct %11
+         %13 = OpTypePointer Uniform %12
+         %14 = OpVariable %13 Uniform
+         %15 = OpTypeInt 32 0
+         %16 = OpConstant %15 0
+         %17 = OpTypePointer Uniform %10
+         %20 = OpConstant %15 1
+         %23 = OpTypeBool
+         %28 = OpTypeVector %10 4
+         %29 = OpTypePointer Input %28
+         %30 = OpVariable %29 Input
+         %31 = OpTypePointer Input %10
+         %34 = OpConstant %10 0
+         %42 = OpConstant %6 100
+         %59 = OpTypePointer Output %28
+         %60 = OpVariable %59 Output
+         %61 = OpConstant %10 1
+         %62 = OpConstantComposite %28 %61 %61 %61 %61
+         %78 = OpConstantComposite %28 %61 %34 %34 %61
+        %100 = OpConstant %6 1
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+          %8 = OpVariable %7 Function
+               OpStore %8 %9
+         %18 = OpAccessChain %17 %14 %9 %16
+         %19 = OpLoad %10 %18
+         %21 = OpAccessChain %17 %14 %9 %20
+         %22 = OpLoad %10 %21
+         %24 = OpFOrdGreaterThan %23 %19 %22
+               OpSelectionMerge %26 None
+               OpBranchConditional %24 %25 %26
+         %25 = OpLabel
+               OpReturn
+         %26 = OpLabel
+         %32 = OpAccessChain %31 %30 %16
+         %33 = OpLoad %10 %32
+         %35 = OpFOrdLessThan %23 %33 %34
+               OpBranch %36
+         %36 = OpLabel
+         %41 = OpLoad %6 %8
+         %43 = OpSLessThan %23 %41 %42
+               OpLoopMerge %38 %39 None
+               OpBranchConditional %43 %37 %38
+         %37 = OpLabel
+               OpSelectionMerge %50 None
+               OpBranchConditional %24 %49 %50
+         %49 = OpLabel
+               OpBranch %38
+         %50 = OpLabel
+               OpSelectionMerge %58 None
+               OpBranchConditional %24 %57 %63
+         %57 = OpLabel
+               OpStore %60 %62
+               OpBranch %58
+         %63 = OpLabel
+               OpSelectionMerge %68 None
+               OpBranchConditional %35 %67 %68
+         %67 = OpLabel
+               OpReturn
+         %68 = OpLabel
+               OpBranch %58
+         %58 = OpLabel
+               OpSelectionMerge %76 None
+               OpBranchConditional %24 %75 %77
+         %75 = OpLabel
+               OpStore %60 %62
+               OpBranch %76
+         %77 = OpLabel
+               OpStore %60 %78
+               OpBranch %76
+         %76 = OpLabel
+               OpSelectionMerge %85 None
+               OpBranchConditional %24 %84 %85
+         %84 = OpLabel
+               OpReturn
+         %85 = OpLabel
+               OpSelectionMerge %91 None
+               OpBranchConditional %35 %90 %91
+         %90 = OpLabel
+               OpBranch %92
+         %92 = OpLabel
+         %97 = OpLoad %6 %8
+         %98 = OpSLessThan %23 %97 %42
+               OpLoopMerge %94 %93 None
+               OpBranchConditional %98 %93 %94
+         %93 = OpLabel
+         %99 = OpLoad %6 %8
+        %101 = OpIAdd %6 %99 %100
+               OpStore %8 %101
+               OpBranch %92
+         %94 = OpLabel
+               OpBranch %91
+         %91 = OpLabel
+               OpBranch %39
+         %39 = OpLabel
+        %102 = OpLoad %6 %8
+        %103 = OpIAdd %6 %102 %100
+               OpStore %8 %103
+               OpBranch %36
+         %38 = OpLabel
+        %104 = OpLoad %6 %8
+        %105 = OpSGreaterThanEqual %23 %104 %42
+               OpSelectionMerge %107 None
+               OpBranchConditional %105 %106 %108
+        %106 = OpLabel
+               OpStore %60 %78
+               OpBranch %107
+        %108 = OpLabel
+               OpStore %60 %62
+               OpBranch %107
+        %107 = OpLabel
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> STD140 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
index 2f47599..dcea799 100644 (file)
 {      "discard-in-loop-in-function.amber",                                                                                                            "discard-in-loop-in-function",                                                                                                          "A shader with a discard nested in a loop in a function"                                                        },
 {      "discards-in-control-flow.amber",                                                                                                                       "discards-in-control-flow",                                                                                                                     "A fragment shader with discards in loops and conditionals"                                                     },
 {      "do-while-false-loops.amber",                                                                                                                           "do-while-false-loops",                                                                                                                         "Code wrapped in nested single iteration loops"                                                                         },
+{      "do-while-if-return.amber",                                                                                                                                     "do-while-if-return",                                                                                                                           "A fragment shader with true if in a nested do while loop"                                                      },
 {      "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"                                                                                     },
+{      "flag-always-false-if.amber",                                                                                                                           "flag-always-false-if",                                                                                                                         "A fragment shader with recurrent always false if statement"                                            },
 {      "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"                          },
 {      "spv-stable-pillars-O-op-select-to-op-phi.amber",                                                                                       "spv-stable-pillars-O-op-select-to-op-phi",                                                                                     "Three shaders diff: OpSelect -> OpPhi"                                                                                         },
 {      "spv-stable-quicksort-mat-func-param.amber",                                                                                            "spv-stable-quicksort-mat-func-param",                                                                                          "Two shaders with diff: added mat3x3 func param"                                                                        },
 {      "spv-stable-rects-Os-mutate-var-push-through-var.amber",                                                                        "spv-stable-rects-Os-mutate-var-push-through-var",                                                                      "Three shaders diff: new variable used and mutated"                                                                     },
+{      "stable-binarysearch-tree-false-if-discard-loop.amber",                                                                         "stable-binarysearch-tree-false-if-discard-loop",                                                                       "A fragment shader with always false if with discard loop"                                                      },
+{      "stable-binarysearch-tree-nested-if-and-conditional.amber",                                                                     "stable-binarysearch-tree-nested-if-and-conditional",                                                           "A fragment shader with nested if and conditional statement"                                            },
 {      "stable-binarysearch-tree-with-loop-read-write-global.amber",                                                           "stable-binarysearch-tree-with-loop-read-write-global",                                                         "A pair of fragment shaders that both render red"                                                                       },
+{      "stable-collatz-push-constant-with-nested-min-max.amber",                                                                       "stable-collatz-push-constant-with-nested-min-max",                                                                     "A fragment shader with push constant and nested min max"                                                       },
 {      "stable-colorgrid-modulo-injected-conditional-true.amber",                                                                      "stable-colorgrid-modulo-injected-conditional-true",                                                            "A fragment shader with an always true conditional"                                                                     },
 {      "stable-colorgrid-modulo-true-conditional-simple-loop.amber",                                                           "stable-colorgrid-modulo-true-conditional-simple-loop",                                                         "A fragment shader with conditional and simple loop"                                                            },
 {      "stable-colorgrid-modulo-vec3-values-from-matrix.amber",                                                                        "stable-colorgrid-modulo-vec3-values-from-matrix",                                                                      "A fragment shader with vec3 values set from matrix4x2"                                                         },
+{      "stable-mergesort-reversed-for-loop.amber",                                                                                                     "stable-mergesort-reversed-for-loop",                                                                                           "A fragment shader with once iterated reversed for loop"                                                        },
 {      "stable-quicksort-for-loop-with-injection.amber",                                                                                       "stable-quicksort-for-loop-with-injection",                                                                                     "A fragment shader with a for loop containing injection"                                                        },
 {      "stable-quicksort-if-false-else-return.amber",                                                                                          "stable-quicksort-if-false-else-return",                                                                                        "A fragment shader with an always false if statement"                                                           },
 {      "stable-quicksort-max-value-as-index.amber",                                                                                            "stable-quicksort-max-value-as-index",                                                                                          "A fragment shader with greater of two values as index"                                                         },
 {      "stable-rects-vec4-clamp-conditional-min-mix.amber",                                                                            "stable-rects-vec4-clamp-conditional-min-mix",                                                                          "A fragment shader with min-mix in always false conditional"                                            },
+{      "stable-triangle-array-nested-loop.amber",                                                                                                      "stable-triangle-array-nested-loop",                                                                                            "A fragment shader with array and nested loops"                                                                         },
+{      "stable-triangle-nested-for-loop-and-true-if.amber",                                                                            "stable-triangle-nested-for-loop-and-true-if",                                                                          "A fragment shader with nested for loop and always true if"                                                     },
 {      "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"                                                                                         },
 {      "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"                                                         },
+{      "vec2-modf.amber",                                                                                                                                                      "vec2-modf",                                                                                                                                            "A fragment shader with vec2 in modulus fraction function"                                                      },
 {      "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"                                                         },
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-binarysearch-tree-false-if-discard-loop.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-binarysearch-tree-false-if-discard-loop.amber
new file mode 100644 (file)
index 0000000..360fcaa
--- /dev/null
@@ -0,0 +1,2113 @@
+#!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 always false if with discard loop
+
+# The test passes because both shaders render the same image.
+
+# Optimized using spirv-opt with the following arguments:
+# '-O'
+# spirv-opt commit hash: 230f363e6da32791f640b02205e0645cc67c3f1d
+
+
+
+SHADER vertex reference_vertex_shader PASSTHROUGH
+
+# reference_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# struct BST
+# {
+#     int data;
+#     int leftIndex;
+#     int rightIndex;
+# };
+#
+# BST tree[10];
+#
+# void makeTreeNode(inout BST tree, int data)
+# {
+#     tree.data = data;
+#     tree.leftIndex = -1;
+#     tree.rightIndex = -1;
+# }
+# void insert(int treeIndex, int data)
+# {
+#     int baseIndex = 0;
+#     while (baseIndex <= treeIndex)
+#     {
+#         if (data <= tree[baseIndex].data)
+#         {
+#             if (tree[baseIndex].leftIndex == -1)
+#             {
+#                 tree[baseIndex].leftIndex = treeIndex;
+#                 makeTreeNode(tree[treeIndex], data);
+#                 return;
+#             }
+#             else
+#             {
+#                 baseIndex = tree[baseIndex].leftIndex;
+#                 continue;
+#             }
+#         }
+#         else
+#         {
+#             if (tree[baseIndex].rightIndex == -1)
+#             {
+#                 tree[baseIndex].rightIndex = treeIndex;
+#                 makeTreeNode(tree[treeIndex], data);
+#                 return;
+#             }
+#             else
+#             {
+#                 baseIndex = tree[baseIndex].rightIndex;
+#                 continue;
+#             }
+#         }
+#     }
+# }
+# int search(int target)
+# {
+#     BST currentNode;
+#     int index = 0;
+#     while (index != -1)
+#     {
+#         currentNode = tree[index];
+#         if (currentNode.data == target)
+#         {
+#             return target;
+#         }
+#         index = target > currentNode.data ? currentNode.rightIndex : currentNode.leftIndex;
+#     }
+#     return -1;
+# }
+# void main()
+# {
+#     int treeIndex = 0;
+#     makeTreeNode(tree[0], 9);
+#     treeIndex++;
+#     insert(treeIndex, 5);
+#     treeIndex++;
+#     insert(treeIndex, 12);
+#     treeIndex++;
+#     insert(treeIndex, 15);
+#     treeIndex++;
+#     insert(treeIndex, 7);
+#     treeIndex++;
+#     insert(treeIndex, 8);
+#     treeIndex++;
+#     insert(treeIndex, 2);
+#     treeIndex++;
+#     insert(treeIndex, 6);
+#     treeIndex++;
+#     insert(treeIndex, 17);
+#     treeIndex++;
+#     insert(treeIndex, 13);
+#     int count = 0;
+#     for (int i = 0; i < 20; i++)
+#     {
+#         int result = search(i);
+#         switch (i)
+#         {
+#         case 9:
+#         case 5:
+#         case 12:
+#         case 15:
+#         case 7:
+#         case 8:
+#         case 2:
+#         case 6:
+#         case 17:
+#         case 13:
+#             if (result == i)
+#             {
+#                 count++;
+#             }
+#             break;
+#         default:
+#             if (result == -1)
+#             {
+#                 count++;
+#             }
+#             break;
+#         }
+#     }
+#     if (count == 20)
+#     {
+#         _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#     }
+#     else
+#     {
+#         _GLF_color = vec4(0.0, 0.0, 1.0, 1.0);
+#     }
+# }
+SHADER fragment reference_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 1372
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %254
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %7 "BST"
+               OpMemberName %7 0 "data"
+               OpMemberName %7 1 "leftIndex"
+               OpMemberName %7 2 "rightIndex"
+               OpName %47 "tree"
+               OpName %254 "_GLF_color"
+               OpDecorate %254 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypeStruct %6 %6 %6
+          %8 = OpTypePointer Function %7
+          %9 = OpTypePointer Function %6
+         %24 = OpConstant %6 0
+         %27 = OpConstant %6 1
+         %28 = OpConstant %6 -1
+         %30 = OpConstant %6 2
+         %40 = OpTypeBool
+         %43 = OpTypeInt 32 0
+         %44 = OpConstant %43 10
+         %45 = OpTypeArray %7 %44
+        %141 = OpConstant %6 9
+        %151 = OpConstant %6 5
+        %158 = OpConstant %6 12
+        %165 = OpConstant %6 15
+        %172 = OpConstant %6 7
+        %179 = OpConstant %6 8
+        %192 = OpConstant %6 6
+        %199 = OpConstant %6 17
+        %206 = OpConstant %6 13
+        %219 = OpConstant %6 20
+        %251 = OpTypeFloat 32
+        %252 = OpTypeVector %251 4
+        %253 = OpTypePointer Output %252
+        %254 = OpVariable %253 Output
+        %255 = OpConstant %251 1
+        %256 = OpConstant %251 0
+        %257 = OpConstantComposite %252 %255 %256 %256 %255
+        %259 = OpConstantComposite %252 %256 %256 %255 %255
+        %262 = OpConstant %43 0
+        %263 = OpConstantFalse %40
+        %266 = OpConstantTrue %40
+       %1015 = OpTypePointer Function %45
+       %1318 = OpUndef %6
+       %1359 = OpConstantComposite %7 %141 %28 %28
+       %1360 = OpConstantComposite %7 %151 %28 %28
+       %1361 = OpConstantComposite %7 %158 %28 %28
+       %1362 = OpConstant %6 3
+       %1363 = OpConstantComposite %7 %165 %28 %28
+       %1364 = OpConstant %6 4
+       %1365 = OpConstantComposite %7 %172 %28 %28
+       %1366 = OpConstantComposite %7 %179 %28 %28
+       %1367 = OpConstantComposite %7 %30 %28 %28
+       %1368 = OpConstantComposite %7 %192 %28 %28
+       %1369 = OpConstantComposite %7 %199 %28 %28
+       %1370 = OpConstantComposite %7 %206 %28 %28
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %47 = OpVariable %1015 Function
+        %148 = OpAccessChain %8 %47 %24
+               OpStore %148 %1359
+               OpSelectionMerge %347 None
+               OpSwitch %262 %288
+        %288 = OpLabel
+               OpBranch %289
+        %289 = OpLabel
+       %1212 = OpPhi %6 %24 %288 %1342 %343
+        %293 = OpSLessThanEqual %40 %1212 %27
+               OpLoopMerge %344 %343 None
+               OpBranchConditional %293 %294 %344
+        %294 = OpLabel
+        %297 = OpAccessChain %9 %47 %1212 %24
+        %298 = OpLoad %6 %297
+        %299 = OpSLessThanEqual %40 %151 %298
+               OpSelectionMerge %342 None
+               OpBranchConditional %299 %300 %321
+        %321 = OpLabel
+        %323 = OpAccessChain %9 %47 %1212 %30
+        %324 = OpLoad %6 %323
+        %325 = OpIEqual %40 %324 %28
+               OpSelectionMerge %341 None
+               OpBranchConditional %325 %326 %337
+        %337 = OpLabel
+        %340 = OpLoad %6 %323
+               OpBranch %343
+        %326 = OpLabel
+               OpStore %323 %27
+        %336 = OpAccessChain %8 %47 %27
+               OpStore %336 %1360
+               OpBranch %344
+        %341 = OpLabel
+               OpUnreachable
+        %300 = OpLabel
+        %302 = OpAccessChain %9 %47 %1212 %27
+        %303 = OpLoad %6 %302
+        %304 = OpIEqual %40 %303 %28
+               OpSelectionMerge %320 None
+               OpBranchConditional %304 %305 %316
+        %316 = OpLabel
+        %319 = OpLoad %6 %302
+               OpBranch %343
+        %305 = OpLabel
+               OpStore %302 %27
+        %315 = OpAccessChain %8 %47 %27
+               OpStore %315 %1360
+               OpBranch %344
+        %320 = OpLabel
+               OpUnreachable
+        %342 = OpLabel
+               OpUnreachable
+        %343 = OpLabel
+       %1342 = OpPhi %6 %319 %316 %340 %337
+               OpBranch %289
+        %344 = OpLabel
+       %1213 = OpPhi %40 %263 %289 %266 %305 %266 %326
+               OpSelectionMerge %346 None
+               OpBranchConditional %1213 %347 %346
+        %346 = OpLabel
+               OpBranch %347
+        %347 = OpLabel
+               OpSelectionMerge %424 None
+               OpSwitch %262 %365
+        %365 = OpLabel
+               OpBranch %366
+        %366 = OpLabel
+       %1220 = OpPhi %6 %24 %365 %1344 %420
+        %370 = OpSLessThanEqual %40 %1220 %30
+               OpLoopMerge %421 %420 None
+               OpBranchConditional %370 %371 %421
+        %371 = OpLabel
+        %374 = OpAccessChain %9 %47 %1220 %24
+        %375 = OpLoad %6 %374
+        %376 = OpSLessThanEqual %40 %158 %375
+               OpSelectionMerge %419 None
+               OpBranchConditional %376 %377 %398
+        %398 = OpLabel
+        %400 = OpAccessChain %9 %47 %1220 %30
+        %401 = OpLoad %6 %400
+        %402 = OpIEqual %40 %401 %28
+               OpSelectionMerge %418 None
+               OpBranchConditional %402 %403 %414
+        %414 = OpLabel
+        %417 = OpLoad %6 %400
+               OpBranch %420
+        %403 = OpLabel
+               OpStore %400 %30
+        %413 = OpAccessChain %8 %47 %30
+               OpStore %413 %1361
+               OpBranch %421
+        %418 = OpLabel
+               OpUnreachable
+        %377 = OpLabel
+        %379 = OpAccessChain %9 %47 %1220 %27
+        %380 = OpLoad %6 %379
+        %381 = OpIEqual %40 %380 %28
+               OpSelectionMerge %397 None
+               OpBranchConditional %381 %382 %393
+        %393 = OpLabel
+        %396 = OpLoad %6 %379
+               OpBranch %420
+        %382 = OpLabel
+               OpStore %379 %30
+        %392 = OpAccessChain %8 %47 %30
+               OpStore %392 %1361
+               OpBranch %421
+        %397 = OpLabel
+               OpUnreachable
+        %419 = OpLabel
+               OpUnreachable
+        %420 = OpLabel
+       %1344 = OpPhi %6 %396 %393 %417 %414
+               OpBranch %366
+        %421 = OpLabel
+       %1221 = OpPhi %40 %263 %366 %266 %382 %266 %403
+               OpSelectionMerge %423 None
+               OpBranchConditional %1221 %424 %423
+        %423 = OpLabel
+               OpBranch %424
+        %424 = OpLabel
+               OpSelectionMerge %501 None
+               OpSwitch %262 %442
+        %442 = OpLabel
+               OpBranch %443
+        %443 = OpLabel
+       %1228 = OpPhi %6 %24 %442 %1345 %497
+        %447 = OpSLessThanEqual %40 %1228 %1362
+               OpLoopMerge %498 %497 None
+               OpBranchConditional %447 %448 %498
+        %448 = OpLabel
+        %451 = OpAccessChain %9 %47 %1228 %24
+        %452 = OpLoad %6 %451
+        %453 = OpSLessThanEqual %40 %165 %452
+               OpSelectionMerge %496 None
+               OpBranchConditional %453 %454 %475
+        %475 = OpLabel
+        %477 = OpAccessChain %9 %47 %1228 %30
+        %478 = OpLoad %6 %477
+        %479 = OpIEqual %40 %478 %28
+               OpSelectionMerge %495 None
+               OpBranchConditional %479 %480 %491
+        %491 = OpLabel
+        %494 = OpLoad %6 %477
+               OpBranch %497
+        %480 = OpLabel
+               OpStore %477 %1362
+        %490 = OpAccessChain %8 %47 %1362
+               OpStore %490 %1363
+               OpBranch %498
+        %495 = OpLabel
+               OpUnreachable
+        %454 = OpLabel
+        %456 = OpAccessChain %9 %47 %1228 %27
+        %457 = OpLoad %6 %456
+        %458 = OpIEqual %40 %457 %28
+               OpSelectionMerge %474 None
+               OpBranchConditional %458 %459 %470
+        %470 = OpLabel
+        %473 = OpLoad %6 %456
+               OpBranch %497
+        %459 = OpLabel
+               OpStore %456 %1362
+        %469 = OpAccessChain %8 %47 %1362
+               OpStore %469 %1363
+               OpBranch %498
+        %474 = OpLabel
+               OpUnreachable
+        %496 = OpLabel
+               OpUnreachable
+        %497 = OpLabel
+       %1345 = OpPhi %6 %473 %470 %494 %491
+               OpBranch %443
+        %498 = OpLabel
+       %1229 = OpPhi %40 %263 %443 %266 %459 %266 %480
+               OpSelectionMerge %500 None
+               OpBranchConditional %1229 %501 %500
+        %500 = OpLabel
+               OpBranch %501
+        %501 = OpLabel
+               OpSelectionMerge %578 None
+               OpSwitch %262 %519
+        %519 = OpLabel
+               OpBranch %520
+        %520 = OpLabel
+       %1236 = OpPhi %6 %24 %519 %1346 %574
+        %524 = OpSLessThanEqual %40 %1236 %1364
+               OpLoopMerge %575 %574 None
+               OpBranchConditional %524 %525 %575
+        %525 = OpLabel
+        %528 = OpAccessChain %9 %47 %1236 %24
+        %529 = OpLoad %6 %528
+        %530 = OpSLessThanEqual %40 %172 %529
+               OpSelectionMerge %573 None
+               OpBranchConditional %530 %531 %552
+        %552 = OpLabel
+        %554 = OpAccessChain %9 %47 %1236 %30
+        %555 = OpLoad %6 %554
+        %556 = OpIEqual %40 %555 %28
+               OpSelectionMerge %572 None
+               OpBranchConditional %556 %557 %568
+        %568 = OpLabel
+        %571 = OpLoad %6 %554
+               OpBranch %574
+        %557 = OpLabel
+               OpStore %554 %1364
+        %567 = OpAccessChain %8 %47 %1364
+               OpStore %567 %1365
+               OpBranch %575
+        %572 = OpLabel
+               OpUnreachable
+        %531 = OpLabel
+        %533 = OpAccessChain %9 %47 %1236 %27
+        %534 = OpLoad %6 %533
+        %535 = OpIEqual %40 %534 %28
+               OpSelectionMerge %551 None
+               OpBranchConditional %535 %536 %547
+        %547 = OpLabel
+        %550 = OpLoad %6 %533
+               OpBranch %574
+        %536 = OpLabel
+               OpStore %533 %1364
+        %546 = OpAccessChain %8 %47 %1364
+               OpStore %546 %1365
+               OpBranch %575
+        %551 = OpLabel
+               OpUnreachable
+        %573 = OpLabel
+               OpUnreachable
+        %574 = OpLabel
+       %1346 = OpPhi %6 %550 %547 %571 %568
+               OpBranch %520
+        %575 = OpLabel
+       %1237 = OpPhi %40 %263 %520 %266 %536 %266 %557
+               OpSelectionMerge %577 None
+               OpBranchConditional %1237 %578 %577
+        %577 = OpLabel
+               OpBranch %578
+        %578 = OpLabel
+               OpSelectionMerge %655 None
+               OpSwitch %262 %596
+        %596 = OpLabel
+               OpBranch %597
+        %597 = OpLabel
+       %1244 = OpPhi %6 %24 %596 %1347 %651
+        %601 = OpSLessThanEqual %40 %1244 %151
+               OpLoopMerge %652 %651 None
+               OpBranchConditional %601 %602 %652
+        %602 = OpLabel
+        %605 = OpAccessChain %9 %47 %1244 %24
+        %606 = OpLoad %6 %605
+        %607 = OpSLessThanEqual %40 %179 %606
+               OpSelectionMerge %650 None
+               OpBranchConditional %607 %608 %629
+        %629 = OpLabel
+        %631 = OpAccessChain %9 %47 %1244 %30
+        %632 = OpLoad %6 %631
+        %633 = OpIEqual %40 %632 %28
+               OpSelectionMerge %649 None
+               OpBranchConditional %633 %634 %645
+        %645 = OpLabel
+        %648 = OpLoad %6 %631
+               OpBranch %651
+        %634 = OpLabel
+               OpStore %631 %151
+        %644 = OpAccessChain %8 %47 %151
+               OpStore %644 %1366
+               OpBranch %652
+        %649 = OpLabel
+               OpUnreachable
+        %608 = OpLabel
+        %610 = OpAccessChain %9 %47 %1244 %27
+        %611 = OpLoad %6 %610
+        %612 = OpIEqual %40 %611 %28
+               OpSelectionMerge %628 None
+               OpBranchConditional %612 %613 %624
+        %624 = OpLabel
+        %627 = OpLoad %6 %610
+               OpBranch %651
+        %613 = OpLabel
+               OpStore %610 %151
+        %623 = OpAccessChain %8 %47 %151
+               OpStore %623 %1366
+               OpBranch %652
+        %628 = OpLabel
+               OpUnreachable
+        %650 = OpLabel
+               OpUnreachable
+        %651 = OpLabel
+       %1347 = OpPhi %6 %627 %624 %648 %645
+               OpBranch %597
+        %652 = OpLabel
+       %1245 = OpPhi %40 %263 %597 %266 %613 %266 %634
+               OpSelectionMerge %654 None
+               OpBranchConditional %1245 %655 %654
+        %654 = OpLabel
+               OpBranch %655
+        %655 = OpLabel
+               OpSelectionMerge %732 None
+               OpSwitch %262 %673
+        %673 = OpLabel
+               OpBranch %674
+        %674 = OpLabel
+       %1252 = OpPhi %6 %24 %673 %1348 %728
+        %678 = OpSLessThanEqual %40 %1252 %192
+               OpLoopMerge %729 %728 None
+               OpBranchConditional %678 %679 %729
+        %679 = OpLabel
+        %682 = OpAccessChain %9 %47 %1252 %24
+        %683 = OpLoad %6 %682
+        %684 = OpSLessThanEqual %40 %30 %683
+               OpSelectionMerge %727 None
+               OpBranchConditional %684 %685 %706
+        %706 = OpLabel
+        %708 = OpAccessChain %9 %47 %1252 %30
+        %709 = OpLoad %6 %708
+        %710 = OpIEqual %40 %709 %28
+               OpSelectionMerge %726 None
+               OpBranchConditional %710 %711 %722
+        %722 = OpLabel
+        %725 = OpLoad %6 %708
+               OpBranch %728
+        %711 = OpLabel
+               OpStore %708 %192
+        %721 = OpAccessChain %8 %47 %192
+               OpStore %721 %1367
+               OpBranch %729
+        %726 = OpLabel
+               OpUnreachable
+        %685 = OpLabel
+        %687 = OpAccessChain %9 %47 %1252 %27
+        %688 = OpLoad %6 %687
+        %689 = OpIEqual %40 %688 %28
+               OpSelectionMerge %705 None
+               OpBranchConditional %689 %690 %701
+        %701 = OpLabel
+        %704 = OpLoad %6 %687
+               OpBranch %728
+        %690 = OpLabel
+               OpStore %687 %192
+        %700 = OpAccessChain %8 %47 %192
+               OpStore %700 %1367
+               OpBranch %729
+        %705 = OpLabel
+               OpUnreachable
+        %727 = OpLabel
+               OpUnreachable
+        %728 = OpLabel
+       %1348 = OpPhi %6 %704 %701 %725 %722
+               OpBranch %674
+        %729 = OpLabel
+       %1253 = OpPhi %40 %263 %674 %266 %690 %266 %711
+               OpSelectionMerge %731 None
+               OpBranchConditional %1253 %732 %731
+        %731 = OpLabel
+               OpBranch %732
+        %732 = OpLabel
+               OpSelectionMerge %809 None
+               OpSwitch %262 %750
+        %750 = OpLabel
+               OpBranch %751
+        %751 = OpLabel
+       %1260 = OpPhi %6 %24 %750 %1349 %805
+        %755 = OpSLessThanEqual %40 %1260 %172
+               OpLoopMerge %806 %805 None
+               OpBranchConditional %755 %756 %806
+        %756 = OpLabel
+        %759 = OpAccessChain %9 %47 %1260 %24
+        %760 = OpLoad %6 %759
+        %761 = OpSLessThanEqual %40 %192 %760
+               OpSelectionMerge %804 None
+               OpBranchConditional %761 %762 %783
+        %783 = OpLabel
+        %785 = OpAccessChain %9 %47 %1260 %30
+        %786 = OpLoad %6 %785
+        %787 = OpIEqual %40 %786 %28
+               OpSelectionMerge %803 None
+               OpBranchConditional %787 %788 %799
+        %799 = OpLabel
+        %802 = OpLoad %6 %785
+               OpBranch %805
+        %788 = OpLabel
+               OpStore %785 %172
+        %798 = OpAccessChain %8 %47 %172
+               OpStore %798 %1368
+               OpBranch %806
+        %803 = OpLabel
+               OpUnreachable
+        %762 = OpLabel
+        %764 = OpAccessChain %9 %47 %1260 %27
+        %765 = OpLoad %6 %764
+        %766 = OpIEqual %40 %765 %28
+               OpSelectionMerge %782 None
+               OpBranchConditional %766 %767 %778
+        %778 = OpLabel
+        %781 = OpLoad %6 %764
+               OpBranch %805
+        %767 = OpLabel
+               OpStore %764 %172
+        %777 = OpAccessChain %8 %47 %172
+               OpStore %777 %1368
+               OpBranch %806
+        %782 = OpLabel
+               OpUnreachable
+        %804 = OpLabel
+               OpUnreachable
+        %805 = OpLabel
+       %1349 = OpPhi %6 %781 %778 %802 %799
+               OpBranch %751
+        %806 = OpLabel
+       %1261 = OpPhi %40 %263 %751 %266 %767 %266 %788
+               OpSelectionMerge %808 None
+               OpBranchConditional %1261 %809 %808
+        %808 = OpLabel
+               OpBranch %809
+        %809 = OpLabel
+               OpSelectionMerge %886 None
+               OpSwitch %262 %827
+        %827 = OpLabel
+               OpBranch %828
+        %828 = OpLabel
+       %1268 = OpPhi %6 %24 %827 %1350 %882
+        %832 = OpSLessThanEqual %40 %1268 %179
+               OpLoopMerge %883 %882 None
+               OpBranchConditional %832 %833 %883
+        %833 = OpLabel
+        %836 = OpAccessChain %9 %47 %1268 %24
+        %837 = OpLoad %6 %836
+        %838 = OpSLessThanEqual %40 %199 %837
+               OpSelectionMerge %881 None
+               OpBranchConditional %838 %839 %860
+        %860 = OpLabel
+        %862 = OpAccessChain %9 %47 %1268 %30
+        %863 = OpLoad %6 %862
+        %864 = OpIEqual %40 %863 %28
+               OpSelectionMerge %880 None
+               OpBranchConditional %864 %865 %876
+        %876 = OpLabel
+        %879 = OpLoad %6 %862
+               OpBranch %882
+        %865 = OpLabel
+               OpStore %862 %179
+        %875 = OpAccessChain %8 %47 %179
+               OpStore %875 %1369
+               OpBranch %883
+        %880 = OpLabel
+               OpUnreachable
+        %839 = OpLabel
+        %841 = OpAccessChain %9 %47 %1268 %27
+        %842 = OpLoad %6 %841
+        %843 = OpIEqual %40 %842 %28
+               OpSelectionMerge %859 None
+               OpBranchConditional %843 %844 %855
+        %855 = OpLabel
+        %858 = OpLoad %6 %841
+               OpBranch %882
+        %844 = OpLabel
+               OpStore %841 %179
+        %854 = OpAccessChain %8 %47 %179
+               OpStore %854 %1369
+               OpBranch %883
+        %859 = OpLabel
+               OpUnreachable
+        %881 = OpLabel
+               OpUnreachable
+        %882 = OpLabel
+       %1350 = OpPhi %6 %858 %855 %879 %876
+               OpBranch %828
+        %883 = OpLabel
+       %1269 = OpPhi %40 %263 %828 %266 %844 %266 %865
+               OpSelectionMerge %885 None
+               OpBranchConditional %1269 %886 %885
+        %885 = OpLabel
+               OpBranch %886
+        %886 = OpLabel
+               OpSelectionMerge %963 None
+               OpSwitch %262 %904
+        %904 = OpLabel
+               OpBranch %905
+        %905 = OpLabel
+       %1276 = OpPhi %6 %24 %904 %1351 %959
+        %909 = OpSLessThanEqual %40 %1276 %141
+               OpLoopMerge %960 %959 None
+               OpBranchConditional %909 %910 %960
+        %910 = OpLabel
+        %913 = OpAccessChain %9 %47 %1276 %24
+        %914 = OpLoad %6 %913
+        %915 = OpSLessThanEqual %40 %206 %914
+               OpSelectionMerge %958 None
+               OpBranchConditional %915 %916 %937
+        %937 = OpLabel
+        %939 = OpAccessChain %9 %47 %1276 %30
+        %940 = OpLoad %6 %939
+        %941 = OpIEqual %40 %940 %28
+               OpSelectionMerge %957 None
+               OpBranchConditional %941 %942 %953
+        %953 = OpLabel
+        %956 = OpLoad %6 %939
+               OpBranch %959
+        %942 = OpLabel
+               OpStore %939 %141
+        %952 = OpAccessChain %8 %47 %141
+               OpStore %952 %1370
+               OpBranch %960
+        %957 = OpLabel
+               OpUnreachable
+        %916 = OpLabel
+        %918 = OpAccessChain %9 %47 %1276 %27
+        %919 = OpLoad %6 %918
+        %920 = OpIEqual %40 %919 %28
+               OpSelectionMerge %936 None
+               OpBranchConditional %920 %921 %932
+        %932 = OpLabel
+        %935 = OpLoad %6 %918
+               OpBranch %959
+        %921 = OpLabel
+               OpStore %918 %141
+        %931 = OpAccessChain %8 %47 %141
+               OpStore %931 %1370
+               OpBranch %960
+        %936 = OpLabel
+               OpUnreachable
+        %958 = OpLabel
+               OpUnreachable
+        %959 = OpLabel
+       %1351 = OpPhi %6 %935 %932 %956 %953
+               OpBranch %905
+        %960 = OpLabel
+       %1277 = OpPhi %40 %263 %905 %266 %921 %266 %942
+               OpSelectionMerge %962 None
+               OpBranchConditional %1277 %963 %962
+        %962 = OpLabel
+               OpBranch %963
+        %963 = OpLabel
+               OpBranch %213
+        %213 = OpLabel
+       %1290 = OpPhi %6 %1318 %963 %1287 %216
+       %1281 = OpPhi %6 %24 %963 %1352 %216
+       %1280 = OpPhi %6 %24 %963 %246 %216
+        %220 = OpSLessThan %40 %1280 %219
+               OpLoopMerge %215 %216 None
+               OpBranchConditional %220 %214 %215
+        %214 = OpLabel
+               OpSelectionMerge %1013 None
+               OpSwitch %262 %981
+        %981 = OpLabel
+               OpBranch %982
+        %982 = OpLabel
+       %1282 = OpPhi %6 %24 %981 %1371 %1009
+        %985 = OpINotEqual %40 %1282 %28
+               OpLoopMerge %1010 %1009 None
+               OpBranchConditional %985 %986 %1010
+        %986 = OpLabel
+        %988 = OpAccessChain %8 %47 %1282
+        %989 = OpLoad %7 %988
+       %1019 = OpCompositeExtract %6 %989 0
+       %1020 = OpCompositeExtract %6 %989 1
+       %1021 = OpCompositeExtract %6 %989 2
+        %993 = OpIEqual %40 %1019 %1280
+               OpSelectionMerge %996 None
+               OpBranchConditional %993 %994 %996
+        %994 = OpLabel
+               OpBranch %1010
+        %996 = OpLabel
+       %1000 = OpSGreaterThan %40 %1280 %1019
+       %1371 = OpSelect %6 %1000 %1021 %1020
+               OpBranch %1009
+       %1009 = OpLabel
+               OpBranch %982
+       %1010 = OpLabel
+       %1288 = OpPhi %6 %1290 %982 %1280 %994
+       %1284 = OpPhi %40 %263 %982 %266 %994
+               OpSelectionMerge %1012 None
+               OpBranchConditional %1284 %1013 %1012
+       %1012 = OpLabel
+               OpBranch %1013
+       %1013 = OpLabel
+       %1287 = OpPhi %6 %1288 %1010 %28 %1012
+               OpSelectionMerge %228 None
+               OpSwitch %1280 %227 9 %226 5 %226 12 %226 15 %226 7 %226 8 %226 2 %226 6 %226 17 %226 13 %226
+        %226 = OpLabel
+        %231 = OpIEqual %40 %1287 %1280
+               OpSelectionMerge %233 None
+               OpBranchConditional %231 %232 %233
+        %232 = OpLabel
+        %235 = OpIAdd %6 %1281 %27
+               OpBranch %233
+        %233 = OpLabel
+       %1354 = OpPhi %6 %1281 %226 %235 %232
+               OpBranch %228
+        %227 = OpLabel
+        %238 = OpIEqual %40 %1287 %28
+               OpSelectionMerge %240 None
+               OpBranchConditional %238 %239 %240
+        %239 = OpLabel
+        %242 = OpIAdd %6 %1281 %27
+               OpBranch %240
+        %240 = OpLabel
+       %1353 = OpPhi %6 %1281 %227 %242 %239
+               OpBranch %228
+        %228 = OpLabel
+       %1352 = OpPhi %6 %1353 %240 %1354 %233
+               OpBranch %216
+        %216 = OpLabel
+        %246 = OpIAdd %6 %1280 %27
+               OpBranch %213
+        %215 = OpLabel
+        %248 = OpIEqual %40 %1281 %219
+               OpSelectionMerge %250 None
+               OpBranchConditional %248 %249 %258
+        %258 = OpLabel
+               OpStore %254 %259
+               OpBranch %250
+        %249 = OpLabel
+               OpStore %254 %257
+               OpBranch %250
+        %250 = OpLabel
+               OpReturn
+               OpFunctionEnd
+END
+
+
+BUFFER reference_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics reference_pipeline
+  ATTACH reference_vertex_shader
+  ATTACH reference_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER reference_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR reference_pipeline 0 0 0 255
+
+CLEAR reference_pipeline
+RUN reference_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch;
+# };
+# layout(location = 0) out vec4 _GLF_color;
+#
+# struct BST
+# {
+#     int data;
+#     int leftIndex;
+#     int rightIndex;
+# };
+#
+# BST tree[10];
+#
+# void makeTreeNode(inout BST tree, int data)
+# {
+#     tree.data = data;
+#     tree.leftIndex = -1;
+#     tree.rightIndex = -1;
+# }
+# void insert(int treeIndex, int data)
+# {
+#     int baseIndex = 0;
+#     while (baseIndex <= treeIndex)
+#     {
+#         if (data <= tree[baseIndex].data)
+#         {
+#             if (tree[baseIndex].leftIndex == -1)
+#             {
+#                 // Always false.
+#                 if ((injectionSwitch.y < injectionSwitch.x))
+#                 {
+#                     do
+#                     {
+#                         // This is never reached.
+#                         discard;
+#                     }
+#                     // Always false.
+#                     while (injectionSwitch.y < injectionSwitch.x);
+#                 }
+#                 tree[baseIndex].leftIndex = treeIndex;
+#                 makeTreeNode(tree[treeIndex], data);
+#                 // Iterates once.
+#                 for (int int_i = 0; int_i < int((injectionSwitch.y)); int_i++)
+#                 {
+#                     return;
+#                 }
+#             }
+#             else
+#             {
+#                 baseIndex = tree[baseIndex].leftIndex;
+#                 continue;
+#             }
+#         }
+#         else
+#         {
+#             if (tree[baseIndex].rightIndex == -1)
+#             {
+#                 tree[baseIndex].rightIndex = treeIndex;
+#                 makeTreeNode(tree[treeIndex], data);
+#                 return;
+#             }
+#             else
+#             {
+#                 baseIndex = tree[baseIndex].rightIndex;
+#                 continue;
+#             }
+#         }
+#     }
+# }
+# int search(int target)
+# {
+#     BST currentNode;
+#     int index = 0;
+#     while (index != -1)
+#     {
+#         currentNode = tree[index];
+#         if (currentNode.data == target)
+#         {
+#             return target;
+#         }
+#         index = target > currentNode.data ? currentNode.rightIndex : currentNode.leftIndex;
+#     }
+#     return -1;
+# }
+# void main()
+# {
+#     int treeIndex = 0;
+#     makeTreeNode(tree[0], 9);
+#     treeIndex++;
+#     insert(treeIndex, 5);
+#     treeIndex++;
+#     // gl_FragCoord.y < 0.0 == false
+#     // Iterates once,
+#     for (int int_i = 0; (gl_FragCoord.y < 0.0) || (int_i != int(injectionSwitch.y)); int_i++)
+#     {
+#         insert(treeIndex, 12);
+#     }
+#     treeIndex++;
+#     insert(treeIndex, 15);
+#     treeIndex++;
+#     insert(treeIndex, 7);
+#     treeIndex++;
+#     insert(treeIndex, 8);
+#     treeIndex++;
+#     insert(treeIndex, 2);
+#     treeIndex++;
+#     insert(treeIndex, 6);
+#     treeIndex++;
+#     insert(treeIndex, 17);
+#     treeIndex++;
+#     insert(treeIndex, 13);
+#     int count = 0;
+#     for (int i = 0; i < 20; i++)
+#     {
+#         int result = search(i);
+#         switch (i)
+#         {
+#         case 9:
+#         case 5:
+#         case 12:
+#         case 15:
+#         case 7:
+#         case 8:
+#         case 2:
+#         case 6:
+#         case 17:
+#         case 13:
+#             if (result == i)
+#             {
+#                 count++;
+#             }
+#             break;
+#         default:
+#             if (result == -1)
+#             {
+#                 count++;
+#             }
+#             break;
+#         }
+#     }
+#     if (count == 20)
+#     {
+#         _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#     }
+#     else
+#     {
+#         _GLF_color = vec4(0.0, 0.0, 1.0, 1.0);
+#     }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 1740
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %204 %315
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %7 "BST"
+               OpMemberName %7 0 "data"
+               OpMemberName %7 1 "leftIndex"
+               OpMemberName %7 2 "rightIndex"
+               OpName %47 "tree"
+               OpName %63 "buf0"
+               OpMemberName %63 0 "injectionSwitch"
+               OpName %65 ""
+               OpName %204 "gl_FragCoord"
+               OpName %315 "_GLF_color"
+               OpMemberDecorate %63 0 Offset 0
+               OpDecorate %63 Block
+               OpDecorate %65 DescriptorSet 0
+               OpDecorate %65 Binding 0
+               OpDecorate %204 BuiltIn FragCoord
+               OpDecorate %315 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypeStruct %6 %6 %6
+          %8 = OpTypePointer Function %7
+          %9 = OpTypePointer Function %6
+         %24 = OpConstant %6 0
+         %27 = OpConstant %6 1
+         %28 = OpConstant %6 -1
+         %30 = OpConstant %6 2
+         %40 = OpTypeBool
+         %43 = OpTypeInt 32 0
+         %44 = OpConstant %43 10
+         %45 = OpTypeArray %7 %44
+         %61 = OpTypeFloat 32
+         %62 = OpTypeVector %61 2
+         %63 = OpTypeStruct %62
+         %64 = OpTypePointer Uniform %63
+         %65 = OpVariable %64 Uniform
+         %66 = OpConstant %43 1
+         %67 = OpTypePointer Uniform %61
+         %70 = OpConstant %43 0
+        %179 = OpConstant %6 9
+        %189 = OpConstant %6 5
+        %202 = OpTypeVector %61 4
+        %203 = OpTypePointer Input %202
+        %204 = OpVariable %203 Input
+        %205 = OpTypePointer Input %61
+        %208 = OpConstant %61 0
+        %219 = OpConstant %6 12
+        %228 = OpConstant %6 15
+        %235 = OpConstant %6 7
+        %242 = OpConstant %6 8
+        %255 = OpConstant %6 6
+        %262 = OpConstant %6 17
+        %269 = OpConstant %6 13
+        %282 = OpConstant %6 20
+        %314 = OpTypePointer Output %202
+        %315 = OpVariable %314 Output
+        %316 = OpConstant %61 1
+        %317 = OpConstantComposite %202 %316 %208 %208 %316
+        %319 = OpConstantComposite %202 %208 %208 %316 %316
+        %322 = OpConstantFalse %40
+        %325 = OpConstantTrue %40
+       %1301 = OpTypePointer Function %45
+       %1620 = OpUndef %6
+       %1727 = OpConstantComposite %7 %179 %28 %28
+       %1728 = OpConstantComposite %7 %189 %28 %28
+       %1729 = OpConstant %6 3
+       %1730 = OpConstantComposite %7 %219 %28 %28
+       %1731 = OpConstantComposite %7 %228 %28 %28
+       %1732 = OpConstant %6 4
+       %1733 = OpConstantComposite %7 %235 %28 %28
+       %1734 = OpConstantComposite %7 %242 %28 %28
+       %1735 = OpConstantComposite %7 %30 %28 %28
+       %1736 = OpConstantComposite %7 %255 %28 %28
+       %1737 = OpConstantComposite %7 %262 %28 %28
+       %1738 = OpConstantComposite %7 %269 %28 %28
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %47 = OpVariable %1301 Function
+        %186 = OpAccessChain %8 %47 %24
+               OpStore %186 %1727
+               OpSelectionMerge %432 None
+               OpSwitch %70 %350
+        %350 = OpLabel
+               OpBranch %351
+        %351 = OpLabel
+       %1501 = OpPhi %40 %322 %350 %1674 %428
+       %1498 = OpPhi %6 %24 %350 %1671 %428
+        %355 = OpSLessThanEqual %40 %1498 %27
+               OpLoopMerge %429 %428 None
+               OpBranchConditional %355 %356 %429
+        %356 = OpLabel
+        %359 = OpAccessChain %9 %47 %1498 %24
+        %360 = OpLoad %6 %359
+        %361 = OpSLessThanEqual %40 %189 %360
+               OpSelectionMerge %427 None
+               OpBranchConditional %361 %362 %406
+        %406 = OpLabel
+        %408 = OpAccessChain %9 %47 %1498 %30
+        %409 = OpLoad %6 %408
+        %410 = OpIEqual %40 %409 %28
+               OpSelectionMerge %426 None
+               OpBranchConditional %410 %411 %422
+        %422 = OpLabel
+        %425 = OpLoad %6 %408
+               OpBranch %428
+        %411 = OpLabel
+               OpStore %408 %27
+        %421 = OpAccessChain %8 %47 %27
+               OpStore %421 %1728
+               OpBranch %429
+        %426 = OpLabel
+               OpUnreachable
+        %362 = OpLabel
+        %364 = OpAccessChain %9 %47 %1498 %27
+        %365 = OpLoad %6 %364
+        %366 = OpIEqual %40 %365 %28
+               OpSelectionMerge %405 None
+               OpBranchConditional %366 %367 %401
+        %401 = OpLabel
+        %404 = OpLoad %6 %364
+               OpBranch %428
+        %367 = OpLabel
+        %368 = OpAccessChain %67 %65 %24 %66
+        %369 = OpLoad %61 %368
+        %370 = OpAccessChain %67 %65 %24 %70
+        %371 = OpLoad %61 %370
+        %372 = OpFOrdLessThan %40 %369 %371
+               OpSelectionMerge %378 None
+               OpBranchConditional %372 %373 %378
+        %373 = OpLabel
+               OpBranch %374
+        %374 = OpLabel
+               OpLoopMerge %377 %376 None
+               OpBranch %375
+        %375 = OpLabel
+               OpKill
+        %376 = OpLabel
+               OpBranch %374
+        %377 = OpLabel
+               OpUnreachable
+        %378 = OpLabel
+               OpStore %364 %27
+        %388 = OpAccessChain %8 %47 %27
+               OpStore %388 %1728
+               OpBranch %389
+        %389 = OpLabel
+        %394 = OpConvertFToS %6 %369
+        %395 = OpSLessThan %40 %24 %394
+               OpLoopMerge %398 %397 None
+               OpBranchConditional %395 %396 %398
+        %396 = OpLabel
+               OpBranch %398
+        %397 = OpLabel
+               OpBranch %389
+        %398 = OpLabel
+       %1499 = OpPhi %40 %1501 %389 %325 %396
+               OpSelectionMerge %400 None
+               OpBranchConditional %1499 %429 %400
+        %400 = OpLabel
+               OpBranch %405
+        %405 = OpLabel
+               OpBranch %427
+        %427 = OpLabel
+               OpBranch %428
+        %428 = OpLabel
+       %1674 = OpPhi %40 %1501 %401 %1501 %422 %1499 %427
+       %1671 = OpPhi %6 %404 %401 %425 %422 %1498 %427
+               OpBranch %351
+        %429 = OpLabel
+       %1502 = OpPhi %40 %1501 %351 %1499 %398 %325 %411
+               OpSelectionMerge %431 None
+               OpBranchConditional %1502 %432 %431
+        %431 = OpLabel
+               OpBranch %432
+        %432 = OpLabel
+               OpBranch %197
+        %197 = OpLabel
+       %1509 = OpPhi %6 %24 %432 %225 %200
+               OpLoopMerge %199 %200 None
+               OpBranch %201
+        %201 = OpLabel
+        %206 = OpAccessChain %205 %204 %66
+        %207 = OpLoad %61 %206
+        %209 = OpFOrdLessThan %40 %207 %208
+        %210 = OpLogicalNot %40 %209
+               OpSelectionMerge %212 None
+               OpBranchConditional %210 %211 %212
+        %211 = OpLabel
+        %214 = OpAccessChain %67 %65 %24 %66
+        %215 = OpLoad %61 %214
+        %216 = OpConvertFToS %6 %215
+        %217 = OpINotEqual %40 %1509 %216
+               OpBranch %212
+        %212 = OpLabel
+        %218 = OpPhi %40 %209 %201 %217 %211
+               OpBranchConditional %218 %198 %199
+        %198 = OpLabel
+               OpSelectionMerge %534 None
+               OpSwitch %70 %452
+        %452 = OpLabel
+               OpBranch %453
+        %453 = OpLabel
+       %1662 = OpPhi %40 %322 %452 %1726 %530
+       %1659 = OpPhi %6 %24 %452 %1723 %530
+        %457 = OpSLessThanEqual %40 %1659 %30
+               OpLoopMerge %531 %530 None
+               OpBranchConditional %457 %458 %531
+        %458 = OpLabel
+        %461 = OpAccessChain %9 %47 %1659 %24
+        %462 = OpLoad %6 %461
+        %463 = OpSLessThanEqual %40 %219 %462
+               OpSelectionMerge %529 None
+               OpBranchConditional %463 %464 %508
+        %508 = OpLabel
+        %510 = OpAccessChain %9 %47 %1659 %30
+        %511 = OpLoad %6 %510
+        %512 = OpIEqual %40 %511 %28
+               OpSelectionMerge %528 None
+               OpBranchConditional %512 %513 %524
+        %524 = OpLabel
+        %527 = OpLoad %6 %510
+               OpBranch %530
+        %513 = OpLabel
+               OpStore %510 %30
+        %523 = OpAccessChain %8 %47 %30
+               OpStore %523 %1730
+               OpBranch %531
+        %528 = OpLabel
+               OpUnreachable
+        %464 = OpLabel
+        %466 = OpAccessChain %9 %47 %1659 %27
+        %467 = OpLoad %6 %466
+        %468 = OpIEqual %40 %467 %28
+               OpSelectionMerge %507 None
+               OpBranchConditional %468 %469 %503
+        %503 = OpLabel
+        %506 = OpLoad %6 %466
+               OpBranch %530
+        %469 = OpLabel
+        %470 = OpAccessChain %67 %65 %24 %66
+        %471 = OpLoad %61 %470
+        %472 = OpAccessChain %67 %65 %24 %70
+        %473 = OpLoad %61 %472
+        %474 = OpFOrdLessThan %40 %471 %473
+               OpSelectionMerge %480 None
+               OpBranchConditional %474 %475 %480
+        %475 = OpLabel
+               OpBranch %476
+        %476 = OpLabel
+               OpLoopMerge %479 %478 None
+               OpBranch %477
+        %477 = OpLabel
+               OpKill
+        %478 = OpLabel
+               OpBranch %476
+        %479 = OpLabel
+               OpUnreachable
+        %480 = OpLabel
+               OpStore %466 %30
+        %490 = OpAccessChain %8 %47 %30
+               OpStore %490 %1730
+               OpBranch %491
+        %491 = OpLabel
+        %496 = OpConvertFToS %6 %471
+        %497 = OpSLessThan %40 %24 %496
+               OpLoopMerge %500 %499 None
+               OpBranchConditional %497 %498 %500
+        %498 = OpLabel
+               OpBranch %500
+        %499 = OpLabel
+               OpBranch %491
+        %500 = OpLabel
+       %1660 = OpPhi %40 %1662 %491 %325 %498
+               OpSelectionMerge %502 None
+               OpBranchConditional %1660 %531 %502
+        %502 = OpLabel
+               OpBranch %507
+        %507 = OpLabel
+               OpBranch %529
+        %529 = OpLabel
+               OpBranch %530
+        %530 = OpLabel
+       %1726 = OpPhi %40 %1662 %503 %1662 %524 %1660 %529
+       %1723 = OpPhi %6 %506 %503 %527 %524 %1659 %529
+               OpBranch %453
+        %531 = OpLabel
+       %1663 = OpPhi %40 %1662 %453 %1660 %500 %325 %513
+               OpSelectionMerge %533 None
+               OpBranchConditional %1663 %534 %533
+        %533 = OpLabel
+               OpBranch %534
+        %534 = OpLabel
+               OpBranch %200
+        %200 = OpLabel
+        %225 = OpIAdd %6 %1509 %27
+               OpBranch %197
+        %199 = OpLabel
+               OpSelectionMerge %636 None
+               OpSwitch %70 %554
+        %554 = OpLabel
+               OpBranch %555
+        %555 = OpLabel
+       %1515 = OpPhi %40 %322 %554 %1685 %632
+       %1512 = OpPhi %6 %24 %554 %1682 %632
+        %559 = OpSLessThanEqual %40 %1512 %1729
+               OpLoopMerge %633 %632 None
+               OpBranchConditional %559 %560 %633
+        %560 = OpLabel
+        %563 = OpAccessChain %9 %47 %1512 %24
+        %564 = OpLoad %6 %563
+        %565 = OpSLessThanEqual %40 %228 %564
+               OpSelectionMerge %631 None
+               OpBranchConditional %565 %566 %610
+        %610 = OpLabel
+        %612 = OpAccessChain %9 %47 %1512 %30
+        %613 = OpLoad %6 %612
+        %614 = OpIEqual %40 %613 %28
+               OpSelectionMerge %630 None
+               OpBranchConditional %614 %615 %626
+        %626 = OpLabel
+        %629 = OpLoad %6 %612
+               OpBranch %632
+        %615 = OpLabel
+               OpStore %612 %1729
+        %625 = OpAccessChain %8 %47 %1729
+               OpStore %625 %1731
+               OpBranch %633
+        %630 = OpLabel
+               OpUnreachable
+        %566 = OpLabel
+        %568 = OpAccessChain %9 %47 %1512 %27
+        %569 = OpLoad %6 %568
+        %570 = OpIEqual %40 %569 %28
+               OpSelectionMerge %609 None
+               OpBranchConditional %570 %571 %605
+        %605 = OpLabel
+        %608 = OpLoad %6 %568
+               OpBranch %632
+        %571 = OpLabel
+        %572 = OpAccessChain %67 %65 %24 %66
+        %573 = OpLoad %61 %572
+        %574 = OpAccessChain %67 %65 %24 %70
+        %575 = OpLoad %61 %574
+        %576 = OpFOrdLessThan %40 %573 %575
+               OpSelectionMerge %582 None
+               OpBranchConditional %576 %577 %582
+        %577 = OpLabel
+               OpBranch %578
+        %578 = OpLabel
+               OpLoopMerge %581 %580 None
+               OpBranch %579
+        %579 = OpLabel
+               OpKill
+        %580 = OpLabel
+               OpBranch %578
+        %581 = OpLabel
+               OpUnreachable
+        %582 = OpLabel
+               OpStore %568 %1729
+        %592 = OpAccessChain %8 %47 %1729
+               OpStore %592 %1731
+               OpBranch %593
+        %593 = OpLabel
+        %598 = OpConvertFToS %6 %573
+        %599 = OpSLessThan %40 %24 %598
+               OpLoopMerge %602 %601 None
+               OpBranchConditional %599 %600 %602
+        %600 = OpLabel
+               OpBranch %602
+        %601 = OpLabel
+               OpBranch %593
+        %602 = OpLabel
+       %1513 = OpPhi %40 %1515 %593 %325 %600
+               OpSelectionMerge %604 None
+               OpBranchConditional %1513 %633 %604
+        %604 = OpLabel
+               OpBranch %609
+        %609 = OpLabel
+               OpBranch %631
+        %631 = OpLabel
+               OpBranch %632
+        %632 = OpLabel
+       %1685 = OpPhi %40 %1515 %605 %1515 %626 %1513 %631
+       %1682 = OpPhi %6 %608 %605 %629 %626 %1512 %631
+               OpBranch %555
+        %633 = OpLabel
+       %1516 = OpPhi %40 %1515 %555 %1513 %602 %325 %615
+               OpSelectionMerge %635 None
+               OpBranchConditional %1516 %636 %635
+        %635 = OpLabel
+               OpBranch %636
+        %636 = OpLabel
+               OpSelectionMerge %738 None
+               OpSwitch %70 %656
+        %656 = OpLabel
+               OpBranch %657
+        %657 = OpLabel
+       %1526 = OpPhi %40 %322 %656 %1689 %734
+       %1523 = OpPhi %6 %24 %656 %1686 %734
+        %661 = OpSLessThanEqual %40 %1523 %1732
+               OpLoopMerge %735 %734 None
+               OpBranchConditional %661 %662 %735
+        %662 = OpLabel
+        %665 = OpAccessChain %9 %47 %1523 %24
+        %666 = OpLoad %6 %665
+        %667 = OpSLessThanEqual %40 %235 %666
+               OpSelectionMerge %733 None
+               OpBranchConditional %667 %668 %712
+        %712 = OpLabel
+        %714 = OpAccessChain %9 %47 %1523 %30
+        %715 = OpLoad %6 %714
+        %716 = OpIEqual %40 %715 %28
+               OpSelectionMerge %732 None
+               OpBranchConditional %716 %717 %728
+        %728 = OpLabel
+        %731 = OpLoad %6 %714
+               OpBranch %734
+        %717 = OpLabel
+               OpStore %714 %1732
+        %727 = OpAccessChain %8 %47 %1732
+               OpStore %727 %1733
+               OpBranch %735
+        %732 = OpLabel
+               OpUnreachable
+        %668 = OpLabel
+        %670 = OpAccessChain %9 %47 %1523 %27
+        %671 = OpLoad %6 %670
+        %672 = OpIEqual %40 %671 %28
+               OpSelectionMerge %711 None
+               OpBranchConditional %672 %673 %707
+        %707 = OpLabel
+        %710 = OpLoad %6 %670
+               OpBranch %734
+        %673 = OpLabel
+        %674 = OpAccessChain %67 %65 %24 %66
+        %675 = OpLoad %61 %674
+        %676 = OpAccessChain %67 %65 %24 %70
+        %677 = OpLoad %61 %676
+        %678 = OpFOrdLessThan %40 %675 %677
+               OpSelectionMerge %684 None
+               OpBranchConditional %678 %679 %684
+        %679 = OpLabel
+               OpBranch %680
+        %680 = OpLabel
+               OpLoopMerge %683 %682 None
+               OpBranch %681
+        %681 = OpLabel
+               OpKill
+        %682 = OpLabel
+               OpBranch %680
+        %683 = OpLabel
+               OpUnreachable
+        %684 = OpLabel
+               OpStore %670 %1732
+        %694 = OpAccessChain %8 %47 %1732
+               OpStore %694 %1733
+               OpBranch %695
+        %695 = OpLabel
+        %700 = OpConvertFToS %6 %675
+        %701 = OpSLessThan %40 %24 %700
+               OpLoopMerge %704 %703 None
+               OpBranchConditional %701 %702 %704
+        %702 = OpLabel
+               OpBranch %704
+        %703 = OpLabel
+               OpBranch %695
+        %704 = OpLabel
+       %1524 = OpPhi %40 %1526 %695 %325 %702
+               OpSelectionMerge %706 None
+               OpBranchConditional %1524 %735 %706
+        %706 = OpLabel
+               OpBranch %711
+        %711 = OpLabel
+               OpBranch %733
+        %733 = OpLabel
+               OpBranch %734
+        %734 = OpLabel
+       %1689 = OpPhi %40 %1526 %707 %1526 %728 %1524 %733
+       %1686 = OpPhi %6 %710 %707 %731 %728 %1523 %733
+               OpBranch %657
+        %735 = OpLabel
+       %1527 = OpPhi %40 %1526 %657 %1524 %704 %325 %717
+               OpSelectionMerge %737 None
+               OpBranchConditional %1527 %738 %737
+        %737 = OpLabel
+               OpBranch %738
+        %738 = OpLabel
+               OpSelectionMerge %840 None
+               OpSwitch %70 %758
+        %758 = OpLabel
+               OpBranch %759
+        %759 = OpLabel
+       %1537 = OpPhi %40 %322 %758 %1693 %836
+       %1534 = OpPhi %6 %24 %758 %1690 %836
+        %763 = OpSLessThanEqual %40 %1534 %189
+               OpLoopMerge %837 %836 None
+               OpBranchConditional %763 %764 %837
+        %764 = OpLabel
+        %767 = OpAccessChain %9 %47 %1534 %24
+        %768 = OpLoad %6 %767
+        %769 = OpSLessThanEqual %40 %242 %768
+               OpSelectionMerge %835 None
+               OpBranchConditional %769 %770 %814
+        %814 = OpLabel
+        %816 = OpAccessChain %9 %47 %1534 %30
+        %817 = OpLoad %6 %816
+        %818 = OpIEqual %40 %817 %28
+               OpSelectionMerge %834 None
+               OpBranchConditional %818 %819 %830
+        %830 = OpLabel
+        %833 = OpLoad %6 %816
+               OpBranch %836
+        %819 = OpLabel
+               OpStore %816 %189
+        %829 = OpAccessChain %8 %47 %189
+               OpStore %829 %1734
+               OpBranch %837
+        %834 = OpLabel
+               OpUnreachable
+        %770 = OpLabel
+        %772 = OpAccessChain %9 %47 %1534 %27
+        %773 = OpLoad %6 %772
+        %774 = OpIEqual %40 %773 %28
+               OpSelectionMerge %813 None
+               OpBranchConditional %774 %775 %809
+        %809 = OpLabel
+        %812 = OpLoad %6 %772
+               OpBranch %836
+        %775 = OpLabel
+        %776 = OpAccessChain %67 %65 %24 %66
+        %777 = OpLoad %61 %776
+        %778 = OpAccessChain %67 %65 %24 %70
+        %779 = OpLoad %61 %778
+        %780 = OpFOrdLessThan %40 %777 %779
+               OpSelectionMerge %786 None
+               OpBranchConditional %780 %781 %786
+        %781 = OpLabel
+               OpBranch %782
+        %782 = OpLabel
+               OpLoopMerge %785 %784 None
+               OpBranch %783
+        %783 = OpLabel
+               OpKill
+        %784 = OpLabel
+               OpBranch %782
+        %785 = OpLabel
+               OpUnreachable
+        %786 = OpLabel
+               OpStore %772 %189
+        %796 = OpAccessChain %8 %47 %189
+               OpStore %796 %1734
+               OpBranch %797
+        %797 = OpLabel
+        %802 = OpConvertFToS %6 %777
+        %803 = OpSLessThan %40 %24 %802
+               OpLoopMerge %806 %805 None
+               OpBranchConditional %803 %804 %806
+        %804 = OpLabel
+               OpBranch %806
+        %805 = OpLabel
+               OpBranch %797
+        %806 = OpLabel
+       %1535 = OpPhi %40 %1537 %797 %325 %804
+               OpSelectionMerge %808 None
+               OpBranchConditional %1535 %837 %808
+        %808 = OpLabel
+               OpBranch %813
+        %813 = OpLabel
+               OpBranch %835
+        %835 = OpLabel
+               OpBranch %836
+        %836 = OpLabel
+       %1693 = OpPhi %40 %1537 %809 %1537 %830 %1535 %835
+       %1690 = OpPhi %6 %812 %809 %833 %830 %1534 %835
+               OpBranch %759
+        %837 = OpLabel
+       %1538 = OpPhi %40 %1537 %759 %1535 %806 %325 %819
+               OpSelectionMerge %839 None
+               OpBranchConditional %1538 %840 %839
+        %839 = OpLabel
+               OpBranch %840
+        %840 = OpLabel
+               OpSelectionMerge %942 None
+               OpSwitch %70 %860
+        %860 = OpLabel
+               OpBranch %861
+        %861 = OpLabel
+       %1548 = OpPhi %40 %322 %860 %1697 %938
+       %1545 = OpPhi %6 %24 %860 %1694 %938
+        %865 = OpSLessThanEqual %40 %1545 %255
+               OpLoopMerge %939 %938 None
+               OpBranchConditional %865 %866 %939
+        %866 = OpLabel
+        %869 = OpAccessChain %9 %47 %1545 %24
+        %870 = OpLoad %6 %869
+        %871 = OpSLessThanEqual %40 %30 %870
+               OpSelectionMerge %937 None
+               OpBranchConditional %871 %872 %916
+        %916 = OpLabel
+        %918 = OpAccessChain %9 %47 %1545 %30
+        %919 = OpLoad %6 %918
+        %920 = OpIEqual %40 %919 %28
+               OpSelectionMerge %936 None
+               OpBranchConditional %920 %921 %932
+        %932 = OpLabel
+        %935 = OpLoad %6 %918
+               OpBranch %938
+        %921 = OpLabel
+               OpStore %918 %255
+        %931 = OpAccessChain %8 %47 %255
+               OpStore %931 %1735
+               OpBranch %939
+        %936 = OpLabel
+               OpUnreachable
+        %872 = OpLabel
+        %874 = OpAccessChain %9 %47 %1545 %27
+        %875 = OpLoad %6 %874
+        %876 = OpIEqual %40 %875 %28
+               OpSelectionMerge %915 None
+               OpBranchConditional %876 %877 %911
+        %911 = OpLabel
+        %914 = OpLoad %6 %874
+               OpBranch %938
+        %877 = OpLabel
+        %878 = OpAccessChain %67 %65 %24 %66
+        %879 = OpLoad %61 %878
+        %880 = OpAccessChain %67 %65 %24 %70
+        %881 = OpLoad %61 %880
+        %882 = OpFOrdLessThan %40 %879 %881
+               OpSelectionMerge %888 None
+               OpBranchConditional %882 %883 %888
+        %883 = OpLabel
+               OpBranch %884
+        %884 = OpLabel
+               OpLoopMerge %887 %886 None
+               OpBranch %885
+        %885 = OpLabel
+               OpKill
+        %886 = OpLabel
+               OpBranch %884
+        %887 = OpLabel
+               OpUnreachable
+        %888 = OpLabel
+               OpStore %874 %255
+        %898 = OpAccessChain %8 %47 %255
+               OpStore %898 %1735
+               OpBranch %899
+        %899 = OpLabel
+        %904 = OpConvertFToS %6 %879
+        %905 = OpSLessThan %40 %24 %904
+               OpLoopMerge %908 %907 None
+               OpBranchConditional %905 %906 %908
+        %906 = OpLabel
+               OpBranch %908
+        %907 = OpLabel
+               OpBranch %899
+        %908 = OpLabel
+       %1546 = OpPhi %40 %1548 %899 %325 %906
+               OpSelectionMerge %910 None
+               OpBranchConditional %1546 %939 %910
+        %910 = OpLabel
+               OpBranch %915
+        %915 = OpLabel
+               OpBranch %937
+        %937 = OpLabel
+               OpBranch %938
+        %938 = OpLabel
+       %1697 = OpPhi %40 %1548 %911 %1548 %932 %1546 %937
+       %1694 = OpPhi %6 %914 %911 %935 %932 %1545 %937
+               OpBranch %861
+        %939 = OpLabel
+       %1549 = OpPhi %40 %1548 %861 %1546 %908 %325 %921
+               OpSelectionMerge %941 None
+               OpBranchConditional %1549 %942 %941
+        %941 = OpLabel
+               OpBranch %942
+        %942 = OpLabel
+               OpSelectionMerge %1044 None
+               OpSwitch %70 %962
+        %962 = OpLabel
+               OpBranch %963
+        %963 = OpLabel
+       %1559 = OpPhi %40 %322 %962 %1701 %1040
+       %1556 = OpPhi %6 %24 %962 %1698 %1040
+        %967 = OpSLessThanEqual %40 %1556 %235
+               OpLoopMerge %1041 %1040 None
+               OpBranchConditional %967 %968 %1041
+        %968 = OpLabel
+        %971 = OpAccessChain %9 %47 %1556 %24
+        %972 = OpLoad %6 %971
+        %973 = OpSLessThanEqual %40 %255 %972
+               OpSelectionMerge %1039 None
+               OpBranchConditional %973 %974 %1018
+       %1018 = OpLabel
+       %1020 = OpAccessChain %9 %47 %1556 %30
+       %1021 = OpLoad %6 %1020
+       %1022 = OpIEqual %40 %1021 %28
+               OpSelectionMerge %1038 None
+               OpBranchConditional %1022 %1023 %1034
+       %1034 = OpLabel
+       %1037 = OpLoad %6 %1020
+               OpBranch %1040
+       %1023 = OpLabel
+               OpStore %1020 %235
+       %1033 = OpAccessChain %8 %47 %235
+               OpStore %1033 %1736
+               OpBranch %1041
+       %1038 = OpLabel
+               OpUnreachable
+        %974 = OpLabel
+        %976 = OpAccessChain %9 %47 %1556 %27
+        %977 = OpLoad %6 %976
+        %978 = OpIEqual %40 %977 %28
+               OpSelectionMerge %1017 None
+               OpBranchConditional %978 %979 %1013
+       %1013 = OpLabel
+       %1016 = OpLoad %6 %976
+               OpBranch %1040
+        %979 = OpLabel
+        %980 = OpAccessChain %67 %65 %24 %66
+        %981 = OpLoad %61 %980
+        %982 = OpAccessChain %67 %65 %24 %70
+        %983 = OpLoad %61 %982
+        %984 = OpFOrdLessThan %40 %981 %983
+               OpSelectionMerge %990 None
+               OpBranchConditional %984 %985 %990
+        %985 = OpLabel
+               OpBranch %986
+        %986 = OpLabel
+               OpLoopMerge %989 %988 None
+               OpBranch %987
+        %987 = OpLabel
+               OpKill
+        %988 = OpLabel
+               OpBranch %986
+        %989 = OpLabel
+               OpUnreachable
+        %990 = OpLabel
+               OpStore %976 %235
+       %1000 = OpAccessChain %8 %47 %235
+               OpStore %1000 %1736
+               OpBranch %1001
+       %1001 = OpLabel
+       %1006 = OpConvertFToS %6 %981
+       %1007 = OpSLessThan %40 %24 %1006
+               OpLoopMerge %1010 %1009 None
+               OpBranchConditional %1007 %1008 %1010
+       %1008 = OpLabel
+               OpBranch %1010
+       %1009 = OpLabel
+               OpBranch %1001
+       %1010 = OpLabel
+       %1557 = OpPhi %40 %1559 %1001 %325 %1008
+               OpSelectionMerge %1012 None
+               OpBranchConditional %1557 %1041 %1012
+       %1012 = OpLabel
+               OpBranch %1017
+       %1017 = OpLabel
+               OpBranch %1039
+       %1039 = OpLabel
+               OpBranch %1040
+       %1040 = OpLabel
+       %1701 = OpPhi %40 %1559 %1013 %1559 %1034 %1557 %1039
+       %1698 = OpPhi %6 %1016 %1013 %1037 %1034 %1556 %1039
+               OpBranch %963
+       %1041 = OpLabel
+       %1560 = OpPhi %40 %1559 %963 %1557 %1010 %325 %1023
+               OpSelectionMerge %1043 None
+               OpBranchConditional %1560 %1044 %1043
+       %1043 = OpLabel
+               OpBranch %1044
+       %1044 = OpLabel
+               OpSelectionMerge %1146 None
+               OpSwitch %70 %1064
+       %1064 = OpLabel
+               OpBranch %1065
+       %1065 = OpLabel
+       %1570 = OpPhi %40 %322 %1064 %1705 %1142
+       %1567 = OpPhi %6 %24 %1064 %1702 %1142
+       %1069 = OpSLessThanEqual %40 %1567 %242
+               OpLoopMerge %1143 %1142 None
+               OpBranchConditional %1069 %1070 %1143
+       %1070 = OpLabel
+       %1073 = OpAccessChain %9 %47 %1567 %24
+       %1074 = OpLoad %6 %1073
+       %1075 = OpSLessThanEqual %40 %262 %1074
+               OpSelectionMerge %1141 None
+               OpBranchConditional %1075 %1076 %1120
+       %1120 = OpLabel
+       %1122 = OpAccessChain %9 %47 %1567 %30
+       %1123 = OpLoad %6 %1122
+       %1124 = OpIEqual %40 %1123 %28
+               OpSelectionMerge %1140 None
+               OpBranchConditional %1124 %1125 %1136
+       %1136 = OpLabel
+       %1139 = OpLoad %6 %1122
+               OpBranch %1142
+       %1125 = OpLabel
+               OpStore %1122 %242
+       %1135 = OpAccessChain %8 %47 %242
+               OpStore %1135 %1737
+               OpBranch %1143
+       %1140 = OpLabel
+               OpUnreachable
+       %1076 = OpLabel
+       %1078 = OpAccessChain %9 %47 %1567 %27
+       %1079 = OpLoad %6 %1078
+       %1080 = OpIEqual %40 %1079 %28
+               OpSelectionMerge %1119 None
+               OpBranchConditional %1080 %1081 %1115
+       %1115 = OpLabel
+       %1118 = OpLoad %6 %1078
+               OpBranch %1142
+       %1081 = OpLabel
+       %1082 = OpAccessChain %67 %65 %24 %66
+       %1083 = OpLoad %61 %1082
+       %1084 = OpAccessChain %67 %65 %24 %70
+       %1085 = OpLoad %61 %1084
+       %1086 = OpFOrdLessThan %40 %1083 %1085
+               OpSelectionMerge %1092 None
+               OpBranchConditional %1086 %1087 %1092
+       %1087 = OpLabel
+               OpBranch %1088
+       %1088 = OpLabel
+               OpLoopMerge %1091 %1090 None
+               OpBranch %1089
+       %1089 = OpLabel
+               OpKill
+       %1090 = OpLabel
+               OpBranch %1088
+       %1091 = OpLabel
+               OpUnreachable
+       %1092 = OpLabel
+               OpStore %1078 %242
+       %1102 = OpAccessChain %8 %47 %242
+               OpStore %1102 %1737
+               OpBranch %1103
+       %1103 = OpLabel
+       %1108 = OpConvertFToS %6 %1083
+       %1109 = OpSLessThan %40 %24 %1108
+               OpLoopMerge %1112 %1111 None
+               OpBranchConditional %1109 %1110 %1112
+       %1110 = OpLabel
+               OpBranch %1112
+       %1111 = OpLabel
+               OpBranch %1103
+       %1112 = OpLabel
+       %1568 = OpPhi %40 %1570 %1103 %325 %1110
+               OpSelectionMerge %1114 None
+               OpBranchConditional %1568 %1143 %1114
+       %1114 = OpLabel
+               OpBranch %1119
+       %1119 = OpLabel
+               OpBranch %1141
+       %1141 = OpLabel
+               OpBranch %1142
+       %1142 = OpLabel
+       %1705 = OpPhi %40 %1570 %1115 %1570 %1136 %1568 %1141
+       %1702 = OpPhi %6 %1118 %1115 %1139 %1136 %1567 %1141
+               OpBranch %1065
+       %1143 = OpLabel
+       %1571 = OpPhi %40 %1570 %1065 %1568 %1112 %325 %1125
+               OpSelectionMerge %1145 None
+               OpBranchConditional %1571 %1146 %1145
+       %1145 = OpLabel
+               OpBranch %1146
+       %1146 = OpLabel
+               OpSelectionMerge %1248 None
+               OpSwitch %70 %1166
+       %1166 = OpLabel
+               OpBranch %1167
+       %1167 = OpLabel
+       %1581 = OpPhi %40 %322 %1166 %1709 %1244
+       %1578 = OpPhi %6 %24 %1166 %1706 %1244
+       %1171 = OpSLessThanEqual %40 %1578 %179
+               OpLoopMerge %1245 %1244 None
+               OpBranchConditional %1171 %1172 %1245
+       %1172 = OpLabel
+       %1175 = OpAccessChain %9 %47 %1578 %24
+       %1176 = OpLoad %6 %1175
+       %1177 = OpSLessThanEqual %40 %269 %1176
+               OpSelectionMerge %1243 None
+               OpBranchConditional %1177 %1178 %1222
+       %1222 = OpLabel
+       %1224 = OpAccessChain %9 %47 %1578 %30
+       %1225 = OpLoad %6 %1224
+       %1226 = OpIEqual %40 %1225 %28
+               OpSelectionMerge %1242 None
+               OpBranchConditional %1226 %1227 %1238
+       %1238 = OpLabel
+       %1241 = OpLoad %6 %1224
+               OpBranch %1244
+       %1227 = OpLabel
+               OpStore %1224 %179
+       %1237 = OpAccessChain %8 %47 %179
+               OpStore %1237 %1738
+               OpBranch %1245
+       %1242 = OpLabel
+               OpUnreachable
+       %1178 = OpLabel
+       %1180 = OpAccessChain %9 %47 %1578 %27
+       %1181 = OpLoad %6 %1180
+       %1182 = OpIEqual %40 %1181 %28
+               OpSelectionMerge %1221 None
+               OpBranchConditional %1182 %1183 %1217
+       %1217 = OpLabel
+       %1220 = OpLoad %6 %1180
+               OpBranch %1244
+       %1183 = OpLabel
+       %1184 = OpAccessChain %67 %65 %24 %66
+       %1185 = OpLoad %61 %1184
+       %1186 = OpAccessChain %67 %65 %24 %70
+       %1187 = OpLoad %61 %1186
+       %1188 = OpFOrdLessThan %40 %1185 %1187
+               OpSelectionMerge %1194 None
+               OpBranchConditional %1188 %1189 %1194
+       %1189 = OpLabel
+               OpBranch %1190
+       %1190 = OpLabel
+               OpLoopMerge %1193 %1192 None
+               OpBranch %1191
+       %1191 = OpLabel
+               OpKill
+       %1192 = OpLabel
+               OpBranch %1190
+       %1193 = OpLabel
+               OpUnreachable
+       %1194 = OpLabel
+               OpStore %1180 %179
+       %1204 = OpAccessChain %8 %47 %179
+               OpStore %1204 %1738
+               OpBranch %1205
+       %1205 = OpLabel
+       %1210 = OpConvertFToS %6 %1185
+       %1211 = OpSLessThan %40 %24 %1210
+               OpLoopMerge %1214 %1213 None
+               OpBranchConditional %1211 %1212 %1214
+       %1212 = OpLabel
+               OpBranch %1214
+       %1213 = OpLabel
+               OpBranch %1205
+       %1214 = OpLabel
+       %1579 = OpPhi %40 %1581 %1205 %325 %1212
+               OpSelectionMerge %1216 None
+               OpBranchConditional %1579 %1245 %1216
+       %1216 = OpLabel
+               OpBranch %1221
+       %1221 = OpLabel
+               OpBranch %1243
+       %1243 = OpLabel
+               OpBranch %1244
+       %1244 = OpLabel
+       %1709 = OpPhi %40 %1581 %1217 %1581 %1238 %1579 %1243
+       %1706 = OpPhi %6 %1220 %1217 %1241 %1238 %1578 %1243
+               OpBranch %1167
+       %1245 = OpLabel
+       %1582 = OpPhi %40 %1581 %1167 %1579 %1214 %325 %1227
+               OpSelectionMerge %1247 None
+               OpBranchConditional %1582 %1248 %1247
+       %1247 = OpLabel
+               OpBranch %1248
+       %1248 = OpLabel
+               OpBranch %276
+        %276 = OpLabel
+       %1593 = OpPhi %6 %1620 %1248 %1590 %279
+       %1584 = OpPhi %6 %24 %1248 %1710 %279
+       %1583 = OpPhi %6 %24 %1248 %309 %279
+        %283 = OpSLessThan %40 %1583 %282
+               OpLoopMerge %278 %279 None
+               OpBranchConditional %283 %277 %278
+        %277 = OpLabel
+               OpSelectionMerge %1299 None
+               OpSwitch %70 %1267
+       %1267 = OpLabel
+               OpBranch %1268
+       %1268 = OpLabel
+       %1585 = OpPhi %6 %24 %1267 %1739 %1295
+       %1271 = OpINotEqual %40 %1585 %28
+               OpLoopMerge %1296 %1295 None
+               OpBranchConditional %1271 %1272 %1296
+       %1272 = OpLabel
+       %1274 = OpAccessChain %8 %47 %1585
+       %1275 = OpLoad %7 %1274
+       %1305 = OpCompositeExtract %6 %1275 0
+       %1306 = OpCompositeExtract %6 %1275 1
+       %1307 = OpCompositeExtract %6 %1275 2
+       %1279 = OpIEqual %40 %1305 %1583
+               OpSelectionMerge %1282 None
+               OpBranchConditional %1279 %1280 %1282
+       %1280 = OpLabel
+               OpBranch %1296
+       %1282 = OpLabel
+       %1286 = OpSGreaterThan %40 %1583 %1305
+       %1739 = OpSelect %6 %1286 %1307 %1306
+               OpBranch %1295
+       %1295 = OpLabel
+               OpBranch %1268
+       %1296 = OpLabel
+       %1591 = OpPhi %6 %1593 %1268 %1583 %1280
+       %1587 = OpPhi %40 %322 %1268 %325 %1280
+               OpSelectionMerge %1298 None
+               OpBranchConditional %1587 %1299 %1298
+       %1298 = OpLabel
+               OpBranch %1299
+       %1299 = OpLabel
+       %1590 = OpPhi %6 %1591 %1296 %28 %1298
+               OpSelectionMerge %291 None
+               OpSwitch %1583 %290 9 %289 5 %289 12 %289 15 %289 7 %289 8 %289 2 %289 6 %289 17 %289 13 %289
+        %289 = OpLabel
+        %294 = OpIEqual %40 %1590 %1583
+               OpSelectionMerge %296 None
+               OpBranchConditional %294 %295 %296
+        %295 = OpLabel
+        %298 = OpIAdd %6 %1584 %27
+               OpBranch %296
+        %296 = OpLabel
+       %1712 = OpPhi %6 %1584 %289 %298 %295
+               OpBranch %291
+        %290 = OpLabel
+        %301 = OpIEqual %40 %1590 %28
+               OpSelectionMerge %303 None
+               OpBranchConditional %301 %302 %303
+        %302 = OpLabel
+        %305 = OpIAdd %6 %1584 %27
+               OpBranch %303
+        %303 = OpLabel
+       %1711 = OpPhi %6 %1584 %290 %305 %302
+               OpBranch %291
+        %291 = OpLabel
+       %1710 = OpPhi %6 %1711 %303 %1712 %296
+               OpBranch %279
+        %279 = OpLabel
+        %309 = OpIAdd %6 %1583 %27
+               OpBranch %276
+        %278 = OpLabel
+        %311 = OpIEqual %40 %1584 %282
+               OpSelectionMerge %313 None
+               OpBranchConditional %311 %312 %318
+        %318 = OpLabel
+               OpStore %315 %319
+               OpBranch %313
+        %312 = OpLabel
+               OpStore %315 %317
+               OpBranch %313
+        %313 = 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 reference_framebuffer EQ_HISTOGRAM_EMD_BUFFER variant_framebuffer TOLERANCE 0.005
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-binarysearch-tree-nested-if-and-conditional.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-binarysearch-tree-nested-if-and-conditional.amber
new file mode 100644 (file)
index 0000000..fe0394a
--- /dev/null
@@ -0,0 +1,1267 @@
+#!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 nested if and conditional statement
+
+# The test passes because both shaders render the same image.
+
+SHADER vertex reference_vertex_shader PASSTHROUGH
+
+# reference_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# struct BST
+# {
+#   int data;
+#   int leftIndex;
+#   int rightIndex;
+# };
+#
+# BST tree[10];
+#
+# void makeTreeNode(inout BST tree, int data)
+# {
+#   tree.data = data;
+#   tree.leftIndex = -1;
+#   tree.rightIndex = -1;
+# }
+# void insert(int treeIndex, int data)
+# {
+#   int baseIndex = 0;
+#   while (baseIndex <= treeIndex)
+#   {
+#     if (data <= tree[baseIndex].data)
+#     {
+#       if (tree[baseIndex].leftIndex == -1)
+#       {
+#         tree[baseIndex].leftIndex = treeIndex;
+#         makeTreeNode(tree[treeIndex], data);
+#         return;
+#       }
+#       else
+#       {
+#         baseIndex = tree[baseIndex].leftIndex;
+#         continue;
+#       }
+#     }
+#     else
+#     {
+#       if (tree[baseIndex].rightIndex == -1)
+#       {
+#         tree[baseIndex].rightIndex = treeIndex;
+#         makeTreeNode(tree[treeIndex], data);
+#         return;
+#       }
+#       else
+#       {
+#         baseIndex = tree[baseIndex].rightIndex;
+#         continue;
+#       }
+#     }
+#   }
+# }
+# int search(int target)
+# {
+#   BST currentNode;
+#   int index = 0;
+#   while (index != -1)
+#   {
+#     currentNode = tree[index];
+#     if (currentNode.data == target)
+#     {
+#       return target;
+#     }
+#     index = target > currentNode.data ? currentNode.rightIndex : currentNode.leftIndex;
+#   }
+#   return -1;
+# }
+# void main()
+# {
+#   int treeIndex = 0;
+#   makeTreeNode(tree[0], 9);
+#   treeIndex++;
+#   insert(treeIndex, 5);
+#   treeIndex++;
+#   insert(treeIndex, 12);
+#   treeIndex++;
+#   insert(treeIndex, 15);
+#   treeIndex++;
+#   insert(treeIndex, 7);
+#   treeIndex++;
+#   insert(treeIndex, 8);
+#   treeIndex++;
+#   insert(treeIndex, 2);
+#   treeIndex++;
+#   insert(treeIndex, 6);
+#   treeIndex++;
+#   insert(treeIndex, 17);
+#   treeIndex++;
+#   insert(treeIndex, 13);
+#   int count = 0;
+#   for (int i = 0; i < 20; i++)
+#   {
+#     int result = search(i);
+#     switch (i)
+#     {
+#     case 9:
+#     case 5:
+#     case 12:
+#     case 15:
+#     case 7:
+#     case 8:
+#     case 2:
+#     case 6:
+#     case 17:
+#     case 13:
+#       if (result == i)
+#       {
+#         count++;
+#       }
+#       break;
+#     default:
+#       if (result == -1)
+#       {
+#         count++;
+#       }
+#       break;
+#     }
+#   }
+#   if (count == 20)
+#   {
+#     _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#   }
+#   else
+#   {
+#     _GLF_color = vec4(0.0, 0.0, 1.0, 1.0);
+#   }
+# }
+SHADER fragment reference_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 260
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %254
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %7 "BST"
+               OpMemberName %7 0 "data"
+               OpMemberName %7 1 "leftIndex"
+               OpMemberName %7 2 "rightIndex"
+               OpName %13 "makeTreeNode(struct-BST-i1-i1-i11;i1;"
+               OpName %11 "tree"
+               OpName %12 "data"
+               OpName %18 "insert(i1;i1;"
+               OpName %16 "treeIndex"
+               OpName %17 "data"
+               OpName %22 "search(i1;"
+               OpName %21 "target"
+               OpName %32 "baseIndex"
+               OpName %47 "tree"
+               OpName %65 "param"
+               OpName %69 "param"
+               OpName %91 "param"
+               OpName %94 "param"
+               OpName %105 "index"
+               OpName %113 "currentNode"
+               OpName %140 "treeIndex"
+               OpName %142 "param"
+               OpName %145 "param"
+               OpName %152 "param"
+               OpName %154 "param"
+               OpName %159 "param"
+               OpName %161 "param"
+               OpName %166 "param"
+               OpName %168 "param"
+               OpName %173 "param"
+               OpName %175 "param"
+               OpName %180 "param"
+               OpName %182 "param"
+               OpName %186 "param"
+               OpName %188 "param"
+               OpName %193 "param"
+               OpName %195 "param"
+               OpName %200 "param"
+               OpName %202 "param"
+               OpName %207 "param"
+               OpName %209 "param"
+               OpName %211 "count"
+               OpName %212 "i"
+               OpName %221 "result"
+               OpName %222 "param"
+               OpName %254 "_GLF_color"
+               OpDecorate %254 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypeStruct %6 %6 %6
+          %8 = OpTypePointer Function %7
+          %9 = OpTypePointer Function %6
+         %10 = OpTypeFunction %2 %8 %9
+         %15 = OpTypeFunction %2 %9 %9
+         %20 = OpTypeFunction %6 %9
+         %24 = OpConstant %6 0
+         %27 = OpConstant %6 1
+         %28 = OpConstant %6 -1
+         %30 = OpConstant %6 2
+         %40 = OpTypeBool
+         %43 = OpTypeInt 32 0
+         %44 = OpConstant %43 10
+         %45 = OpTypeArray %7 %44
+         %46 = OpTypePointer Private %45
+         %47 = OpVariable %46 Private
+         %49 = OpTypePointer Private %6
+         %66 = OpTypePointer Private %7
+        %141 = OpConstant %6 9
+        %151 = OpConstant %6 5
+        %158 = OpConstant %6 12
+        %165 = OpConstant %6 15
+        %172 = OpConstant %6 7
+        %179 = OpConstant %6 8
+        %192 = OpConstant %6 6
+        %199 = OpConstant %6 17
+        %206 = OpConstant %6 13
+        %219 = OpConstant %6 20
+        %251 = OpTypeFloat 32
+        %252 = OpTypeVector %251 4
+        %253 = OpTypePointer Output %252
+        %254 = OpVariable %253 Output
+        %255 = OpConstant %251 1
+        %256 = OpConstant %251 0
+        %257 = OpConstantComposite %252 %255 %256 %256 %255
+        %259 = OpConstantComposite %252 %256 %256 %255 %255
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %140 = OpVariable %9 Function
+        %142 = OpVariable %8 Function
+        %145 = OpVariable %9 Function
+        %152 = OpVariable %9 Function
+        %154 = OpVariable %9 Function
+        %159 = OpVariable %9 Function
+        %161 = OpVariable %9 Function
+        %166 = OpVariable %9 Function
+        %168 = OpVariable %9 Function
+        %173 = OpVariable %9 Function
+        %175 = OpVariable %9 Function
+        %180 = OpVariable %9 Function
+        %182 = OpVariable %9 Function
+        %186 = OpVariable %9 Function
+        %188 = OpVariable %9 Function
+        %193 = OpVariable %9 Function
+        %195 = OpVariable %9 Function
+        %200 = OpVariable %9 Function
+        %202 = OpVariable %9 Function
+        %207 = OpVariable %9 Function
+        %209 = OpVariable %9 Function
+        %211 = OpVariable %9 Function
+        %212 = OpVariable %9 Function
+        %221 = OpVariable %9 Function
+        %222 = OpVariable %9 Function
+               OpStore %140 %24
+        %143 = OpAccessChain %66 %47 %24
+        %144 = OpLoad %7 %143
+               OpStore %142 %144
+               OpStore %145 %141
+        %146 = OpFunctionCall %2 %13 %142 %145
+        %147 = OpLoad %7 %142
+        %148 = OpAccessChain %66 %47 %24
+               OpStore %148 %147
+        %149 = OpLoad %6 %140
+        %150 = OpIAdd %6 %149 %27
+               OpStore %140 %150
+        %153 = OpLoad %6 %140
+               OpStore %152 %153
+               OpStore %154 %151
+        %155 = OpFunctionCall %2 %18 %152 %154
+        %156 = OpLoad %6 %140
+        %157 = OpIAdd %6 %156 %27
+               OpStore %140 %157
+        %160 = OpLoad %6 %140
+               OpStore %159 %160
+               OpStore %161 %158
+        %162 = OpFunctionCall %2 %18 %159 %161
+        %163 = OpLoad %6 %140
+        %164 = OpIAdd %6 %163 %27
+               OpStore %140 %164
+        %167 = OpLoad %6 %140
+               OpStore %166 %167
+               OpStore %168 %165
+        %169 = OpFunctionCall %2 %18 %166 %168
+        %170 = OpLoad %6 %140
+        %171 = OpIAdd %6 %170 %27
+               OpStore %140 %171
+        %174 = OpLoad %6 %140
+               OpStore %173 %174
+               OpStore %175 %172
+        %176 = OpFunctionCall %2 %18 %173 %175
+        %177 = OpLoad %6 %140
+        %178 = OpIAdd %6 %177 %27
+               OpStore %140 %178
+        %181 = OpLoad %6 %140
+               OpStore %180 %181
+               OpStore %182 %179
+        %183 = OpFunctionCall %2 %18 %180 %182
+        %184 = OpLoad %6 %140
+        %185 = OpIAdd %6 %184 %27
+               OpStore %140 %185
+        %187 = OpLoad %6 %140
+               OpStore %186 %187
+               OpStore %188 %30
+        %189 = OpFunctionCall %2 %18 %186 %188
+        %190 = OpLoad %6 %140
+        %191 = OpIAdd %6 %190 %27
+               OpStore %140 %191
+        %194 = OpLoad %6 %140
+               OpStore %193 %194
+               OpStore %195 %192
+        %196 = OpFunctionCall %2 %18 %193 %195
+        %197 = OpLoad %6 %140
+        %198 = OpIAdd %6 %197 %27
+               OpStore %140 %198
+        %201 = OpLoad %6 %140
+               OpStore %200 %201
+               OpStore %202 %199
+        %203 = OpFunctionCall %2 %18 %200 %202
+        %204 = OpLoad %6 %140
+        %205 = OpIAdd %6 %204 %27
+               OpStore %140 %205
+        %208 = OpLoad %6 %140
+               OpStore %207 %208
+               OpStore %209 %206
+        %210 = OpFunctionCall %2 %18 %207 %209
+               OpStore %211 %24
+               OpStore %212 %24
+               OpBranch %213
+        %213 = OpLabel
+               OpLoopMerge %215 %216 None
+               OpBranch %217
+        %217 = OpLabel
+        %218 = OpLoad %6 %212
+        %220 = OpSLessThan %40 %218 %219
+               OpBranchConditional %220 %214 %215
+        %214 = OpLabel
+        %223 = OpLoad %6 %212
+               OpStore %222 %223
+        %224 = OpFunctionCall %6 %22 %222
+               OpStore %221 %224
+        %225 = OpLoad %6 %212
+               OpSelectionMerge %228 None
+               OpSwitch %225 %227 9 %226 5 %226 12 %226 15 %226 7 %226 8 %226 2 %226 6 %226 17 %226 13 %226
+        %227 = OpLabel
+        %237 = OpLoad %6 %221
+        %238 = OpIEqual %40 %237 %28
+               OpSelectionMerge %240 None
+               OpBranchConditional %238 %239 %240
+        %239 = OpLabel
+        %241 = OpLoad %6 %211
+        %242 = OpIAdd %6 %241 %27
+               OpStore %211 %242
+               OpBranch %240
+        %240 = OpLabel
+               OpBranch %228
+        %226 = OpLabel
+        %229 = OpLoad %6 %221
+        %230 = OpLoad %6 %212
+        %231 = OpIEqual %40 %229 %230
+               OpSelectionMerge %233 None
+               OpBranchConditional %231 %232 %233
+        %232 = OpLabel
+        %234 = OpLoad %6 %211
+        %235 = OpIAdd %6 %234 %27
+               OpStore %211 %235
+               OpBranch %233
+        %233 = OpLabel
+               OpBranch %228
+        %228 = OpLabel
+               OpBranch %216
+        %216 = OpLabel
+        %245 = OpLoad %6 %212
+        %246 = OpIAdd %6 %245 %27
+               OpStore %212 %246
+               OpBranch %213
+        %215 = OpLabel
+        %247 = OpLoad %6 %211
+        %248 = OpIEqual %40 %247 %219
+               OpSelectionMerge %250 None
+               OpBranchConditional %248 %249 %258
+        %249 = OpLabel
+               OpStore %254 %257
+               OpBranch %250
+        %258 = OpLabel
+               OpStore %254 %259
+               OpBranch %250
+        %250 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %13 = OpFunction %2 None %10
+         %11 = OpFunctionParameter %8
+         %12 = OpFunctionParameter %9
+         %14 = OpLabel
+         %25 = OpLoad %6 %12
+         %26 = OpAccessChain %9 %11 %24
+               OpStore %26 %25
+         %29 = OpAccessChain %9 %11 %27
+               OpStore %29 %28
+         %31 = OpAccessChain %9 %11 %30
+               OpStore %31 %28
+               OpReturn
+               OpFunctionEnd
+         %18 = OpFunction %2 None %15
+         %16 = OpFunctionParameter %9
+         %17 = OpFunctionParameter %9
+         %19 = OpLabel
+         %32 = OpVariable %9 Function
+         %65 = OpVariable %8 Function
+         %69 = OpVariable %9 Function
+         %91 = OpVariable %8 Function
+         %94 = OpVariable %9 Function
+               OpStore %32 %24
+               OpBranch %33
+         %33 = OpLabel
+               OpLoopMerge %35 %36 None
+               OpBranch %37
+         %37 = OpLabel
+         %38 = OpLoad %6 %32
+         %39 = OpLoad %6 %16
+         %41 = OpSLessThanEqual %40 %38 %39
+               OpBranchConditional %41 %34 %35
+         %34 = OpLabel
+         %42 = OpLoad %6 %17
+         %48 = OpLoad %6 %32
+         %50 = OpAccessChain %49 %47 %48 %24
+         %51 = OpLoad %6 %50
+         %52 = OpSLessThanEqual %40 %42 %51
+               OpSelectionMerge %54 None
+               OpBranchConditional %52 %53 %80
+         %53 = OpLabel
+         %55 = OpLoad %6 %32
+         %56 = OpAccessChain %49 %47 %55 %27
+         %57 = OpLoad %6 %56
+         %58 = OpIEqual %40 %57 %28
+               OpSelectionMerge %60 None
+               OpBranchConditional %58 %59 %75
+         %59 = OpLabel
+         %61 = OpLoad %6 %32
+         %62 = OpLoad %6 %16
+         %63 = OpAccessChain %49 %47 %61 %27
+               OpStore %63 %62
+         %64 = OpLoad %6 %16
+         %67 = OpAccessChain %66 %47 %64
+         %68 = OpLoad %7 %67
+               OpStore %65 %68
+         %70 = OpLoad %6 %17
+               OpStore %69 %70
+         %71 = OpFunctionCall %2 %13 %65 %69
+         %72 = OpLoad %7 %65
+         %73 = OpAccessChain %66 %47 %64
+               OpStore %73 %72
+               OpReturn
+         %75 = OpLabel
+         %76 = OpLoad %6 %32
+         %77 = OpAccessChain %49 %47 %76 %27
+         %78 = OpLoad %6 %77
+               OpStore %32 %78
+               OpBranch %36
+         %60 = OpLabel
+               OpUnreachable
+         %80 = OpLabel
+         %81 = OpLoad %6 %32
+         %82 = OpAccessChain %49 %47 %81 %30
+         %83 = OpLoad %6 %82
+         %84 = OpIEqual %40 %83 %28
+               OpSelectionMerge %86 None
+               OpBranchConditional %84 %85 %100
+         %85 = OpLabel
+         %87 = OpLoad %6 %32
+         %88 = OpLoad %6 %16
+         %89 = OpAccessChain %49 %47 %87 %30
+               OpStore %89 %88
+         %90 = OpLoad %6 %16
+         %92 = OpAccessChain %66 %47 %90
+         %93 = OpLoad %7 %92
+               OpStore %91 %93
+         %95 = OpLoad %6 %17
+               OpStore %94 %95
+         %96 = OpFunctionCall %2 %13 %91 %94
+         %97 = OpLoad %7 %91
+         %98 = OpAccessChain %66 %47 %90
+               OpStore %98 %97
+               OpReturn
+        %100 = OpLabel
+        %101 = OpLoad %6 %32
+        %102 = OpAccessChain %49 %47 %101 %30
+        %103 = OpLoad %6 %102
+               OpStore %32 %103
+               OpBranch %36
+         %86 = OpLabel
+               OpUnreachable
+         %54 = OpLabel
+               OpUnreachable
+         %36 = OpLabel
+               OpBranch %33
+         %35 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %22 = OpFunction %6 None %20
+         %21 = OpFunctionParameter %9
+         %23 = OpLabel
+        %105 = OpVariable %9 Function
+        %113 = OpVariable %8 Function
+        %129 = OpVariable %9 Function
+               OpStore %105 %24
+               OpBranch %106
+        %106 = OpLabel
+               OpLoopMerge %108 %109 None
+               OpBranch %110
+        %110 = OpLabel
+        %111 = OpLoad %6 %105
+        %112 = OpINotEqual %40 %111 %28
+               OpBranchConditional %112 %107 %108
+        %107 = OpLabel
+        %114 = OpLoad %6 %105
+        %115 = OpAccessChain %66 %47 %114
+        %116 = OpLoad %7 %115
+               OpStore %113 %116
+        %117 = OpAccessChain %9 %113 %24
+        %118 = OpLoad %6 %117
+        %119 = OpLoad %6 %21
+        %120 = OpIEqual %40 %118 %119
+               OpSelectionMerge %122 None
+               OpBranchConditional %120 %121 %122
+        %121 = OpLabel
+        %123 = OpLoad %6 %21
+               OpReturnValue %123
+        %122 = OpLabel
+        %125 = OpLoad %6 %21
+        %126 = OpAccessChain %9 %113 %24
+        %127 = OpLoad %6 %126
+        %128 = OpSGreaterThan %40 %125 %127
+               OpSelectionMerge %131 None
+               OpBranchConditional %128 %130 %134
+        %130 = OpLabel
+        %132 = OpAccessChain %9 %113 %30
+        %133 = OpLoad %6 %132
+               OpStore %129 %133
+               OpBranch %131
+        %134 = OpLabel
+        %135 = OpAccessChain %9 %113 %27
+        %136 = OpLoad %6 %135
+               OpStore %129 %136
+               OpBranch %131
+        %131 = OpLabel
+        %137 = OpLoad %6 %129
+               OpStore %105 %137
+               OpBranch %109
+        %109 = OpLabel
+               OpBranch %106
+        %108 = OpLabel
+               OpReturnValue %28
+               OpFunctionEnd
+END
+
+
+BUFFER reference_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics reference_pipeline
+  ATTACH reference_vertex_shader
+  ATTACH reference_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER reference_framebuffer AS color LOCATION 0
+END
+CLEAR_COLOR reference_pipeline 0 0 0 255
+
+CLEAR reference_pipeline
+RUN reference_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#   vec2 injectionSwitch; // x == 0.0, y == 1.0
+# };
+# layout(location = 0) out vec4 _GLF_color;
+#
+# struct BST
+# {
+#   int data;
+#   int leftIndex;
+#   int rightIndex;
+# };
+#
+# BST tree[10];
+#
+# void makeTreeNode(inout BST tree, int data)
+# {
+#   tree.data = data;
+#   tree.leftIndex = -1;
+#   tree.rightIndex = -1;
+# }
+# void insert(int treeIndex, int data)
+# {
+#   int baseIndex = 0;
+#   while (baseIndex <= treeIndex)
+#   {
+#     if (data <= tree[baseIndex].data)
+#     {
+#       if (tree[baseIndex].leftIndex == -1)
+#       {
+#         tree[baseIndex].leftIndex = treeIndex;
+#         // Always true.
+#         if (injectionSwitch.x < injectionSwitch.y)
+#         {
+#           makeTreeNode(tree[treeIndex], data);
+#         }
+#         // Always true.
+#         if (injectionSwitch.x < injectionSwitch.y)
+#         {
+#           return;
+#         }
+#       }
+#       else
+#       {
+#         baseIndex = tree[baseIndex].leftIndex;
+#         continue;
+#       }
+#     }
+#     else
+#     {
+#       // Conditional statement's result is irrelevant.
+#       if ((injectionSwitch.x < injectionSwitch.y ? tree[baseIndex].rightIndex : tree[baseIndex].rightIndex) == -1)
+#       {
+#         tree[baseIndex].rightIndex = treeIndex;
+#         makeTreeNode(tree[treeIndex], data);
+#         return;
+#       }
+#       else
+#       {
+#         baseIndex = tree[baseIndex].rightIndex;
+#         continue;
+#       }
+#     }
+#     // Always false.
+#     if (injectionSwitch.x > injectionSwitch.y)
+#     {
+#       return;
+#     }
+#   }
+# }
+# int search(int target)
+# {
+#   BST currentNode;
+#   int index = 0;
+#   while (index != -1)
+#   {
+#     currentNode = tree[index];
+#     if (currentNode.data == target)
+#     {
+#       return target;
+#     }
+#     index = target > currentNode.data ? currentNode.rightIndex : currentNode.leftIndex;
+#   }
+#   return -1;
+# }
+# void main()
+# {
+#   int treeIndex = 0;
+#   makeTreeNode(tree[0], 9);
+#   treeIndex++;
+#   insert(treeIndex, 5);
+#   treeIndex++;
+#   insert(treeIndex, 12);
+#   treeIndex++;
+#   insert(treeIndex, 15);
+#   treeIndex++;
+#   insert(treeIndex, 7);
+#   treeIndex++;
+#   insert(treeIndex, 8);
+#   treeIndex++;
+#   insert(treeIndex, 2);
+#   treeIndex++;
+#   insert(treeIndex, 6);
+#   treeIndex++;
+#   insert(treeIndex, 17);
+#   treeIndex++;
+#   insert(treeIndex, 13);
+#   int count = 0;
+#   for (int i = 0; i < 20; i++)
+#   {
+#     int result = search(i);
+#     switch (i)
+#     {
+#     case 9:
+#     case 5:
+#     case 12:
+#     case 15:
+#     case 7:
+#     case 8:
+#     case 2:
+#     case 6:
+#     case 17:
+#     case 13:
+#       if (result == i)
+#       {
+#         count++;
+#       }
+#       break;
+#     default:
+#       if (result == -1)
+#       {
+#         count++;
+#       }
+#       break;
+#     }
+#   }
+#   if (count == 20)
+#   {
+#     _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#   }
+#   else
+#   {
+#     _GLF_color = vec4(0.0, 0.0, 1.0, 1.0);
+#   }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 302
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %296
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %7 "BST"
+               OpMemberName %7 0 "data"
+               OpMemberName %7 1 "leftIndex"
+               OpMemberName %7 2 "rightIndex"
+               OpName %13 "makeTreeNode(struct-BST-i1-i1-i11;i1;"
+               OpName %11 "tree"
+               OpName %12 "data"
+               OpName %18 "insert(i1;i1;"
+               OpName %16 "treeIndex"
+               OpName %17 "data"
+               OpName %22 "search(i1;"
+               OpName %21 "target"
+               OpName %32 "baseIndex"
+               OpName %47 "tree"
+               OpName %66 "buf0"
+               OpMemberName %66 0 "injectionSwitch"
+               OpName %68 ""
+               OpName %80 "param"
+               OpName %84 "param"
+               OpName %126 "param"
+               OpName %129 "param"
+               OpName %148 "index"
+               OpName %156 "currentNode"
+               OpName %183 "treeIndex"
+               OpName %185 "param"
+               OpName %188 "param"
+               OpName %195 "param"
+               OpName %197 "param"
+               OpName %202 "param"
+               OpName %204 "param"
+               OpName %209 "param"
+               OpName %211 "param"
+               OpName %216 "param"
+               OpName %218 "param"
+               OpName %223 "param"
+               OpName %225 "param"
+               OpName %229 "param"
+               OpName %231 "param"
+               OpName %236 "param"
+               OpName %238 "param"
+               OpName %243 "param"
+               OpName %245 "param"
+               OpName %250 "param"
+               OpName %252 "param"
+               OpName %254 "count"
+               OpName %255 "i"
+               OpName %264 "result"
+               OpName %265 "param"
+               OpName %296 "_GLF_color"
+               OpMemberDecorate %66 0 Offset 0
+               OpDecorate %66 Block
+               OpDecorate %68 DescriptorSet 0
+               OpDecorate %68 Binding 0
+               OpDecorate %296 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypeStruct %6 %6 %6
+          %8 = OpTypePointer Function %7
+          %9 = OpTypePointer Function %6
+         %10 = OpTypeFunction %2 %8 %9
+         %15 = OpTypeFunction %2 %9 %9
+         %20 = OpTypeFunction %6 %9
+         %24 = OpConstant %6 0
+         %27 = OpConstant %6 1
+         %28 = OpConstant %6 -1
+         %30 = OpConstant %6 2
+         %40 = OpTypeBool
+         %43 = OpTypeInt 32 0
+         %44 = OpConstant %43 10
+         %45 = OpTypeArray %7 %44
+         %46 = OpTypePointer Private %45
+         %47 = OpVariable %46 Private
+         %49 = OpTypePointer Private %6
+         %64 = OpTypeFloat 32
+         %65 = OpTypeVector %64 2
+         %66 = OpTypeStruct %65
+         %67 = OpTypePointer Uniform %66
+         %68 = OpVariable %67 Uniform
+         %69 = OpConstant %43 0
+         %70 = OpTypePointer Uniform %64
+         %73 = OpConstant %43 1
+         %81 = OpTypePointer Private %7
+        %184 = OpConstant %6 9
+        %194 = OpConstant %6 5
+        %201 = OpConstant %6 12
+        %208 = OpConstant %6 15
+        %215 = OpConstant %6 7
+        %222 = OpConstant %6 8
+        %235 = OpConstant %6 6
+        %242 = OpConstant %6 17
+        %249 = OpConstant %6 13
+        %262 = OpConstant %6 20
+        %294 = OpTypeVector %64 4
+        %295 = OpTypePointer Output %294
+        %296 = OpVariable %295 Output
+        %297 = OpConstant %64 1
+        %298 = OpConstant %64 0
+        %299 = OpConstantComposite %294 %297 %298 %298 %297
+        %301 = OpConstantComposite %294 %298 %298 %297 %297
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %183 = OpVariable %9 Function
+        %185 = OpVariable %8 Function
+        %188 = OpVariable %9 Function
+        %195 = OpVariable %9 Function
+        %197 = OpVariable %9 Function
+        %202 = OpVariable %9 Function
+        %204 = OpVariable %9 Function
+        %209 = OpVariable %9 Function
+        %211 = OpVariable %9 Function
+        %216 = OpVariable %9 Function
+        %218 = OpVariable %9 Function
+        %223 = OpVariable %9 Function
+        %225 = OpVariable %9 Function
+        %229 = OpVariable %9 Function
+        %231 = OpVariable %9 Function
+        %236 = OpVariable %9 Function
+        %238 = OpVariable %9 Function
+        %243 = OpVariable %9 Function
+        %245 = OpVariable %9 Function
+        %250 = OpVariable %9 Function
+        %252 = OpVariable %9 Function
+        %254 = OpVariable %9 Function
+        %255 = OpVariable %9 Function
+        %264 = OpVariable %9 Function
+        %265 = OpVariable %9 Function
+               OpStore %183 %24
+        %186 = OpAccessChain %81 %47 %24
+        %187 = OpLoad %7 %186
+               OpStore %185 %187
+               OpStore %188 %184
+        %189 = OpFunctionCall %2 %13 %185 %188
+        %190 = OpLoad %7 %185
+        %191 = OpAccessChain %81 %47 %24
+               OpStore %191 %190
+        %192 = OpLoad %6 %183
+        %193 = OpIAdd %6 %192 %27
+               OpStore %183 %193
+        %196 = OpLoad %6 %183
+               OpStore %195 %196
+               OpStore %197 %194
+        %198 = OpFunctionCall %2 %18 %195 %197
+        %199 = OpLoad %6 %183
+        %200 = OpIAdd %6 %199 %27
+               OpStore %183 %200
+        %203 = OpLoad %6 %183
+               OpStore %202 %203
+               OpStore %204 %201
+        %205 = OpFunctionCall %2 %18 %202 %204
+        %206 = OpLoad %6 %183
+        %207 = OpIAdd %6 %206 %27
+               OpStore %183 %207
+        %210 = OpLoad %6 %183
+               OpStore %209 %210
+               OpStore %211 %208
+        %212 = OpFunctionCall %2 %18 %209 %211
+        %213 = OpLoad %6 %183
+        %214 = OpIAdd %6 %213 %27
+               OpStore %183 %214
+        %217 = OpLoad %6 %183
+               OpStore %216 %217
+               OpStore %218 %215
+        %219 = OpFunctionCall %2 %18 %216 %218
+        %220 = OpLoad %6 %183
+        %221 = OpIAdd %6 %220 %27
+               OpStore %183 %221
+        %224 = OpLoad %6 %183
+               OpStore %223 %224
+               OpStore %225 %222
+        %226 = OpFunctionCall %2 %18 %223 %225
+        %227 = OpLoad %6 %183
+        %228 = OpIAdd %6 %227 %27
+               OpStore %183 %228
+        %230 = OpLoad %6 %183
+               OpStore %229 %230
+               OpStore %231 %30
+        %232 = OpFunctionCall %2 %18 %229 %231
+        %233 = OpLoad %6 %183
+        %234 = OpIAdd %6 %233 %27
+               OpStore %183 %234
+        %237 = OpLoad %6 %183
+               OpStore %236 %237
+               OpStore %238 %235
+        %239 = OpFunctionCall %2 %18 %236 %238
+        %240 = OpLoad %6 %183
+        %241 = OpIAdd %6 %240 %27
+               OpStore %183 %241
+        %244 = OpLoad %6 %183
+               OpStore %243 %244
+               OpStore %245 %242
+        %246 = OpFunctionCall %2 %18 %243 %245
+        %247 = OpLoad %6 %183
+        %248 = OpIAdd %6 %247 %27
+               OpStore %183 %248
+        %251 = OpLoad %6 %183
+               OpStore %250 %251
+               OpStore %252 %249
+        %253 = OpFunctionCall %2 %18 %250 %252
+               OpStore %254 %24
+               OpStore %255 %24
+               OpBranch %256
+        %256 = OpLabel
+               OpLoopMerge %258 %259 None
+               OpBranch %260
+        %260 = OpLabel
+        %261 = OpLoad %6 %255
+        %263 = OpSLessThan %40 %261 %262
+               OpBranchConditional %263 %257 %258
+        %257 = OpLabel
+        %266 = OpLoad %6 %255
+               OpStore %265 %266
+        %267 = OpFunctionCall %6 %22 %265
+               OpStore %264 %267
+        %268 = OpLoad %6 %255
+               OpSelectionMerge %271 None
+               OpSwitch %268 %270 9 %269 5 %269 12 %269 15 %269 7 %269 8 %269 2 %269 6 %269 17 %269 13 %269
+        %270 = OpLabel
+        %280 = OpLoad %6 %264
+        %281 = OpIEqual %40 %280 %28
+               OpSelectionMerge %283 None
+               OpBranchConditional %281 %282 %283
+        %282 = OpLabel
+        %284 = OpLoad %6 %254
+        %285 = OpIAdd %6 %284 %27
+               OpStore %254 %285
+               OpBranch %283
+        %283 = OpLabel
+               OpBranch %271
+        %269 = OpLabel
+        %272 = OpLoad %6 %264
+        %273 = OpLoad %6 %255
+        %274 = OpIEqual %40 %272 %273
+               OpSelectionMerge %276 None
+               OpBranchConditional %274 %275 %276
+        %275 = OpLabel
+        %277 = OpLoad %6 %254
+        %278 = OpIAdd %6 %277 %27
+               OpStore %254 %278
+               OpBranch %276
+        %276 = OpLabel
+               OpBranch %271
+        %271 = OpLabel
+               OpBranch %259
+        %259 = OpLabel
+        %288 = OpLoad %6 %255
+        %289 = OpIAdd %6 %288 %27
+               OpStore %255 %289
+               OpBranch %256
+        %258 = OpLabel
+        %290 = OpLoad %6 %254
+        %291 = OpIEqual %40 %290 %262
+               OpSelectionMerge %293 None
+               OpBranchConditional %291 %292 %300
+        %292 = OpLabel
+               OpStore %296 %299
+               OpBranch %293
+        %300 = OpLabel
+               OpStore %296 %301
+               OpBranch %293
+        %293 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %13 = OpFunction %2 None %10
+         %11 = OpFunctionParameter %8
+         %12 = OpFunctionParameter %9
+         %14 = OpLabel
+         %25 = OpLoad %6 %12
+         %26 = OpAccessChain %9 %11 %24
+               OpStore %26 %25
+         %29 = OpAccessChain %9 %11 %27
+               OpStore %29 %28
+         %31 = OpAccessChain %9 %11 %30
+               OpStore %31 %28
+               OpReturn
+               OpFunctionEnd
+         %18 = OpFunction %2 None %15
+         %16 = OpFunctionParameter %9
+         %17 = OpFunctionParameter %9
+         %19 = OpLabel
+         %32 = OpVariable %9 Function
+         %80 = OpVariable %8 Function
+         %84 = OpVariable %9 Function
+        %108 = OpVariable %9 Function
+        %126 = OpVariable %8 Function
+        %129 = OpVariable %9 Function
+               OpStore %32 %24
+               OpBranch %33
+         %33 = OpLabel
+               OpLoopMerge %35 %36 None
+               OpBranch %37
+         %37 = OpLabel
+         %38 = OpLoad %6 %32
+         %39 = OpLoad %6 %16
+         %41 = OpSLessThanEqual %40 %38 %39
+               OpBranchConditional %41 %34 %35
+         %34 = OpLabel
+         %42 = OpLoad %6 %17
+         %48 = OpLoad %6 %32
+         %50 = OpAccessChain %49 %47 %48 %24
+         %51 = OpLoad %6 %50
+         %52 = OpSLessThanEqual %40 %42 %51
+               OpSelectionMerge %54 None
+               OpBranchConditional %52 %53 %102
+         %53 = OpLabel
+         %55 = OpLoad %6 %32
+         %56 = OpAccessChain %49 %47 %55 %27
+         %57 = OpLoad %6 %56
+         %58 = OpIEqual %40 %57 %28
+               OpSelectionMerge %60 None
+               OpBranchConditional %58 %59 %97
+         %59 = OpLabel
+         %61 = OpLoad %6 %32
+         %62 = OpLoad %6 %16
+         %63 = OpAccessChain %49 %47 %61 %27
+               OpStore %63 %62
+         %71 = OpAccessChain %70 %68 %24 %69
+         %72 = OpLoad %64 %71
+         %74 = OpAccessChain %70 %68 %24 %73
+         %75 = OpLoad %64 %74
+         %76 = OpFOrdLessThan %40 %72 %75
+               OpSelectionMerge %78 None
+               OpBranchConditional %76 %77 %78
+         %77 = OpLabel
+         %79 = OpLoad %6 %16
+         %82 = OpAccessChain %81 %47 %79
+         %83 = OpLoad %7 %82
+               OpStore %80 %83
+         %85 = OpLoad %6 %17
+               OpStore %84 %85
+         %86 = OpFunctionCall %2 %13 %80 %84
+         %87 = OpLoad %7 %80
+         %88 = OpAccessChain %81 %47 %79
+               OpStore %88 %87
+               OpBranch %78
+         %78 = OpLabel
+         %89 = OpAccessChain %70 %68 %24 %69
+         %90 = OpLoad %64 %89
+         %91 = OpAccessChain %70 %68 %24 %73
+         %92 = OpLoad %64 %91
+         %93 = OpFOrdLessThan %40 %90 %92
+               OpSelectionMerge %95 None
+               OpBranchConditional %93 %94 %95
+         %94 = OpLabel
+               OpReturn
+         %95 = OpLabel
+               OpBranch %60
+         %97 = OpLabel
+         %98 = OpLoad %6 %32
+         %99 = OpAccessChain %49 %47 %98 %27
+        %100 = OpLoad %6 %99
+               OpStore %32 %100
+               OpBranch %36
+         %60 = OpLabel
+               OpBranch %54
+        %102 = OpLabel
+        %103 = OpAccessChain %70 %68 %24 %69
+        %104 = OpLoad %64 %103
+        %105 = OpAccessChain %70 %68 %24 %73
+        %106 = OpLoad %64 %105
+        %107 = OpFOrdLessThan %40 %104 %106
+               OpSelectionMerge %110 None
+               OpBranchConditional %107 %109 %114
+        %109 = OpLabel
+        %111 = OpLoad %6 %32
+        %112 = OpAccessChain %49 %47 %111 %30
+        %113 = OpLoad %6 %112
+               OpStore %108 %113
+               OpBranch %110
+        %114 = OpLabel
+        %115 = OpLoad %6 %32
+        %116 = OpAccessChain %49 %47 %115 %30
+        %117 = OpLoad %6 %116
+               OpStore %108 %117
+               OpBranch %110
+        %110 = OpLabel
+        %118 = OpLoad %6 %108
+        %119 = OpIEqual %40 %118 %28
+               OpSelectionMerge %121 None
+               OpBranchConditional %119 %120 %135
+        %120 = OpLabel
+        %122 = OpLoad %6 %32
+        %123 = OpLoad %6 %16
+        %124 = OpAccessChain %49 %47 %122 %30
+               OpStore %124 %123
+        %125 = OpLoad %6 %16
+        %127 = OpAccessChain %81 %47 %125
+        %128 = OpLoad %7 %127
+               OpStore %126 %128
+        %130 = OpLoad %6 %17
+               OpStore %129 %130
+        %131 = OpFunctionCall %2 %13 %126 %129
+        %132 = OpLoad %7 %126
+        %133 = OpAccessChain %81 %47 %125
+               OpStore %133 %132
+               OpReturn
+        %135 = OpLabel
+        %136 = OpLoad %6 %32
+        %137 = OpAccessChain %49 %47 %136 %30
+        %138 = OpLoad %6 %137
+               OpStore %32 %138
+               OpBranch %36
+        %121 = OpLabel
+               OpUnreachable
+         %54 = OpLabel
+        %140 = OpAccessChain %70 %68 %24 %69
+        %141 = OpLoad %64 %140
+        %142 = OpAccessChain %70 %68 %24 %73
+        %143 = OpLoad %64 %142
+        %144 = OpFOrdGreaterThan %40 %141 %143
+               OpSelectionMerge %146 None
+               OpBranchConditional %144 %145 %146
+        %145 = OpLabel
+               OpReturn
+        %146 = OpLabel
+               OpBranch %36
+         %36 = OpLabel
+               OpBranch %33
+         %35 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %22 = OpFunction %6 None %20
+         %21 = OpFunctionParameter %9
+         %23 = OpLabel
+        %148 = OpVariable %9 Function
+        %156 = OpVariable %8 Function
+        %172 = OpVariable %9 Function
+               OpStore %148 %24
+               OpBranch %149
+        %149 = OpLabel
+               OpLoopMerge %151 %152 None
+               OpBranch %153
+        %153 = OpLabel
+        %154 = OpLoad %6 %148
+        %155 = OpINotEqual %40 %154 %28
+               OpBranchConditional %155 %150 %151
+        %150 = OpLabel
+        %157 = OpLoad %6 %148
+        %158 = OpAccessChain %81 %47 %157
+        %159 = OpLoad %7 %158
+               OpStore %156 %159
+        %160 = OpAccessChain %9 %156 %24
+        %161 = OpLoad %6 %160
+        %162 = OpLoad %6 %21
+        %163 = OpIEqual %40 %161 %162
+               OpSelectionMerge %165 None
+               OpBranchConditional %163 %164 %165
+        %164 = OpLabel
+        %166 = OpLoad %6 %21
+               OpReturnValue %166
+        %165 = OpLabel
+        %168 = OpLoad %6 %21
+        %169 = OpAccessChain %9 %156 %24
+        %170 = OpLoad %6 %169
+        %171 = OpSGreaterThan %40 %168 %170
+               OpSelectionMerge %174 None
+               OpBranchConditional %171 %173 %177
+        %173 = OpLabel
+        %175 = OpAccessChain %9 %156 %30
+        %176 = OpLoad %6 %175
+               OpStore %172 %176
+               OpBranch %174
+        %177 = OpLabel
+        %178 = OpAccessChain %9 %156 %27
+        %179 = OpLoad %6 %178
+               OpStore %172 %179
+               OpBranch %174
+        %174 = OpLabel
+        %180 = OpLoad %6 %172
+               OpStore %148 %180
+               OpBranch %152
+        %152 = OpLabel
+               OpBranch %149
+        %151 = OpLabel
+               OpReturnValue %28
+               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 reference_framebuffer EQ_HISTOGRAM_EMD_BUFFER variant_framebuffer TOLERANCE 0.005
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-collatz-push-constant-with-nested-min-max.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-collatz-push-constant-with-nested-min-max.amber
new file mode 100644 (file)
index 0000000..be3de84
--- /dev/null
@@ -0,0 +1,551 @@
+#!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 push constant and nested min max
+
+# The test passes because both shaders render the same image.
+
+SHADER vertex reference_vertex_shader PASSTHROUGH
+
+# reference_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0 {
+#  vec2 resolution;
+# };
+# const vec4 pal[16] = vec4[16](vec4(0.0, 0.0, 0.0, 1.0), vec4(0.5, 0.0, 0.0, 1.0), vec4(0.0, 0.5, 0.0, 1.0), vec4(0.5, 0.5, 0.0, 1.0), vec4(0.0, 0.0, 0.5, 1.0), vec4(0.5, 0.0, 0.5, 1.0), vec4(0.0, 0.5, 0.5, 1.0), vec4(0.5, 0.5, 0.5, 1.0), vec4(0.0, 0.0, 0.0, 1.0), vec4(1.0, 0.0, 0.0, 1.0), vec4(0.0, 1.0, 0.0, 1.0), vec4(1.0, 1.0, 0.0, 1.0), vec4(0.0, 0.0, 1.0, 1.0), vec4(1.0, 0.0, 1.0, 1.0), vec4(0.0, 1.0, 1.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0));
+#
+# int collatz(int v)
+# {
+#  int count = 0;
+#  while(v > 1)
+#   {
+#    if((v & 1) == 1)
+#     {
+#      v = 3 * v + 1;
+#     }
+#    else
+#     {
+#      v /= 2;
+#     }
+#    count ++;
+#   }
+#  return count;
+# }
+# void main()
+# {
+#  vec2 lin = gl_FragCoord.xy / resolution;
+#  lin = floor(lin * 8.0);
+#  int v = int(lin.x) * 8 + int(lin.y);
+#  _GLF_color = pal[collatz(v) % 16];
+# }
+SHADER fragment reference_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 108
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %47 %76
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %10 "collatz(i1;"
+               OpName %9 "v"
+               OpName %12 "count"
+               OpName %44 "lin"
+               OpName %47 "gl_FragCoord"
+               OpName %50 "buf0"
+               OpMemberName %50 0 "resolution"
+               OpName %52 ""
+               OpName %61 "v"
+               OpName %76 "_GLF_color"
+               OpName %98 "param"
+               OpName %104 "indexable"
+               OpDecorate %47 BuiltIn FragCoord
+               OpMemberDecorate %50 0 Offset 0
+               OpDecorate %50 Block
+               OpDecorate %52 DescriptorSet 0
+               OpDecorate %52 Binding 0
+               OpDecorate %76 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypePointer Function %6
+          %8 = OpTypeFunction %6 %7
+         %13 = OpConstant %6 0
+         %20 = OpConstant %6 1
+         %21 = OpTypeBool
+         %28 = OpConstant %6 3
+         %33 = OpConstant %6 2
+         %41 = OpTypeFloat 32
+         %42 = OpTypeVector %41 2
+         %43 = OpTypePointer Function %42
+         %45 = OpTypeVector %41 4
+         %46 = OpTypePointer Input %45
+         %47 = OpVariable %46 Input
+         %50 = OpTypeStruct %42
+         %51 = OpTypePointer Uniform %50
+         %52 = OpVariable %51 Uniform
+         %53 = OpTypePointer Uniform %42
+         %58 = OpConstant %41 8
+         %62 = OpTypeInt 32 0
+         %63 = OpConstant %62 0
+         %64 = OpTypePointer Function %41
+         %68 = OpConstant %6 8
+         %70 = OpConstant %62 1
+         %75 = OpTypePointer Output %45
+         %76 = OpVariable %75 Output
+         %77 = OpConstant %62 16
+         %78 = OpTypeArray %45 %77
+         %79 = OpConstant %41 0
+         %80 = OpConstant %41 1
+         %81 = OpConstantComposite %45 %79 %79 %79 %80
+         %82 = OpConstant %41 0.5
+         %83 = OpConstantComposite %45 %82 %79 %79 %80
+         %84 = OpConstantComposite %45 %79 %82 %79 %80
+         %85 = OpConstantComposite %45 %82 %82 %79 %80
+         %86 = OpConstantComposite %45 %79 %79 %82 %80
+         %87 = OpConstantComposite %45 %82 %79 %82 %80
+         %88 = OpConstantComposite %45 %79 %82 %82 %80
+         %89 = OpConstantComposite %45 %82 %82 %82 %80
+         %90 = OpConstantComposite %45 %80 %79 %79 %80
+         %91 = OpConstantComposite %45 %79 %80 %79 %80
+         %92 = OpConstantComposite %45 %80 %80 %79 %80
+         %93 = OpConstantComposite %45 %79 %79 %80 %80
+         %94 = OpConstantComposite %45 %80 %79 %80 %80
+         %95 = OpConstantComposite %45 %79 %80 %80 %80
+         %96 = OpConstantComposite %45 %80 %80 %80 %80
+         %97 = OpConstantComposite %78 %81 %83 %84 %85 %86 %87 %88 %89 %81 %90 %91 %92 %93 %94 %95 %96
+        %101 = OpConstant %6 16
+        %103 = OpTypePointer Function %78
+        %105 = OpTypePointer Function %45
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %44 = OpVariable %43 Function
+         %61 = OpVariable %7 Function
+         %98 = OpVariable %7 Function
+        %104 = OpVariable %103 Function
+         %48 = OpLoad %45 %47
+         %49 = OpVectorShuffle %42 %48 %48 0 1
+         %54 = OpAccessChain %53 %52 %13
+         %55 = OpLoad %42 %54
+         %56 = OpFDiv %42 %49 %55
+               OpStore %44 %56
+         %57 = OpLoad %42 %44
+         %59 = OpVectorTimesScalar %42 %57 %58
+         %60 = OpExtInst %42 %1 Floor %59
+               OpStore %44 %60
+         %65 = OpAccessChain %64 %44 %63
+         %66 = OpLoad %41 %65
+         %67 = OpConvertFToS %6 %66
+         %69 = OpIMul %6 %67 %68
+         %71 = OpAccessChain %64 %44 %70
+         %72 = OpLoad %41 %71
+         %73 = OpConvertFToS %6 %72
+         %74 = OpIAdd %6 %69 %73
+               OpStore %61 %74
+         %99 = OpLoad %6 %61
+               OpStore %98 %99
+        %100 = OpFunctionCall %6 %10 %98
+        %102 = OpSMod %6 %100 %101
+               OpStore %104 %97
+        %106 = OpAccessChain %105 %104 %102
+        %107 = OpLoad %45 %106
+               OpStore %76 %107
+               OpReturn
+               OpFunctionEnd
+         %10 = OpFunction %6 None %8
+          %9 = OpFunctionParameter %7
+         %11 = OpLabel
+         %12 = OpVariable %7 Function
+               OpStore %12 %13
+               OpBranch %14
+         %14 = OpLabel
+               OpLoopMerge %16 %17 None
+               OpBranch %18
+         %18 = OpLabel
+         %19 = OpLoad %6 %9
+         %22 = OpSGreaterThan %21 %19 %20
+               OpBranchConditional %22 %15 %16
+         %15 = OpLabel
+         %23 = OpLoad %6 %9
+         %24 = OpBitwiseAnd %6 %23 %20
+         %25 = OpIEqual %21 %24 %20
+               OpSelectionMerge %27 None
+               OpBranchConditional %25 %26 %32
+         %26 = OpLabel
+         %29 = OpLoad %6 %9
+         %30 = OpIMul %6 %28 %29
+         %31 = OpIAdd %6 %30 %20
+               OpStore %9 %31
+               OpBranch %27
+         %32 = OpLabel
+         %34 = OpLoad %6 %9
+         %35 = OpSDiv %6 %34 %33
+               OpStore %9 %35
+               OpBranch %27
+         %27 = OpLabel
+         %36 = OpLoad %6 %12
+         %37 = OpIAdd %6 %36 %20
+               OpStore %12 %37
+               OpBranch %17
+         %17 = OpLabel
+               OpBranch %14
+         %16 = OpLabel
+         %38 = OpLoad %6 %12
+               OpReturnValue %38
+               OpFunctionEnd
+END
+
+# uniforms for reference
+
+# resolution
+BUFFER reference_resolution DATA_TYPE vec2<float> DATA
+ 256.0 256.0
+END
+
+BUFFER reference_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics reference_pipeline
+  ATTACH reference_vertex_shader
+  ATTACH reference_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER reference_framebuffer AS color LOCATION 0
+  BIND BUFFER reference_resolution AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR reference_pipeline 0 0 0 255
+
+CLEAR reference_pipeline
+RUN reference_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(push_constant) uniform buf_push {
+#  vec2 resolution;
+# };
+# const vec4 pal[16] = vec4[16](vec4(0.0, 0.0, 0.0, 1.0), vec4(0.5, 0.0, 0.0, 1.0), vec4(0.0, 0.5, 0.0, 1.0), vec4(0.5, 0.5, 0.0, 1.0), vec4(0.0, 0.0, 0.5, 1.0), vec4(0.5, 0.0, 0.5, 1.0), vec4(0.0, 0.5, 0.5, 1.0), vec4(0.5, 0.5, 0.5, 1.0), vec4(0.0, 0.0, 0.0, 1.0), vec4(1.0, 0.0, 0.0, 1.0), vec4(0.0, 1.0, 0.0, 1.0), vec4(1.0, 1.0, 0.0, 1.0), vec4(0.0, 0.0, 1.0, 1.0), vec4(1.0, 0.0, 1.0, 1.0), vec4(0.0, 1.0, 1.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0));
+#
+# int collatz(int v)
+# {
+#  int count = 0;
+#  while(v > 1)
+#   {
+#    if((v & 1) == 1)
+#     {
+#      v = 3 * v + 1;
+#     }
+#    else
+#     {
+#      v /= 2;
+#     }
+#    count ++;
+#   }
+#  return count;
+# }
+# void main()
+# {
+#     // vec2 max_c == (gl_FragCoord.xy / resolution).
+#     vec2 max_c = max(   // This should return the same result.
+#                         gl_FragCoord.xy / resolution,
+#                         gl_FragCoord.xy / (vec2(resolution.x, resolution.y))
+#                     );
+#     // vec2 max_a == (gl_FragCoord.xy / resolution)
+#     vec2 max_a = max(
+#                         // gl_FragCoord.y < 0 is always false.
+#                         // mix operation returns vec2(0.0 , 0.0).
+#                         // cosine of 0 is 1.
+#                         // anything divided by 1 stays the same.
+#                         max_c / cos(mix(vec2(1.0, 0.0), vec2(0.0, 218.851), bvec2(true, (gl_FragCoord.y < 0.0)))),
+#                         gl_FragCoord.xy / resolution
+#                     );
+#     // vec2 max_d == vec2(1.0, 1.0)
+#     vec2 max_d = max(
+#                         // Same cosine fucntion as in max_a.
+#                         1.0 / cos(mix(vec2(1.0, 0.0), vec2(0.0, 218.851), bvec2(true, (gl_FragCoord.y < 0.0)))),
+#                         vec2(1.0, 1.0)
+#                     );
+#     // vec2 max_b == vec2(1.0, 1.0)
+#     vec2 max_b = max(
+#                         vec2(1.0, 1.0),
+#                         max_d // max_d == vec2(1.0, 1.0)
+#                     );
+#     // vec2 lin == (gl_FragCoord.xy / resolution)
+#     vec2 lin = min(
+#                     max_a,  // max_a == gl_FragCoord.xy / resolution
+#                     max_b   // max_b == vec2(1.0, 1.0)
+#                     );
+#  lin = floor(lin * 8.0);
+#  int v = int(lin.x) * 8 + int(lin.y);
+#  _GLF_color = pal[collatz(v) % 16];
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 157
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %47 %127
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %10 "collatz(i1;"
+               OpName %9 "v"
+               OpName %12 "count"
+               OpName %44 "max_c"
+               OpName %47 "gl_FragCoord"
+               OpName %50 "buf_push"
+               OpMemberName %50 0 "resolution"
+               OpName %52 ""
+               OpName %70 "max_a"
+               OpName %93 "max_d"
+               OpName %104 "max_b"
+               OpName %107 "lin"
+               OpName %115 "v"
+               OpName %127 "_GLF_color"
+               OpName %147 "param"
+               OpName %153 "indexable"
+               OpDecorate %47 BuiltIn FragCoord
+               OpMemberDecorate %50 0 Offset 0
+               OpDecorate %50 Block
+               OpDecorate %127 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypePointer Function %6
+          %8 = OpTypeFunction %6 %7
+         %13 = OpConstant %6 0
+         %20 = OpConstant %6 1
+         %21 = OpTypeBool
+         %28 = OpConstant %6 3
+         %33 = OpConstant %6 2
+         %41 = OpTypeFloat 32
+         %42 = OpTypeVector %41 2
+         %43 = OpTypePointer Function %42
+         %45 = OpTypeVector %41 4
+         %46 = OpTypePointer Input %45
+         %47 = OpVariable %46 Input
+         %50 = OpTypeStruct %42
+         %51 = OpTypePointer PushConstant %50
+         %52 = OpVariable %51 PushConstant
+         %53 = OpTypePointer PushConstant %42
+         %59 = OpTypeInt 32 0
+         %60 = OpConstant %59 0
+         %61 = OpTypePointer PushConstant %41
+         %64 = OpConstant %59 1
+         %72 = OpConstant %41 1
+         %73 = OpConstant %41 0
+         %74 = OpConstantComposite %42 %72 %73
+         %75 = OpConstant %41 218.850998
+         %76 = OpConstantComposite %42 %73 %75
+         %77 = OpConstantTrue %21
+         %78 = OpTypePointer Input %41
+         %82 = OpTypeVector %21 2
+        %102 = OpConstantComposite %42 %72 %72
+        %112 = OpConstant %41 8
+        %116 = OpTypePointer Function %41
+        %120 = OpConstant %6 8
+        %126 = OpTypePointer Output %45
+        %127 = OpVariable %126 Output
+        %128 = OpConstant %59 16
+        %129 = OpTypeArray %45 %128
+        %130 = OpConstantComposite %45 %73 %73 %73 %72
+        %131 = OpConstant %41 0.5
+        %132 = OpConstantComposite %45 %131 %73 %73 %72
+        %133 = OpConstantComposite %45 %73 %131 %73 %72
+        %134 = OpConstantComposite %45 %131 %131 %73 %72
+        %135 = OpConstantComposite %45 %73 %73 %131 %72
+        %136 = OpConstantComposite %45 %131 %73 %131 %72
+        %137 = OpConstantComposite %45 %73 %131 %131 %72
+        %138 = OpConstantComposite %45 %131 %131 %131 %72
+        %139 = OpConstantComposite %45 %72 %73 %73 %72
+        %140 = OpConstantComposite %45 %73 %72 %73 %72
+        %141 = OpConstantComposite %45 %72 %72 %73 %72
+        %142 = OpConstantComposite %45 %73 %73 %72 %72
+        %143 = OpConstantComposite %45 %72 %73 %72 %72
+        %144 = OpConstantComposite %45 %73 %72 %72 %72
+        %145 = OpConstantComposite %45 %72 %72 %72 %72
+        %146 = OpConstantComposite %129 %130 %132 %133 %134 %135 %136 %137 %138 %130 %139 %140 %141 %142 %143 %144 %145
+        %150 = OpConstant %6 16
+        %152 = OpTypePointer Function %129
+        %154 = OpTypePointer Function %45
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %44 = OpVariable %43 Function
+         %70 = OpVariable %43 Function
+         %93 = OpVariable %43 Function
+        %104 = OpVariable %43 Function
+        %107 = OpVariable %43 Function
+        %115 = OpVariable %7 Function
+        %147 = OpVariable %7 Function
+        %153 = OpVariable %152 Function
+         %48 = OpLoad %45 %47
+         %49 = OpVectorShuffle %42 %48 %48 0 1
+         %54 = OpAccessChain %53 %52 %13
+         %55 = OpLoad %42 %54
+         %56 = OpFDiv %42 %49 %55
+         %57 = OpLoad %45 %47
+         %58 = OpVectorShuffle %42 %57 %57 0 1
+         %62 = OpAccessChain %61 %52 %13 %60
+         %63 = OpLoad %41 %62
+         %65 = OpAccessChain %61 %52 %13 %64
+         %66 = OpLoad %41 %65
+         %67 = OpCompositeConstruct %42 %63 %66
+         %68 = OpFDiv %42 %58 %67
+         %69 = OpExtInst %42 %1 FMax %56 %68
+               OpStore %44 %69
+         %71 = OpLoad %42 %44
+         %79 = OpAccessChain %78 %47 %64
+         %80 = OpLoad %41 %79
+         %81 = OpFOrdLessThan %21 %80 %73
+         %83 = OpCompositeConstruct %82 %77 %81
+         %84 = OpSelect %42 %83 %76 %74
+         %85 = OpExtInst %42 %1 Cos %84
+         %86 = OpFDiv %42 %71 %85
+         %87 = OpLoad %45 %47
+         %88 = OpVectorShuffle %42 %87 %87 0 1
+         %89 = OpAccessChain %53 %52 %13
+         %90 = OpLoad %42 %89
+         %91 = OpFDiv %42 %88 %90
+         %92 = OpExtInst %42 %1 FMax %86 %91
+               OpStore %70 %92
+         %94 = OpAccessChain %78 %47 %64
+         %95 = OpLoad %41 %94
+         %96 = OpFOrdLessThan %21 %95 %73
+         %97 = OpCompositeConstruct %82 %77 %96
+         %98 = OpSelect %42 %97 %76 %74
+         %99 = OpExtInst %42 %1 Cos %98
+        %100 = OpCompositeConstruct %42 %72 %72
+        %101 = OpFDiv %42 %100 %99
+        %103 = OpExtInst %42 %1 FMax %101 %102
+               OpStore %93 %103
+        %105 = OpLoad %42 %93
+        %106 = OpExtInst %42 %1 FMax %102 %105
+               OpStore %104 %106
+        %108 = OpLoad %42 %70
+        %109 = OpLoad %42 %104
+        %110 = OpExtInst %42 %1 FMin %108 %109
+               OpStore %107 %110
+        %111 = OpLoad %42 %107
+        %113 = OpVectorTimesScalar %42 %111 %112
+        %114 = OpExtInst %42 %1 Floor %113
+               OpStore %107 %114
+        %117 = OpAccessChain %116 %107 %60
+        %118 = OpLoad %41 %117
+        %119 = OpConvertFToS %6 %118
+        %121 = OpIMul %6 %119 %120
+        %122 = OpAccessChain %116 %107 %64
+        %123 = OpLoad %41 %122
+        %124 = OpConvertFToS %6 %123
+        %125 = OpIAdd %6 %121 %124
+               OpStore %115 %125
+        %148 = OpLoad %6 %115
+               OpStore %147 %148
+        %149 = OpFunctionCall %6 %10 %147
+        %151 = OpSMod %6 %149 %150
+               OpStore %153 %146
+        %155 = OpAccessChain %154 %153 %151
+        %156 = OpLoad %45 %155
+               OpStore %127 %156
+               OpReturn
+               OpFunctionEnd
+         %10 = OpFunction %6 None %8
+          %9 = OpFunctionParameter %7
+         %11 = OpLabel
+         %12 = OpVariable %7 Function
+               OpStore %12 %13
+               OpBranch %14
+         %14 = OpLabel
+               OpLoopMerge %16 %17 None
+               OpBranch %18
+         %18 = OpLabel
+         %19 = OpLoad %6 %9
+         %22 = OpSGreaterThan %21 %19 %20
+               OpBranchConditional %22 %15 %16
+         %15 = OpLabel
+         %23 = OpLoad %6 %9
+         %24 = OpBitwiseAnd %6 %23 %20
+         %25 = OpIEqual %21 %24 %20
+               OpSelectionMerge %27 None
+               OpBranchConditional %25 %26 %32
+         %26 = OpLabel
+         %29 = OpLoad %6 %9
+         %30 = OpIMul %6 %28 %29
+         %31 = OpIAdd %6 %30 %20
+               OpStore %9 %31
+               OpBranch %27
+         %32 = OpLabel
+         %34 = OpLoad %6 %9
+         %35 = OpSDiv %6 %34 %33
+               OpStore %9 %35
+               OpBranch %27
+         %27 = OpLabel
+         %36 = OpLoad %6 %12
+         %37 = OpIAdd %6 %36 %20
+               OpStore %12 %37
+               OpBranch %17
+         %17 = OpLabel
+               OpBranch %14
+         %16 = OpLabel
+         %38 = OpLoad %6 %12
+               OpReturnValue %38
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# resolution
+BUFFER variant_resolution DATA_TYPE vec2<float> DATA
+ 256.0 256.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 push_constant
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT reference_framebuffer EQ_HISTOGRAM_EMD_BUFFER variant_framebuffer TOLERANCE 0.005
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-mergesort-reversed-for-loop.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-mergesort-reversed-for-loop.amber
new file mode 100644 (file)
index 0000000..03dcbca
--- /dev/null
@@ -0,0 +1,1552 @@
+#!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 once iterated reversed for loop
+
+# The test passes because both shaders render the same image.
+
+SHADER vertex reference_vertex_shader PASSTHROUGH
+
+# reference_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch;
+# };
+# const int N = 10;
+#
+# int data[10], temp[10];
+#
+# void merge(int from, int mid, int to)
+# {
+#     int k = from, i = from, j = mid + 1;
+#     while (i <= mid && j <= to)
+#     {
+#         if (data[i] < data[j])
+#         {
+#             temp[k++] = data[i++];
+#         }
+#         else
+#         {
+#             temp[k++] = data[j++];
+#         }
+#     }
+#     while (i < N && i <= mid)
+#     {
+#         temp[k++] = data[i++];
+#     }
+#     for (int i = from; i <= to; i++)
+#     {
+#         data[i] = temp[i];
+#     }
+# }
+# void mergeSort()
+# {
+#     int low = 0;
+#     int high = N - 1;
+#     for (int m = 1; m <= high; m = 2 * m)
+#     {
+#         for (int i = low; i < high; i += 2 * m)
+#         {
+#             int from = i;
+#             int mid = i + m - 1;
+#             int to = min(i + 2 * m - 1, high);
+#             merge(from, mid, to);
+#         }
+#     }
+# }
+# void main()
+# {
+#     int i = int(injectionSwitch.x);
+#     do
+#     {
+#         switch (i)
+#         {
+#         case 0:
+#             data[i] = 4;
+#             break;
+#         case 1:
+#             data[i] = 3;
+#             break;
+#         case 2:
+#             data[i] = 2;
+#             break;
+#         case 3:
+#             data[i] = 1;
+#             break;
+#         case 4:
+#             data[i] = 0;
+#             break;
+#         case 5:
+#             data[i] = -1;
+#             break;
+#         case 6:
+#             data[i] = -2;
+#             break;
+#         case 7:
+#             data[i] = -3;
+#             break;
+#         case 8:
+#             data[i] = -4;
+#             break;
+#         case 9:
+#             data[i] = -5;
+#             break;
+#         }
+#         i++;
+#     } while (i < 10);
+#     for (int j = 0; j < 10; j++)
+#     {
+#         temp[j] = data[j];
+#     }
+#     mergeSort();
+#     float grey;
+#     if (int(gl_FragCoord[1]) < 30)
+#     {
+#         grey = 0.5 + float(data[0]) / 10.0;
+#     }
+#     else
+#     {
+#         if (int(gl_FragCoord[1]) < 60)
+#         {
+#             grey = 0.5 + float(data[1]) / 10.0;
+#         }
+#         else
+#         {
+#             if (int(gl_FragCoord[1]) < 90)
+#             {
+#                 grey = 0.5 + float(data[2]) / 10.0;
+#             }
+#             else
+#             {
+#                 if (int(gl_FragCoord[1]) < 120)
+#                 {
+#                     grey = 0.5 + float(data[3]) / 10.0;
+#                 }
+#                 else
+#                 {
+#                     if (int(gl_FragCoord[1]) < 150)
+#                     {
+#                         discard;
+#                     }
+#                     else
+#                     {
+#                         if (int(gl_FragCoord[1]) < 180)
+#                         {
+#                             grey = 0.5 + float(data[5]) / 10.0;
+#                         }
+#                         else
+#                         {
+#                             if (int(gl_FragCoord[1]) < 210)
+#                             {
+#                                 grey = 0.5 + float(data[6]) / 10.0;
+#                             }
+#                             else
+#                             {
+#                                 if (int(gl_FragCoord[1]) < 240)
+#                                 {
+#                                     grey = 0.5 + float(data[7]) / 10.0;
+#                                 }
+#                                 else
+#                                 {
+#                                     if (int(gl_FragCoord[1]) < 270)
+#                                     {
+#                                         grey = 0.5 + float(data[8]) / 10.0;
+#                                     }
+#                                     else
+#                                     {
+#                                         discard;
+#                                     }
+#                                 }
+#                             }
+#                         }
+#                     }
+#                 }
+#             }
+#         }
+#     }
+#     _GLF_color = vec4(vec3(grey), 1.0);
+# }
+SHADER fragment reference_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 378
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %243 %369
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %12 "merge(i1;i1;i1;"
+               OpName %9 "from"
+               OpName %10 "mid"
+               OpName %11 "to"
+               OpName %14 "mergeSort("
+               OpName %16 "k"
+               OpName %18 "i"
+               OpName %20 "j"
+               OpName %41 "data"
+               OpName %52 "temp"
+               OpName %87 "i"
+               OpName %104 "low"
+               OpName %106 "high"
+               OpName %108 "m"
+               OpName %117 "i"
+               OpName %127 "from"
+               OpName %129 "mid"
+               OpName %134 "to"
+               OpName %143 "param"
+               OpName %145 "param"
+               OpName %147 "param"
+               OpName %156 "i"
+               OpName %159 "buf0"
+               OpMemberName %159 0 "injectionSwitch"
+               OpName %161 ""
+               OpName %225 "j"
+               OpName %243 "gl_FragCoord"
+               OpName %254 "grey"
+               OpName %369 "_GLF_color"
+               OpMemberDecorate %159 0 Offset 0
+               OpDecorate %159 Block
+               OpDecorate %161 DescriptorSet 0
+               OpDecorate %161 Binding 0
+               OpDecorate %243 BuiltIn FragCoord
+               OpDecorate %369 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypePointer Function %6
+          %8 = OpTypeFunction %2 %7 %7 %7
+         %22 = OpConstant %6 1
+         %31 = OpTypeBool
+         %37 = OpTypeInt 32 0
+         %38 = OpConstant %37 10
+         %39 = OpTypeArray %6 %38
+         %40 = OpTypePointer Private %39
+         %41 = OpVariable %40 Private
+         %43 = OpTypePointer Private %6
+         %52 = OpVariable %40 Private
+         %74 = OpConstant %6 10
+        %105 = OpConstant %6 0
+        %107 = OpConstant %6 9
+        %136 = OpConstant %6 2
+        %157 = OpTypeFloat 32
+        %158 = OpTypeVector %157 2
+        %159 = OpTypeStruct %158
+        %160 = OpTypePointer Uniform %159
+        %161 = OpVariable %160 Uniform
+        %162 = OpConstant %37 0
+        %163 = OpTypePointer Uniform %157
+        %184 = OpConstant %6 4
+        %188 = OpConstant %6 3
+        %201 = OpConstant %6 -1
+        %205 = OpConstant %6 -2
+        %209 = OpConstant %6 -3
+        %213 = OpConstant %6 -4
+        %217 = OpConstant %6 -5
+        %241 = OpTypeVector %157 4
+        %242 = OpTypePointer Input %241
+        %243 = OpVariable %242 Input
+        %244 = OpConstant %37 1
+        %245 = OpTypePointer Input %157
+        %249 = OpConstant %6 30
+        %253 = OpTypePointer Function %157
+        %255 = OpConstant %157 0.5
+        %259 = OpConstant %157 10
+        %266 = OpConstant %6 60
+        %279 = OpConstant %6 90
+        %292 = OpConstant %6 120
+        %305 = OpConstant %6 150
+        %314 = OpConstant %6 180
+        %318 = OpConstant %6 5
+        %328 = OpConstant %6 210
+        %332 = OpConstant %6 6
+        %342 = OpConstant %6 240
+        %346 = OpConstant %6 7
+        %356 = OpConstant %6 270
+        %360 = OpConstant %6 8
+        %368 = OpTypePointer Output %241
+        %369 = OpVariable %368 Output
+        %371 = OpTypeVector %157 3
+        %373 = OpConstant %157 1
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %156 = OpVariable %7 Function
+        %225 = OpVariable %7 Function
+        %254 = OpVariable %253 Function
+        %164 = OpAccessChain %163 %161 %105 %162
+        %165 = OpLoad %157 %164
+        %166 = OpConvertFToS %6 %165
+               OpStore %156 %166
+               OpBranch %167
+        %167 = OpLabel
+               OpLoopMerge %169 %170 None
+               OpBranch %168
+        %168 = OpLabel
+        %171 = OpLoad %6 %156
+               OpSelectionMerge %182 None
+               OpSwitch %171 %182 0 %172 1 %173 2 %174 3 %175 4 %176 5 %177 6 %178 7 %179 8 %180 9 %181
+        %172 = OpLabel
+        %183 = OpLoad %6 %156
+        %185 = OpAccessChain %43 %41 %183
+               OpStore %185 %184
+               OpBranch %182
+        %173 = OpLabel
+        %187 = OpLoad %6 %156
+        %189 = OpAccessChain %43 %41 %187
+               OpStore %189 %188
+               OpBranch %182
+        %174 = OpLabel
+        %191 = OpLoad %6 %156
+        %192 = OpAccessChain %43 %41 %191
+               OpStore %192 %136
+               OpBranch %182
+        %175 = OpLabel
+        %194 = OpLoad %6 %156
+        %195 = OpAccessChain %43 %41 %194
+               OpStore %195 %22
+               OpBranch %182
+        %176 = OpLabel
+        %197 = OpLoad %6 %156
+        %198 = OpAccessChain %43 %41 %197
+               OpStore %198 %105
+               OpBranch %182
+        %177 = OpLabel
+        %200 = OpLoad %6 %156
+        %202 = OpAccessChain %43 %41 %200
+               OpStore %202 %201
+               OpBranch %182
+        %178 = OpLabel
+        %204 = OpLoad %6 %156
+        %206 = OpAccessChain %43 %41 %204
+               OpStore %206 %205
+               OpBranch %182
+        %179 = OpLabel
+        %208 = OpLoad %6 %156
+        %210 = OpAccessChain %43 %41 %208
+               OpStore %210 %209
+               OpBranch %182
+        %180 = OpLabel
+        %212 = OpLoad %6 %156
+        %214 = OpAccessChain %43 %41 %212
+               OpStore %214 %213
+               OpBranch %182
+        %181 = OpLabel
+        %216 = OpLoad %6 %156
+        %218 = OpAccessChain %43 %41 %216
+               OpStore %218 %217
+               OpBranch %182
+        %182 = OpLabel
+        %221 = OpLoad %6 %156
+        %222 = OpIAdd %6 %221 %22
+               OpStore %156 %222
+               OpBranch %170
+        %170 = OpLabel
+        %223 = OpLoad %6 %156
+        %224 = OpSLessThan %31 %223 %74
+               OpBranchConditional %224 %167 %169
+        %169 = OpLabel
+               OpStore %225 %105
+               OpBranch %226
+        %226 = OpLabel
+               OpLoopMerge %228 %229 None
+               OpBranch %230
+        %230 = OpLabel
+        %231 = OpLoad %6 %225
+        %232 = OpSLessThan %31 %231 %74
+               OpBranchConditional %232 %227 %228
+        %227 = OpLabel
+        %233 = OpLoad %6 %225
+        %234 = OpLoad %6 %225
+        %235 = OpAccessChain %43 %41 %234
+        %236 = OpLoad %6 %235
+        %237 = OpAccessChain %43 %52 %233
+               OpStore %237 %236
+               OpBranch %229
+        %229 = OpLabel
+        %238 = OpLoad %6 %225
+        %239 = OpIAdd %6 %238 %22
+               OpStore %225 %239
+               OpBranch %226
+        %228 = OpLabel
+        %240 = OpFunctionCall %2 %14
+        %246 = OpAccessChain %245 %243 %244
+        %247 = OpLoad %157 %246
+        %248 = OpConvertFToS %6 %247
+        %250 = OpSLessThan %31 %248 %249
+               OpSelectionMerge %252 None
+               OpBranchConditional %250 %251 %262
+        %251 = OpLabel
+        %256 = OpAccessChain %43 %41 %105
+        %257 = OpLoad %6 %256
+        %258 = OpConvertSToF %157 %257
+        %260 = OpFDiv %157 %258 %259
+        %261 = OpFAdd %157 %255 %260
+               OpStore %254 %261
+               OpBranch %252
+        %262 = OpLabel
+        %263 = OpAccessChain %245 %243 %244
+        %264 = OpLoad %157 %263
+        %265 = OpConvertFToS %6 %264
+        %267 = OpSLessThan %31 %265 %266
+               OpSelectionMerge %269 None
+               OpBranchConditional %267 %268 %275
+        %268 = OpLabel
+        %270 = OpAccessChain %43 %41 %22
+        %271 = OpLoad %6 %270
+        %272 = OpConvertSToF %157 %271
+        %273 = OpFDiv %157 %272 %259
+        %274 = OpFAdd %157 %255 %273
+               OpStore %254 %274
+               OpBranch %269
+        %275 = OpLabel
+        %276 = OpAccessChain %245 %243 %244
+        %277 = OpLoad %157 %276
+        %278 = OpConvertFToS %6 %277
+        %280 = OpSLessThan %31 %278 %279
+               OpSelectionMerge %282 None
+               OpBranchConditional %280 %281 %288
+        %281 = OpLabel
+        %283 = OpAccessChain %43 %41 %136
+        %284 = OpLoad %6 %283
+        %285 = OpConvertSToF %157 %284
+        %286 = OpFDiv %157 %285 %259
+        %287 = OpFAdd %157 %255 %286
+               OpStore %254 %287
+               OpBranch %282
+        %288 = OpLabel
+        %289 = OpAccessChain %245 %243 %244
+        %290 = OpLoad %157 %289
+        %291 = OpConvertFToS %6 %290
+        %293 = OpSLessThan %31 %291 %292
+               OpSelectionMerge %295 None
+               OpBranchConditional %293 %294 %301
+        %294 = OpLabel
+        %296 = OpAccessChain %43 %41 %188
+        %297 = OpLoad %6 %296
+        %298 = OpConvertSToF %157 %297
+        %299 = OpFDiv %157 %298 %259
+        %300 = OpFAdd %157 %255 %299
+               OpStore %254 %300
+               OpBranch %295
+        %301 = OpLabel
+        %302 = OpAccessChain %245 %243 %244
+        %303 = OpLoad %157 %302
+        %304 = OpConvertFToS %6 %303
+        %306 = OpSLessThan %31 %304 %305
+               OpSelectionMerge %308 None
+               OpBranchConditional %306 %307 %310
+        %307 = OpLabel
+               OpKill
+        %310 = OpLabel
+        %311 = OpAccessChain %245 %243 %244
+        %312 = OpLoad %157 %311
+        %313 = OpConvertFToS %6 %312
+        %315 = OpSLessThan %31 %313 %314
+               OpSelectionMerge %317 None
+               OpBranchConditional %315 %316 %324
+        %316 = OpLabel
+        %319 = OpAccessChain %43 %41 %318
+        %320 = OpLoad %6 %319
+        %321 = OpConvertSToF %157 %320
+        %322 = OpFDiv %157 %321 %259
+        %323 = OpFAdd %157 %255 %322
+               OpStore %254 %323
+               OpBranch %317
+        %324 = OpLabel
+        %325 = OpAccessChain %245 %243 %244
+        %326 = OpLoad %157 %325
+        %327 = OpConvertFToS %6 %326
+        %329 = OpSLessThan %31 %327 %328
+               OpSelectionMerge %331 None
+               OpBranchConditional %329 %330 %338
+        %330 = OpLabel
+        %333 = OpAccessChain %43 %41 %332
+        %334 = OpLoad %6 %333
+        %335 = OpConvertSToF %157 %334
+        %336 = OpFDiv %157 %335 %259
+        %337 = OpFAdd %157 %255 %336
+               OpStore %254 %337
+               OpBranch %331
+        %338 = OpLabel
+        %339 = OpAccessChain %245 %243 %244
+        %340 = OpLoad %157 %339
+        %341 = OpConvertFToS %6 %340
+        %343 = OpSLessThan %31 %341 %342
+               OpSelectionMerge %345 None
+               OpBranchConditional %343 %344 %352
+        %344 = OpLabel
+        %347 = OpAccessChain %43 %41 %346
+        %348 = OpLoad %6 %347
+        %349 = OpConvertSToF %157 %348
+        %350 = OpFDiv %157 %349 %259
+        %351 = OpFAdd %157 %255 %350
+               OpStore %254 %351
+               OpBranch %345
+        %352 = OpLabel
+        %353 = OpAccessChain %245 %243 %244
+        %354 = OpLoad %157 %353
+        %355 = OpConvertFToS %6 %354
+        %357 = OpSLessThan %31 %355 %356
+               OpSelectionMerge %359 None
+               OpBranchConditional %357 %358 %366
+        %358 = OpLabel
+        %361 = OpAccessChain %43 %41 %360
+        %362 = OpLoad %6 %361
+        %363 = OpConvertSToF %157 %362
+        %364 = OpFDiv %157 %363 %259
+        %365 = OpFAdd %157 %255 %364
+               OpStore %254 %365
+               OpBranch %359
+        %366 = OpLabel
+               OpKill
+        %359 = OpLabel
+               OpBranch %345
+        %345 = OpLabel
+               OpBranch %331
+        %331 = OpLabel
+               OpBranch %317
+        %317 = OpLabel
+               OpBranch %308
+        %308 = OpLabel
+               OpBranch %295
+        %295 = OpLabel
+               OpBranch %282
+        %282 = OpLabel
+               OpBranch %269
+        %269 = OpLabel
+               OpBranch %252
+        %252 = OpLabel
+        %370 = OpLoad %157 %254
+        %372 = OpCompositeConstruct %371 %370 %370 %370
+        %374 = OpCompositeExtract %157 %372 0
+        %375 = OpCompositeExtract %157 %372 1
+        %376 = OpCompositeExtract %157 %372 2
+        %377 = OpCompositeConstruct %241 %374 %375 %376 %373
+               OpStore %369 %377
+               OpReturn
+               OpFunctionEnd
+         %12 = OpFunction %2 None %8
+          %9 = OpFunctionParameter %7
+         %10 = OpFunctionParameter %7
+         %11 = OpFunctionParameter %7
+         %13 = OpLabel
+         %16 = OpVariable %7 Function
+         %18 = OpVariable %7 Function
+         %20 = OpVariable %7 Function
+         %87 = OpVariable %7 Function
+         %17 = OpLoad %6 %9
+               OpStore %16 %17
+         %19 = OpLoad %6 %9
+               OpStore %18 %19
+         %21 = OpLoad %6 %10
+         %23 = OpIAdd %6 %21 %22
+               OpStore %20 %23
+               OpBranch %24
+         %24 = OpLabel
+               OpLoopMerge %26 %27 None
+               OpBranch %28
+         %28 = OpLabel
+         %29 = OpLoad %6 %18
+         %30 = OpLoad %6 %10
+         %32 = OpSLessThanEqual %31 %29 %30
+         %33 = OpLoad %6 %20
+         %34 = OpLoad %6 %11
+         %35 = OpSLessThanEqual %31 %33 %34
+         %36 = OpLogicalAnd %31 %32 %35
+               OpBranchConditional %36 %25 %26
+         %25 = OpLabel
+         %42 = OpLoad %6 %18
+         %44 = OpAccessChain %43 %41 %42
+         %45 = OpLoad %6 %44
+         %46 = OpLoad %6 %20
+         %47 = OpAccessChain %43 %41 %46
+         %48 = OpLoad %6 %47
+         %49 = OpSLessThan %31 %45 %48
+               OpSelectionMerge %51 None
+               OpBranchConditional %49 %50 %60
+         %50 = OpLabel
+         %53 = OpLoad %6 %16
+         %54 = OpIAdd %6 %53 %22
+               OpStore %16 %54
+         %55 = OpLoad %6 %18
+         %56 = OpIAdd %6 %55 %22
+               OpStore %18 %56
+         %57 = OpAccessChain %43 %41 %55
+         %58 = OpLoad %6 %57
+         %59 = OpAccessChain %43 %52 %53
+               OpStore %59 %58
+               OpBranch %51
+         %60 = OpLabel
+         %61 = OpLoad %6 %16
+         %62 = OpIAdd %6 %61 %22
+               OpStore %16 %62
+         %63 = OpLoad %6 %20
+         %64 = OpIAdd %6 %63 %22
+               OpStore %20 %64
+         %65 = OpAccessChain %43 %41 %63
+         %66 = OpLoad %6 %65
+         %67 = OpAccessChain %43 %52 %61
+               OpStore %67 %66
+               OpBranch %51
+         %51 = OpLabel
+               OpBranch %27
+         %27 = OpLabel
+               OpBranch %24
+         %26 = OpLabel
+               OpBranch %68
+         %68 = OpLabel
+               OpLoopMerge %70 %71 None
+               OpBranch %72
+         %72 = OpLabel
+         %73 = OpLoad %6 %18
+         %75 = OpSLessThan %31 %73 %74
+         %76 = OpLoad %6 %18
+         %77 = OpLoad %6 %10
+         %78 = OpSLessThanEqual %31 %76 %77
+         %79 = OpLogicalAnd %31 %75 %78
+               OpBranchConditional %79 %69 %70
+         %69 = OpLabel
+         %80 = OpLoad %6 %16
+         %81 = OpIAdd %6 %80 %22
+               OpStore %16 %81
+         %82 = OpLoad %6 %18
+         %83 = OpIAdd %6 %82 %22
+               OpStore %18 %83
+         %84 = OpAccessChain %43 %41 %82
+         %85 = OpLoad %6 %84
+         %86 = OpAccessChain %43 %52 %80
+               OpStore %86 %85
+               OpBranch %71
+         %71 = OpLabel
+               OpBranch %68
+         %70 = OpLabel
+         %88 = OpLoad %6 %9
+               OpStore %87 %88
+               OpBranch %89
+         %89 = OpLabel
+               OpLoopMerge %91 %92 None
+               OpBranch %93
+         %93 = OpLabel
+         %94 = OpLoad %6 %87
+         %95 = OpLoad %6 %11
+         %96 = OpSLessThanEqual %31 %94 %95
+               OpBranchConditional %96 %90 %91
+         %90 = OpLabel
+         %97 = OpLoad %6 %87
+         %98 = OpLoad %6 %87
+         %99 = OpAccessChain %43 %52 %98
+        %100 = OpLoad %6 %99
+        %101 = OpAccessChain %43 %41 %97
+               OpStore %101 %100
+               OpBranch %92
+         %92 = OpLabel
+        %102 = OpLoad %6 %87
+        %103 = OpIAdd %6 %102 %22
+               OpStore %87 %103
+               OpBranch %89
+         %91 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %14 = OpFunction %2 None %3
+         %15 = OpLabel
+        %104 = OpVariable %7 Function
+        %106 = OpVariable %7 Function
+        %108 = OpVariable %7 Function
+        %117 = OpVariable %7 Function
+        %127 = OpVariable %7 Function
+        %129 = OpVariable %7 Function
+        %134 = OpVariable %7 Function
+        %143 = OpVariable %7 Function
+        %145 = OpVariable %7 Function
+        %147 = OpVariable %7 Function
+               OpStore %104 %105
+               OpStore %106 %107
+               OpStore %108 %22
+               OpBranch %109
+        %109 = OpLabel
+               OpLoopMerge %111 %112 None
+               OpBranch %113
+        %113 = OpLabel
+        %114 = OpLoad %6 %108
+        %115 = OpLoad %6 %106
+        %116 = OpSLessThanEqual %31 %114 %115
+               OpBranchConditional %116 %110 %111
+        %110 = OpLabel
+        %118 = OpLoad %6 %104
+               OpStore %117 %118
+               OpBranch %119
+        %119 = OpLabel
+               OpLoopMerge %121 %122 None
+               OpBranch %123
+        %123 = OpLabel
+        %124 = OpLoad %6 %117
+        %125 = OpLoad %6 %106
+        %126 = OpSLessThan %31 %124 %125
+               OpBranchConditional %126 %120 %121
+        %120 = OpLabel
+        %128 = OpLoad %6 %117
+               OpStore %127 %128
+        %130 = OpLoad %6 %117
+        %131 = OpLoad %6 %108
+        %132 = OpIAdd %6 %130 %131
+        %133 = OpISub %6 %132 %22
+               OpStore %129 %133
+        %135 = OpLoad %6 %117
+        %137 = OpLoad %6 %108
+        %138 = OpIMul %6 %136 %137
+        %139 = OpIAdd %6 %135 %138
+        %140 = OpISub %6 %139 %22
+        %141 = OpLoad %6 %106
+        %142 = OpExtInst %6 %1 SMin %140 %141
+               OpStore %134 %142
+        %144 = OpLoad %6 %127
+               OpStore %143 %144
+        %146 = OpLoad %6 %129
+               OpStore %145 %146
+        %148 = OpLoad %6 %134
+               OpStore %147 %148
+        %149 = OpFunctionCall %2 %12 %143 %145 %147
+               OpBranch %122
+        %122 = OpLabel
+        %150 = OpLoad %6 %108
+        %151 = OpIMul %6 %136 %150
+        %152 = OpLoad %6 %117
+        %153 = OpIAdd %6 %152 %151
+               OpStore %117 %153
+               OpBranch %119
+        %121 = OpLabel
+               OpBranch %112
+        %112 = OpLabel
+        %154 = OpLoad %6 %108
+        %155 = OpIMul %6 %136 %154
+               OpStore %108 %155
+               OpBranch %109
+        %111 = OpLabel
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for reference
+
+# injectionSwitch
+BUFFER reference_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER reference_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics reference_pipeline
+  ATTACH reference_vertex_shader
+  ATTACH reference_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER reference_framebuffer AS color LOCATION 0
+  BIND BUFFER reference_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR reference_pipeline 0 0 0 255
+
+CLEAR reference_pipeline
+RUN reference_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch;
+# };
+# const int N = 10;
+#
+# int data[10], temp[10];
+#
+# void merge(int from, int mid, int to)
+# {
+#     int k = from, i = from, j = mid + 1;
+#     while (i <= mid && j <= to)
+#     {
+#         if (data[i] < data[j])
+#         {
+#             temp[k++] = data[i++];
+#         }
+#         else
+#         {
+#             temp[k++] = data[j++];
+#         }
+#     }
+#     while (i < N && i <= mid)
+#     {
+#         temp[k++] = data[i++];
+#     }
+#     for (int i = from; i <= to; i++)
+#     {
+#         data[i] = temp[i];
+#     }
+# }
+# void mergeSort()
+# {
+#     int low = 0;
+#     int high = N - 1;
+#     for (int m = 1; m <= high; m = 2 * m)
+#     {
+#         for (int i = low; i < high; i += 2 * m)
+#         {
+#             int from = i;
+#             int mid = i + m - 1;
+#             int to = min(i + 2 * m - 1, high);
+#             merge(from, mid, to);
+#         }
+#     }
+# }
+# void main()
+# {
+#     int i = int(injectionSwitch.x);
+#     do
+#     {
+#         switch (i)
+#         {
+#         case 0:
+#             data[i] = 4;
+#             break;
+#         case 1:
+#             data[i] = 3;
+#             break;
+#         case 2:
+#             data[i] = 2;
+#             break;
+#         case 3:
+#             data[i] = 1;
+#             break;
+#         case 4:
+#             data[i] = 0;
+#             break;
+#         case 5:
+#             data[i] = -1;
+#             break;
+#         case 6:
+#             data[i] = -2;
+#             break;
+#         case 7:
+#             data[i] = -3;
+#             break;
+#         case 8:
+#             data[i] = -4;
+#             break;
+#         case 9:
+#             data[i] = -5;
+#             break;
+#         }
+#         i++;
+#     } while (i < 10);
+#     for (int j = 0; j < 10; j++)
+#     {
+#         temp[j] = data[j];
+#     }
+#     mergeSort();
+#     float grey;
+#     if (int(gl_FragCoord[1]) < 30)
+#     {
+#         grey = 0.5 + float(data[0]) / 10.0;
+#     }
+#     else
+#     {
+#         if (int(gl_FragCoord[1]) < 60)
+#         {
+#             grey = 0.5 + float(data[1]) / 10.0;
+#         }
+#         else
+#         {
+#             if (int(gl_FragCoord[1]) < 90)
+#             {
+#                 grey = 0.5 + float(data[2]) / 10.0;
+#             }
+#             else
+#             {
+#                 if (int(gl_FragCoord[1]) < 120)
+#                 {
+#                     grey = 0.5 + float(data[3]) / 10.0;
+#                 }
+#                 else
+#                 {
+#                     if (int(gl_FragCoord[1]) < 150)
+#                     {
+#                         // Iterates once.
+#                         for (int int_i = 1; int_i > int((injectionSwitch.x)); int_i--)
+#                         {
+#                             discard;
+#                         }
+#                     }
+#                     else
+#                     {
+#                         if (int(gl_FragCoord[1]) < 180)
+#                         {
+#                             grey = 0.5 + float(data[5]) / 10.0;
+#                         }
+#                         else
+#                         {
+#                             if (int(gl_FragCoord[1]) < 210)
+#                             {
+#                                 grey = 0.5 + float(data[6]) / 10.0;
+#                             }
+#                             else
+#                             {
+#                                 if (int(gl_FragCoord[1]) < 240)
+#                                 {
+#                                     grey = 0.5 + float(data[7]) / 10.0;
+#                                 }
+#                                 else
+#                                 {
+#                                     if (int(gl_FragCoord[1]) < 270)
+#                                     {
+#                                         grey = 0.5 + float(data[8]) / 10.0;
+#                                     }
+#                                     else
+#                                     {
+#                                         discard;
+#                                     }
+#                                 }
+#                             }
+#                         }
+#                     }
+#                 }
+#             }
+#         }
+#     }
+#     _GLF_color = vec4(vec3(grey), 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 391
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %243 %382
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %12 "merge(i1;i1;i1;"
+               OpName %9 "from"
+               OpName %10 "mid"
+               OpName %11 "to"
+               OpName %14 "mergeSort("
+               OpName %16 "k"
+               OpName %18 "i"
+               OpName %20 "j"
+               OpName %41 "data"
+               OpName %52 "temp"
+               OpName %87 "i"
+               OpName %104 "low"
+               OpName %106 "high"
+               OpName %108 "m"
+               OpName %117 "i"
+               OpName %127 "from"
+               OpName %129 "mid"
+               OpName %134 "to"
+               OpName %143 "param"
+               OpName %145 "param"
+               OpName %147 "param"
+               OpName %156 "i"
+               OpName %159 "buf0"
+               OpMemberName %159 0 "injectionSwitch"
+               OpName %161 ""
+               OpName %225 "j"
+               OpName %243 "gl_FragCoord"
+               OpName %254 "grey"
+               OpName %309 "int_i"
+               OpName %382 "_GLF_color"
+               OpMemberDecorate %159 0 Offset 0
+               OpDecorate %159 Block
+               OpDecorate %161 DescriptorSet 0
+               OpDecorate %161 Binding 0
+               OpDecorate %243 BuiltIn FragCoord
+               OpDecorate %382 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypePointer Function %6
+          %8 = OpTypeFunction %2 %7 %7 %7
+         %22 = OpConstant %6 1
+         %31 = OpTypeBool
+         %37 = OpTypeInt 32 0
+         %38 = OpConstant %37 10
+         %39 = OpTypeArray %6 %38
+         %40 = OpTypePointer Private %39
+         %41 = OpVariable %40 Private
+         %43 = OpTypePointer Private %6
+         %52 = OpVariable %40 Private
+         %74 = OpConstant %6 10
+        %105 = OpConstant %6 0
+        %107 = OpConstant %6 9
+        %136 = OpConstant %6 2
+        %157 = OpTypeFloat 32
+        %158 = OpTypeVector %157 2
+        %159 = OpTypeStruct %158
+        %160 = OpTypePointer Uniform %159
+        %161 = OpVariable %160 Uniform
+        %162 = OpConstant %37 0
+        %163 = OpTypePointer Uniform %157
+        %184 = OpConstant %6 4
+        %188 = OpConstant %6 3
+        %201 = OpConstant %6 -1
+        %205 = OpConstant %6 -2
+        %209 = OpConstant %6 -3
+        %213 = OpConstant %6 -4
+        %217 = OpConstant %6 -5
+        %241 = OpTypeVector %157 4
+        %242 = OpTypePointer Input %241
+        %243 = OpVariable %242 Input
+        %244 = OpConstant %37 1
+        %245 = OpTypePointer Input %157
+        %249 = OpConstant %6 30
+        %253 = OpTypePointer Function %157
+        %255 = OpConstant %157 0.5
+        %259 = OpConstant %157 10
+        %266 = OpConstant %6 60
+        %279 = OpConstant %6 90
+        %292 = OpConstant %6 120
+        %305 = OpConstant %6 150
+        %327 = OpConstant %6 180
+        %331 = OpConstant %6 5
+        %341 = OpConstant %6 210
+        %345 = OpConstant %6 6
+        %355 = OpConstant %6 240
+        %359 = OpConstant %6 7
+        %369 = OpConstant %6 270
+        %373 = OpConstant %6 8
+        %381 = OpTypePointer Output %241
+        %382 = OpVariable %381 Output
+        %384 = OpTypeVector %157 3
+        %386 = OpConstant %157 1
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %156 = OpVariable %7 Function
+        %225 = OpVariable %7 Function
+        %254 = OpVariable %253 Function
+        %309 = OpVariable %7 Function
+        %164 = OpAccessChain %163 %161 %105 %162
+        %165 = OpLoad %157 %164
+        %166 = OpConvertFToS %6 %165
+               OpStore %156 %166
+               OpBranch %167
+        %167 = OpLabel
+               OpLoopMerge %169 %170 None
+               OpBranch %168
+        %168 = OpLabel
+        %171 = OpLoad %6 %156
+               OpSelectionMerge %182 None
+               OpSwitch %171 %182 0 %172 1 %173 2 %174 3 %175 4 %176 5 %177 6 %178 7 %179 8 %180 9 %181
+        %172 = OpLabel
+        %183 = OpLoad %6 %156
+        %185 = OpAccessChain %43 %41 %183
+               OpStore %185 %184
+               OpBranch %182
+        %173 = OpLabel
+        %187 = OpLoad %6 %156
+        %189 = OpAccessChain %43 %41 %187
+               OpStore %189 %188
+               OpBranch %182
+        %174 = OpLabel
+        %191 = OpLoad %6 %156
+        %192 = OpAccessChain %43 %41 %191
+               OpStore %192 %136
+               OpBranch %182
+        %175 = OpLabel
+        %194 = OpLoad %6 %156
+        %195 = OpAccessChain %43 %41 %194
+               OpStore %195 %22
+               OpBranch %182
+        %176 = OpLabel
+        %197 = OpLoad %6 %156
+        %198 = OpAccessChain %43 %41 %197
+               OpStore %198 %105
+               OpBranch %182
+        %177 = OpLabel
+        %200 = OpLoad %6 %156
+        %202 = OpAccessChain %43 %41 %200
+               OpStore %202 %201
+               OpBranch %182
+        %178 = OpLabel
+        %204 = OpLoad %6 %156
+        %206 = OpAccessChain %43 %41 %204
+               OpStore %206 %205
+               OpBranch %182
+        %179 = OpLabel
+        %208 = OpLoad %6 %156
+        %210 = OpAccessChain %43 %41 %208
+               OpStore %210 %209
+               OpBranch %182
+        %180 = OpLabel
+        %212 = OpLoad %6 %156
+        %214 = OpAccessChain %43 %41 %212
+               OpStore %214 %213
+               OpBranch %182
+        %181 = OpLabel
+        %216 = OpLoad %6 %156
+        %218 = OpAccessChain %43 %41 %216
+               OpStore %218 %217
+               OpBranch %182
+        %182 = OpLabel
+        %221 = OpLoad %6 %156
+        %222 = OpIAdd %6 %221 %22
+               OpStore %156 %222
+               OpBranch %170
+        %170 = OpLabel
+        %223 = OpLoad %6 %156
+        %224 = OpSLessThan %31 %223 %74
+               OpBranchConditional %224 %167 %169
+        %169 = OpLabel
+               OpStore %225 %105
+               OpBranch %226
+        %226 = OpLabel
+               OpLoopMerge %228 %229 None
+               OpBranch %230
+        %230 = OpLabel
+        %231 = OpLoad %6 %225
+        %232 = OpSLessThan %31 %231 %74
+               OpBranchConditional %232 %227 %228
+        %227 = OpLabel
+        %233 = OpLoad %6 %225
+        %234 = OpLoad %6 %225
+        %235 = OpAccessChain %43 %41 %234
+        %236 = OpLoad %6 %235
+        %237 = OpAccessChain %43 %52 %233
+               OpStore %237 %236
+               OpBranch %229
+        %229 = OpLabel
+        %238 = OpLoad %6 %225
+        %239 = OpIAdd %6 %238 %22
+               OpStore %225 %239
+               OpBranch %226
+        %228 = OpLabel
+        %240 = OpFunctionCall %2 %14
+        %246 = OpAccessChain %245 %243 %244
+        %247 = OpLoad %157 %246
+        %248 = OpConvertFToS %6 %247
+        %250 = OpSLessThan %31 %248 %249
+               OpSelectionMerge %252 None
+               OpBranchConditional %250 %251 %262
+        %251 = OpLabel
+        %256 = OpAccessChain %43 %41 %105
+        %257 = OpLoad %6 %256
+        %258 = OpConvertSToF %157 %257
+        %260 = OpFDiv %157 %258 %259
+        %261 = OpFAdd %157 %255 %260
+               OpStore %254 %261
+               OpBranch %252
+        %262 = OpLabel
+        %263 = OpAccessChain %245 %243 %244
+        %264 = OpLoad %157 %263
+        %265 = OpConvertFToS %6 %264
+        %267 = OpSLessThan %31 %265 %266
+               OpSelectionMerge %269 None
+               OpBranchConditional %267 %268 %275
+        %268 = OpLabel
+        %270 = OpAccessChain %43 %41 %22
+        %271 = OpLoad %6 %270
+        %272 = OpConvertSToF %157 %271
+        %273 = OpFDiv %157 %272 %259
+        %274 = OpFAdd %157 %255 %273
+               OpStore %254 %274
+               OpBranch %269
+        %275 = OpLabel
+        %276 = OpAccessChain %245 %243 %244
+        %277 = OpLoad %157 %276
+        %278 = OpConvertFToS %6 %277
+        %280 = OpSLessThan %31 %278 %279
+               OpSelectionMerge %282 None
+               OpBranchConditional %280 %281 %288
+        %281 = OpLabel
+        %283 = OpAccessChain %43 %41 %136
+        %284 = OpLoad %6 %283
+        %285 = OpConvertSToF %157 %284
+        %286 = OpFDiv %157 %285 %259
+        %287 = OpFAdd %157 %255 %286
+               OpStore %254 %287
+               OpBranch %282
+        %288 = OpLabel
+        %289 = OpAccessChain %245 %243 %244
+        %290 = OpLoad %157 %289
+        %291 = OpConvertFToS %6 %290
+        %293 = OpSLessThan %31 %291 %292
+               OpSelectionMerge %295 None
+               OpBranchConditional %293 %294 %301
+        %294 = OpLabel
+        %296 = OpAccessChain %43 %41 %188
+        %297 = OpLoad %6 %296
+        %298 = OpConvertSToF %157 %297
+        %299 = OpFDiv %157 %298 %259
+        %300 = OpFAdd %157 %255 %299
+               OpStore %254 %300
+               OpBranch %295
+        %301 = OpLabel
+        %302 = OpAccessChain %245 %243 %244
+        %303 = OpLoad %157 %302
+        %304 = OpConvertFToS %6 %303
+        %306 = OpSLessThan %31 %304 %305
+               OpSelectionMerge %308 None
+               OpBranchConditional %306 %307 %323
+        %307 = OpLabel
+               OpStore %309 %22
+               OpBranch %310
+        %310 = OpLabel
+               OpLoopMerge %312 %313 None
+               OpBranch %314
+        %314 = OpLabel
+        %315 = OpLoad %6 %309
+        %316 = OpAccessChain %163 %161 %105 %162
+        %317 = OpLoad %157 %316
+        %318 = OpConvertFToS %6 %317
+        %319 = OpSGreaterThan %31 %315 %318
+               OpBranchConditional %319 %311 %312
+        %311 = OpLabel
+               OpKill
+        %313 = OpLabel
+               OpBranch %310
+        %312 = OpLabel
+               OpBranch %308
+        %323 = OpLabel
+        %324 = OpAccessChain %245 %243 %244
+        %325 = OpLoad %157 %324
+        %326 = OpConvertFToS %6 %325
+        %328 = OpSLessThan %31 %326 %327
+               OpSelectionMerge %330 None
+               OpBranchConditional %328 %329 %337
+        %329 = OpLabel
+        %332 = OpAccessChain %43 %41 %331
+        %333 = OpLoad %6 %332
+        %334 = OpConvertSToF %157 %333
+        %335 = OpFDiv %157 %334 %259
+        %336 = OpFAdd %157 %255 %335
+               OpStore %254 %336
+               OpBranch %330
+        %337 = OpLabel
+        %338 = OpAccessChain %245 %243 %244
+        %339 = OpLoad %157 %338
+        %340 = OpConvertFToS %6 %339
+        %342 = OpSLessThan %31 %340 %341
+               OpSelectionMerge %344 None
+               OpBranchConditional %342 %343 %351
+        %343 = OpLabel
+        %346 = OpAccessChain %43 %41 %345
+        %347 = OpLoad %6 %346
+        %348 = OpConvertSToF %157 %347
+        %349 = OpFDiv %157 %348 %259
+        %350 = OpFAdd %157 %255 %349
+               OpStore %254 %350
+               OpBranch %344
+        %351 = OpLabel
+        %352 = OpAccessChain %245 %243 %244
+        %353 = OpLoad %157 %352
+        %354 = OpConvertFToS %6 %353
+        %356 = OpSLessThan %31 %354 %355
+               OpSelectionMerge %358 None
+               OpBranchConditional %356 %357 %365
+        %357 = OpLabel
+        %360 = OpAccessChain %43 %41 %359
+        %361 = OpLoad %6 %360
+        %362 = OpConvertSToF %157 %361
+        %363 = OpFDiv %157 %362 %259
+        %364 = OpFAdd %157 %255 %363
+               OpStore %254 %364
+               OpBranch %358
+        %365 = OpLabel
+        %366 = OpAccessChain %245 %243 %244
+        %367 = OpLoad %157 %366
+        %368 = OpConvertFToS %6 %367
+        %370 = OpSLessThan %31 %368 %369
+               OpSelectionMerge %372 None
+               OpBranchConditional %370 %371 %379
+        %371 = OpLabel
+        %374 = OpAccessChain %43 %41 %373
+        %375 = OpLoad %6 %374
+        %376 = OpConvertSToF %157 %375
+        %377 = OpFDiv %157 %376 %259
+        %378 = OpFAdd %157 %255 %377
+               OpStore %254 %378
+               OpBranch %372
+        %379 = OpLabel
+               OpKill
+        %372 = OpLabel
+               OpBranch %358
+        %358 = OpLabel
+               OpBranch %344
+        %344 = OpLabel
+               OpBranch %330
+        %330 = OpLabel
+               OpBranch %308
+        %308 = OpLabel
+               OpBranch %295
+        %295 = OpLabel
+               OpBranch %282
+        %282 = OpLabel
+               OpBranch %269
+        %269 = OpLabel
+               OpBranch %252
+        %252 = OpLabel
+        %383 = OpLoad %157 %254
+        %385 = OpCompositeConstruct %384 %383 %383 %383
+        %387 = OpCompositeExtract %157 %385 0
+        %388 = OpCompositeExtract %157 %385 1
+        %389 = OpCompositeExtract %157 %385 2
+        %390 = OpCompositeConstruct %241 %387 %388 %389 %386
+               OpStore %382 %390
+               OpReturn
+               OpFunctionEnd
+         %12 = OpFunction %2 None %8
+          %9 = OpFunctionParameter %7
+         %10 = OpFunctionParameter %7
+         %11 = OpFunctionParameter %7
+         %13 = OpLabel
+         %16 = OpVariable %7 Function
+         %18 = OpVariable %7 Function
+         %20 = OpVariable %7 Function
+         %87 = OpVariable %7 Function
+         %17 = OpLoad %6 %9
+               OpStore %16 %17
+         %19 = OpLoad %6 %9
+               OpStore %18 %19
+         %21 = OpLoad %6 %10
+         %23 = OpIAdd %6 %21 %22
+               OpStore %20 %23
+               OpBranch %24
+         %24 = OpLabel
+               OpLoopMerge %26 %27 None
+               OpBranch %28
+         %28 = OpLabel
+         %29 = OpLoad %6 %18
+         %30 = OpLoad %6 %10
+         %32 = OpSLessThanEqual %31 %29 %30
+         %33 = OpLoad %6 %20
+         %34 = OpLoad %6 %11
+         %35 = OpSLessThanEqual %31 %33 %34
+         %36 = OpLogicalAnd %31 %32 %35
+               OpBranchConditional %36 %25 %26
+         %25 = OpLabel
+         %42 = OpLoad %6 %18
+         %44 = OpAccessChain %43 %41 %42
+         %45 = OpLoad %6 %44
+         %46 = OpLoad %6 %20
+         %47 = OpAccessChain %43 %41 %46
+         %48 = OpLoad %6 %47
+         %49 = OpSLessThan %31 %45 %48
+               OpSelectionMerge %51 None
+               OpBranchConditional %49 %50 %60
+         %50 = OpLabel
+         %53 = OpLoad %6 %16
+         %54 = OpIAdd %6 %53 %22
+               OpStore %16 %54
+         %55 = OpLoad %6 %18
+         %56 = OpIAdd %6 %55 %22
+               OpStore %18 %56
+         %57 = OpAccessChain %43 %41 %55
+         %58 = OpLoad %6 %57
+         %59 = OpAccessChain %43 %52 %53
+               OpStore %59 %58
+               OpBranch %51
+         %60 = OpLabel
+         %61 = OpLoad %6 %16
+         %62 = OpIAdd %6 %61 %22
+               OpStore %16 %62
+         %63 = OpLoad %6 %20
+         %64 = OpIAdd %6 %63 %22
+               OpStore %20 %64
+         %65 = OpAccessChain %43 %41 %63
+         %66 = OpLoad %6 %65
+         %67 = OpAccessChain %43 %52 %61
+               OpStore %67 %66
+               OpBranch %51
+         %51 = OpLabel
+               OpBranch %27
+         %27 = OpLabel
+               OpBranch %24
+         %26 = OpLabel
+               OpBranch %68
+         %68 = OpLabel
+               OpLoopMerge %70 %71 None
+               OpBranch %72
+         %72 = OpLabel
+         %73 = OpLoad %6 %18
+         %75 = OpSLessThan %31 %73 %74
+         %76 = OpLoad %6 %18
+         %77 = OpLoad %6 %10
+         %78 = OpSLessThanEqual %31 %76 %77
+         %79 = OpLogicalAnd %31 %75 %78
+               OpBranchConditional %79 %69 %70
+         %69 = OpLabel
+         %80 = OpLoad %6 %16
+         %81 = OpIAdd %6 %80 %22
+               OpStore %16 %81
+         %82 = OpLoad %6 %18
+         %83 = OpIAdd %6 %82 %22
+               OpStore %18 %83
+         %84 = OpAccessChain %43 %41 %82
+         %85 = OpLoad %6 %84
+         %86 = OpAccessChain %43 %52 %80
+               OpStore %86 %85
+               OpBranch %71
+         %71 = OpLabel
+               OpBranch %68
+         %70 = OpLabel
+         %88 = OpLoad %6 %9
+               OpStore %87 %88
+               OpBranch %89
+         %89 = OpLabel
+               OpLoopMerge %91 %92 None
+               OpBranch %93
+         %93 = OpLabel
+         %94 = OpLoad %6 %87
+         %95 = OpLoad %6 %11
+         %96 = OpSLessThanEqual %31 %94 %95
+               OpBranchConditional %96 %90 %91
+         %90 = OpLabel
+         %97 = OpLoad %6 %87
+         %98 = OpLoad %6 %87
+         %99 = OpAccessChain %43 %52 %98
+        %100 = OpLoad %6 %99
+        %101 = OpAccessChain %43 %41 %97
+               OpStore %101 %100
+               OpBranch %92
+         %92 = OpLabel
+        %102 = OpLoad %6 %87
+        %103 = OpIAdd %6 %102 %22
+               OpStore %87 %103
+               OpBranch %89
+         %91 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %14 = OpFunction %2 None %3
+         %15 = OpLabel
+        %104 = OpVariable %7 Function
+        %106 = OpVariable %7 Function
+        %108 = OpVariable %7 Function
+        %117 = OpVariable %7 Function
+        %127 = OpVariable %7 Function
+        %129 = OpVariable %7 Function
+        %134 = OpVariable %7 Function
+        %143 = OpVariable %7 Function
+        %145 = OpVariable %7 Function
+        %147 = OpVariable %7 Function
+               OpStore %104 %105
+               OpStore %106 %107
+               OpStore %108 %22
+               OpBranch %109
+        %109 = OpLabel
+               OpLoopMerge %111 %112 None
+               OpBranch %113
+        %113 = OpLabel
+        %114 = OpLoad %6 %108
+        %115 = OpLoad %6 %106
+        %116 = OpSLessThanEqual %31 %114 %115
+               OpBranchConditional %116 %110 %111
+        %110 = OpLabel
+        %118 = OpLoad %6 %104
+               OpStore %117 %118
+               OpBranch %119
+        %119 = OpLabel
+               OpLoopMerge %121 %122 None
+               OpBranch %123
+        %123 = OpLabel
+        %124 = OpLoad %6 %117
+        %125 = OpLoad %6 %106
+        %126 = OpSLessThan %31 %124 %125
+               OpBranchConditional %126 %120 %121
+        %120 = OpLabel
+        %128 = OpLoad %6 %117
+               OpStore %127 %128
+        %130 = OpLoad %6 %117
+        %131 = OpLoad %6 %108
+        %132 = OpIAdd %6 %130 %131
+        %133 = OpISub %6 %132 %22
+               OpStore %129 %133
+        %135 = OpLoad %6 %117
+        %137 = OpLoad %6 %108
+        %138 = OpIMul %6 %136 %137
+        %139 = OpIAdd %6 %135 %138
+        %140 = OpISub %6 %139 %22
+        %141 = OpLoad %6 %106
+        %142 = OpExtInst %6 %1 SMin %140 %141
+               OpStore %134 %142
+        %144 = OpLoad %6 %127
+               OpStore %143 %144
+        %146 = OpLoad %6 %129
+               OpStore %145 %146
+        %148 = OpLoad %6 %134
+               OpStore %147 %148
+        %149 = OpFunctionCall %2 %12 %143 %145 %147
+               OpBranch %122
+        %122 = OpLabel
+        %150 = OpLoad %6 %108
+        %151 = OpIMul %6 %136 %150
+        %152 = OpLoad %6 %117
+        %153 = OpIAdd %6 %152 %151
+               OpStore %117 %153
+               OpBranch %119
+        %121 = OpLabel
+               OpBranch %112
+        %112 = OpLabel
+        %154 = OpLoad %6 %108
+        %155 = OpIMul %6 %136 %154
+               OpStore %108 %155
+               OpBranch %109
+        %111 = 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 reference_framebuffer EQ_HISTOGRAM_EMD_BUFFER variant_framebuffer TOLERANCE 0.005
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-triangle-array-nested-loop.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-triangle-array-nested-loop.amber
new file mode 100644 (file)
index 0000000..729d6b3
--- /dev/null
@@ -0,0 +1,896 @@
+#!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 and nested loops
+
+# The test passes because both shaders render the same image.
+
+# Optimized using spirv-opt with the following arguments:
+# '--private-to-local'
+# '--copy-propagate-arrays'
+# '--if-conversion'
+# '--private-to-local'
+# '--eliminate-dead-inserts'
+# '--if-conversion'
+# '--if-conversion'
+# '--scalar-replacement=100'
+# '--private-to-local'
+# '--reduce-load-size'
+# '--ccp'
+# '--scalar-replacement=100'
+# '--eliminate-dead-branches'
+# '--eliminate-dead-branches'
+# '--merge-return'
+# '--private-to-local'
+# '--redundancy-elimination'
+# '--combine-access-chains'
+# '--eliminate-local-multi-store'
+# '--ccp'
+# '--convert-local-access-chains'
+# '--reduce-load-size'
+# '--private-to-local'
+# '--vector-dce'
+# spirv-opt commit hash: 230f363e6da32791f640b02205e0645cc67c3f1d
+
+
+
+SHADER vertex reference_vertex_shader PASSTHROUGH
+
+# reference_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 resolution;
+# };
+# float cross2d(vec2 a, vec2 b)
+# {
+#     return ((a.x) * (b.y) - (b.x) * (a.y));
+# }
+# int pointInTriangle(vec2 p, vec2 a, vec2 b, vec2 c)
+# {
+#     float pab = cross2d(vec2(p.x - a.x, p.y - a.y), vec2(b.x - a.x, b.y - a.y));
+#     float pbc = cross2d(vec2(p.x - b.x, p.y - b.y), vec2(c.x - b.x, c.y - b.y));
+#     if (!((pab < 0.0 && pbc < 0.0) || (pab >= 0.0 && pbc >= 0.0)))
+#     {
+#         return 0;
+#     }
+#     float pca = cross2d(vec2(p.x - c.x, p.y - c.y), vec2(a.x - c.x, a.y - c.y));
+#     if (!((pab < 0.0 && pca < 0.0) || (pab >= 0.0 && pca >= 0.0)))
+#     {
+#         return 0;
+#     }
+#     return 1;
+# }
+# void main()
+# {
+#     vec2 pos = gl_FragCoord.xy / resolution;
+#     if (pointInTriangle(pos, vec2(0.7, 0.3), vec2(0.5, 0.9), vec2(0.1, 0.4)) == 1)
+#     {
+#         _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#     }
+#     else
+#     {
+#         _GLF_color = vec4(0.0, 0.0, 0.0, 1.0);
+#     }
+# }
+SHADER fragment reference_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 207
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %162 %191
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %12 "cross2d(vf2;vf2;"
+               OpName %10 "a"
+               OpName %11 "b"
+               OpName %20 "pointInTriangle(vf2;vf2;vf2;vf2;"
+               OpName %16 "p"
+               OpName %17 "a"
+               OpName %18 "b"
+               OpName %19 "c"
+               OpName %39 "pab"
+               OpName %62 "param"
+               OpName %63 "param"
+               OpName %65 "pbc"
+               OpName %88 "param"
+               OpName %89 "param"
+               OpName %112 "pca"
+               OpName %135 "param"
+               OpName %136 "param"
+               OpName %159 "pos"
+               OpName %162 "gl_FragCoord"
+               OpName %165 "buf0"
+               OpMemberName %165 0 "resolution"
+               OpName %167 ""
+               OpName %181 "param"
+               OpName %183 "param"
+               OpName %184 "param"
+               OpName %185 "param"
+               OpName %191 "_GLF_color"
+               OpDecorate %162 BuiltIn FragCoord
+               OpMemberDecorate %165 0 Offset 0
+               OpDecorate %165 Block
+               OpDecorate %167 DescriptorSet 0
+               OpDecorate %167 Binding 0
+               OpDecorate %191 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 2
+          %8 = OpTypePointer Function %7
+          %9 = OpTypeFunction %6 %8 %8
+         %14 = OpTypeInt 32 1
+         %15 = OpTypeFunction %14 %8 %8 %8 %8
+         %22 = OpTypeInt 32 0
+         %23 = OpConstant %22 0
+         %24 = OpTypePointer Function %6
+         %27 = OpConstant %22 1
+         %91 = OpTypeBool
+         %93 = OpConstant %6 0
+        %110 = OpConstant %14 0
+        %156 = OpConstant %14 1
+        %160 = OpTypeVector %6 4
+        %161 = OpTypePointer Input %160
+        %162 = OpVariable %161 Input
+        %165 = OpTypeStruct %7
+        %166 = OpTypePointer Uniform %165
+        %167 = OpVariable %166 Uniform
+        %168 = OpTypePointer Uniform %7
+        %172 = OpConstant %6 0.699999988
+        %173 = OpConstant %6 0.300000012
+        %174 = OpConstantComposite %7 %172 %173
+        %175 = OpConstant %6 0.5
+        %176 = OpConstant %6 0.899999976
+        %177 = OpConstantComposite %7 %175 %176
+        %178 = OpConstant %6 0.100000001
+        %179 = OpConstant %6 0.400000006
+        %180 = OpConstantComposite %7 %178 %179
+        %190 = OpTypePointer Output %160
+        %191 = OpVariable %190 Output
+        %192 = OpConstant %6 1
+        %193 = OpConstantComposite %160 %192 %93 %93 %192
+        %195 = OpConstantComposite %160 %93 %93 %93 %192
+        %197 = OpTypePointer Function %14
+        %201 = OpConstantFalse %91
+        %202 = OpTypePointer Function %91
+        %204 = OpConstantTrue %91
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %159 = OpVariable %8 Function
+        %181 = OpVariable %8 Function
+        %183 = OpVariable %8 Function
+        %184 = OpVariable %8 Function
+        %185 = OpVariable %8 Function
+        %163 = OpLoad %160 %162
+        %164 = OpVectorShuffle %7 %163 %163 0 1
+        %169 = OpAccessChain %168 %167 %110
+        %170 = OpLoad %7 %169
+        %171 = OpFDiv %7 %164 %170
+               OpStore %159 %171
+               OpStore %181 %171
+               OpStore %183 %174
+               OpStore %184 %177
+               OpStore %185 %180
+        %186 = OpFunctionCall %14 %20 %181 %183 %184 %185
+        %187 = OpIEqual %91 %186 %156
+               OpSelectionMerge %189 None
+               OpBranchConditional %187 %188 %194
+        %188 = OpLabel
+               OpStore %191 %193
+               OpBranch %189
+        %194 = OpLabel
+               OpStore %191 %195
+               OpBranch %189
+        %189 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %12 = OpFunction %6 None %9
+         %10 = OpFunctionParameter %8
+         %11 = OpFunctionParameter %8
+         %13 = OpLabel
+         %25 = OpAccessChain %24 %10 %23
+         %26 = OpLoad %6 %25
+         %28 = OpAccessChain %24 %11 %27
+         %29 = OpLoad %6 %28
+         %30 = OpFMul %6 %26 %29
+         %31 = OpAccessChain %24 %11 %23
+         %32 = OpLoad %6 %31
+         %33 = OpAccessChain %24 %10 %27
+         %34 = OpLoad %6 %33
+         %35 = OpFMul %6 %32 %34
+         %36 = OpFSub %6 %30 %35
+               OpReturnValue %36
+               OpFunctionEnd
+         %20 = OpFunction %14 None %15
+         %16 = OpFunctionParameter %8
+         %17 = OpFunctionParameter %8
+         %18 = OpFunctionParameter %8
+         %19 = OpFunctionParameter %8
+         %21 = OpLabel
+        %203 = OpVariable %202 Function %201
+        %198 = OpVariable %197 Function
+         %39 = OpVariable %24 Function
+         %62 = OpVariable %8 Function
+         %63 = OpVariable %8 Function
+         %65 = OpVariable %24 Function
+         %88 = OpVariable %8 Function
+         %89 = OpVariable %8 Function
+        %112 = OpVariable %24 Function
+        %135 = OpVariable %8 Function
+        %136 = OpVariable %8 Function
+               OpSelectionMerge %196 None
+               OpSwitch %23 %200
+        %200 = OpLabel
+         %40 = OpAccessChain %24 %16 %23
+         %41 = OpLoad %6 %40
+         %42 = OpAccessChain %24 %17 %23
+         %43 = OpLoad %6 %42
+         %44 = OpFSub %6 %41 %43
+         %45 = OpAccessChain %24 %16 %27
+         %46 = OpLoad %6 %45
+         %47 = OpAccessChain %24 %17 %27
+         %48 = OpLoad %6 %47
+         %49 = OpFSub %6 %46 %48
+         %50 = OpCompositeConstruct %7 %44 %49
+         %51 = OpAccessChain %24 %18 %23
+         %52 = OpLoad %6 %51
+         %54 = OpLoad %6 %42
+         %55 = OpFSub %6 %52 %54
+         %56 = OpAccessChain %24 %18 %27
+         %57 = OpLoad %6 %56
+         %59 = OpLoad %6 %47
+         %60 = OpFSub %6 %57 %59
+         %61 = OpCompositeConstruct %7 %55 %60
+               OpStore %62 %50
+               OpStore %63 %61
+         %64 = OpFunctionCall %6 %12 %62 %63
+               OpStore %39 %64
+         %67 = OpLoad %6 %40
+         %69 = OpLoad %6 %51
+         %70 = OpFSub %6 %67 %69
+         %72 = OpLoad %6 %45
+         %74 = OpLoad %6 %56
+         %75 = OpFSub %6 %72 %74
+         %76 = OpCompositeConstruct %7 %70 %75
+         %77 = OpAccessChain %24 %19 %23
+         %78 = OpLoad %6 %77
+         %80 = OpLoad %6 %51
+         %81 = OpFSub %6 %78 %80
+         %82 = OpAccessChain %24 %19 %27
+         %83 = OpLoad %6 %82
+         %85 = OpLoad %6 %56
+         %86 = OpFSub %6 %83 %85
+         %87 = OpCompositeConstruct %7 %81 %86
+               OpStore %88 %76
+               OpStore %89 %87
+         %90 = OpFunctionCall %6 %12 %88 %89
+               OpStore %65 %90
+         %94 = OpFOrdLessThan %91 %64 %93
+         %96 = OpFOrdLessThan %91 %90 %93
+         %97 = OpLogicalAnd %91 %94 %96
+         %98 = OpLogicalNot %91 %97
+               OpSelectionMerge %100 None
+               OpBranchConditional %98 %99 %100
+         %99 = OpLabel
+        %102 = OpFOrdGreaterThanEqual %91 %64 %93
+        %104 = OpFOrdGreaterThanEqual %91 %90 %93
+        %105 = OpLogicalAnd %91 %102 %104
+               OpBranch %100
+        %100 = OpLabel
+        %106 = OpPhi %91 %97 %200 %105 %99
+        %107 = OpLogicalNot %91 %106
+               OpSelectionMerge %109 None
+               OpBranchConditional %107 %108 %109
+        %108 = OpLabel
+               OpStore %203 %204
+               OpStore %198 %110
+               OpBranch %196
+        %109 = OpLabel
+        %114 = OpLoad %6 %40
+        %116 = OpLoad %6 %77
+        %117 = OpFSub %6 %114 %116
+        %119 = OpLoad %6 %45
+        %121 = OpLoad %6 %82
+        %122 = OpFSub %6 %119 %121
+        %123 = OpCompositeConstruct %7 %117 %122
+        %125 = OpLoad %6 %42
+        %127 = OpLoad %6 %77
+        %128 = OpFSub %6 %125 %127
+        %130 = OpLoad %6 %47
+        %132 = OpLoad %6 %82
+        %133 = OpFSub %6 %130 %132
+        %134 = OpCompositeConstruct %7 %128 %133
+               OpStore %135 %123
+               OpStore %136 %134
+        %137 = OpFunctionCall %6 %12 %135 %136
+               OpStore %112 %137
+        %139 = OpFOrdLessThan %91 %64 %93
+        %141 = OpFOrdLessThan %91 %137 %93
+        %142 = OpLogicalAnd %91 %139 %141
+        %143 = OpLogicalNot %91 %142
+               OpSelectionMerge %145 None
+               OpBranchConditional %143 %144 %145
+        %144 = OpLabel
+        %147 = OpFOrdGreaterThanEqual %91 %64 %93
+        %149 = OpFOrdGreaterThanEqual %91 %137 %93
+        %150 = OpLogicalAnd %91 %147 %149
+               OpBranch %145
+        %145 = OpLabel
+        %151 = OpPhi %91 %142 %109 %150 %144
+        %152 = OpLogicalNot %91 %151
+               OpSelectionMerge %154 None
+               OpBranchConditional %152 %153 %154
+        %153 = OpLabel
+               OpStore %203 %204
+               OpStore %198 %110
+               OpBranch %196
+        %154 = OpLabel
+               OpStore %203 %204
+               OpStore %198 %156
+               OpBranch %196
+        %196 = OpLabel
+        %206 = OpPhi %14 %110 %108 %110 %153 %156 %154
+               OpReturnValue %206
+               OpFunctionEnd
+END
+
+# uniforms for reference
+
+# resolution
+BUFFER reference_resolution DATA_TYPE vec2<float> DATA
+ 256.0 256.0
+END
+
+BUFFER reference_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics reference_pipeline
+  ATTACH reference_vertex_shader
+  ATTACH reference_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER reference_framebuffer AS color LOCATION 0
+  BIND BUFFER reference_resolution AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR reference_pipeline 0 0 0 255
+
+CLEAR reference_pipeline
+RUN reference_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 resolution;
+# };
+# float cross2d(vec2 a, vec2 b)
+# {
+#     return ((a.x) * (b.y) - (b.x) * (a.y));
+# }
+# int pointInTriangle(vec2 p, vec2 a, vec2 b, vec2 c)
+# {
+#     const int array_size = 256;
+#     int array_a[array_size];
+#     float pab = cross2d(vec2(p.x - a.x, p.y - a.y), vec2(b.x - a.x, b.y - a.y));
+#     float pbc = cross2d(vec2(p.x - b.x, p.y - b.y), vec2(c.x - b.x, c.y - b.y));
+#     if (!((pab < 0.0 && pbc < 0.0) || (pab >= 0.0 && pbc >= 0.0)))
+#     {
+#         // Injected live code block has no impact on rest of the code in the shader.
+#         // Initialize array to known values.
+#         for (int i = 0; i < array_size; i++)
+#         {
+#             array_a[i] = 0;
+#         }
+#         // Total loop iteration count: 6x4x4x4 = 384.
+#         for (int int_a = 0; int_a < 6; )
+#         {
+#             int_a++;
+#             int int_c = 1;
+#             int int_h = 1;
+#             int int_d = 0;
+#             do
+#             {
+#                 int_d++;
+#                 int int_e = 0;
+#                 for (int int_f = 0; int_f < 4; int_c++)
+#                 {
+#                     int_f++;
+#                     for (int int_g = 0; int_g < 4; int_e++)
+#                     {
+#                         int_g++;
+#                         if (array_a[clamp(int_e * 2 + 32, 0, array_size - 1)] == 0)
+#                         {
+#                             int_h = int_c;
+#                         }
+#                     }
+#                 }
+#                 array_a[clamp(1 + int_h * 16, 0, array_size - 1)] = 1;
+#             } while (int_d < 4);
+#         }
+#         return 0;
+#     }
+#     float pca = cross2d(vec2(p.x - c.x, p.y - c.y), vec2(a.x - c.x, a.y - c.y));
+#     if (!((pab < 0.0 && pca < 0.0) || (pab >= 0.0 && pca >= 0.0)))
+#     {
+#         return 0;
+#     }
+#     return 1;
+# }
+# void main()
+# {
+#     vec2 pos = gl_FragCoord.xy / resolution;
+#     if (pointInTriangle(pos, vec2(0.7, 0.3), vec2(0.5, 0.9), vec2(0.1, 0.4)) == 1)
+#     {
+#         _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#     }
+#     else
+#     {
+#         _GLF_color = vec4(0.0, 0.0, 0.0, 1.0);
+#     }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 318
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %247 %276
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %12 "cross2d(vf2;vf2;"
+               OpName %10 "a"
+               OpName %11 "b"
+               OpName %20 "pointInTriangle(vf2;vf2;vf2;vf2;"
+               OpName %16 "p"
+               OpName %17 "a"
+               OpName %18 "b"
+               OpName %19 "c"
+               OpName %39 "pab"
+               OpName %62 "param"
+               OpName %63 "param"
+               OpName %65 "pbc"
+               OpName %88 "param"
+               OpName %89 "param"
+               OpName %111 "i"
+               OpName %124 "array_a"
+               OpName %130 "int_a"
+               OpName %141 "int_c"
+               OpName %142 "int_h"
+               OpName %143 "int_d"
+               OpName %150 "int_e"
+               OpName %151 "int_f"
+               OpName %162 "int_g"
+               OpName %198 "pca"
+               OpName %221 "param"
+               OpName %222 "param"
+               OpName %244 "pos"
+               OpName %247 "gl_FragCoord"
+               OpName %250 "buf0"
+               OpMemberName %250 0 "resolution"
+               OpName %252 ""
+               OpName %266 "param"
+               OpName %268 "param"
+               OpName %269 "param"
+               OpName %270 "param"
+               OpName %276 "_GLF_color"
+               OpDecorate %247 BuiltIn FragCoord
+               OpMemberDecorate %250 0 Offset 0
+               OpDecorate %250 Block
+               OpDecorate %252 DescriptorSet 0
+               OpDecorate %252 Binding 0
+               OpDecorate %276 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 2
+          %8 = OpTypePointer Function %7
+          %9 = OpTypeFunction %6 %8 %8
+         %14 = OpTypeInt 32 1
+         %15 = OpTypeFunction %14 %8 %8 %8 %8
+         %22 = OpTypeInt 32 0
+         %23 = OpConstant %22 0
+         %24 = OpTypePointer Function %6
+         %27 = OpConstant %22 1
+         %91 = OpTypeBool
+         %93 = OpConstant %6 0
+        %110 = OpTypePointer Function %14
+        %112 = OpConstant %14 0
+        %119 = OpConstant %14 256
+        %121 = OpConstant %22 256
+        %122 = OpTypeArray %14 %121
+        %123 = OpTypePointer Function %122
+        %128 = OpConstant %14 1
+        %137 = OpConstant %14 6
+        %158 = OpConstant %14 4
+        %173 = OpConstant %14 2
+        %175 = OpConstant %14 32
+        %177 = OpConstant %14 255
+        %190 = OpConstant %14 16
+        %245 = OpTypeVector %6 4
+        %246 = OpTypePointer Input %245
+        %247 = OpVariable %246 Input
+        %250 = OpTypeStruct %7
+        %251 = OpTypePointer Uniform %250
+        %252 = OpVariable %251 Uniform
+        %253 = OpTypePointer Uniform %7
+        %257 = OpConstant %6 0.699999988
+        %258 = OpConstant %6 0.300000012
+        %259 = OpConstantComposite %7 %257 %258
+        %260 = OpConstant %6 0.5
+        %261 = OpConstant %6 0.899999976
+        %262 = OpConstantComposite %7 %260 %261
+        %263 = OpConstant %6 0.100000001
+        %264 = OpConstant %6 0.400000006
+        %265 = OpConstantComposite %7 %263 %264
+        %275 = OpTypePointer Output %245
+        %276 = OpVariable %275 Output
+        %277 = OpConstant %6 1
+        %278 = OpConstantComposite %245 %277 %93 %93 %277
+        %280 = OpConstantComposite %245 %93 %93 %93 %277
+        %285 = OpConstantFalse %91
+        %286 = OpTypePointer Function %91
+        %288 = OpConstantTrue %91
+        %317 = OpConstant %14 17
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %244 = OpVariable %8 Function
+        %266 = OpVariable %8 Function
+        %268 = OpVariable %8 Function
+        %269 = OpVariable %8 Function
+        %270 = OpVariable %8 Function
+        %248 = OpLoad %245 %247
+        %249 = OpVectorShuffle %7 %248 %248 0 1
+        %254 = OpAccessChain %253 %252 %112
+        %255 = OpLoad %7 %254
+        %256 = OpFDiv %7 %249 %255
+               OpStore %244 %256
+               OpStore %266 %256
+               OpStore %268 %259
+               OpStore %269 %262
+               OpStore %270 %265
+        %271 = OpFunctionCall %14 %20 %266 %268 %269 %270
+        %272 = OpIEqual %91 %271 %128
+               OpSelectionMerge %274 None
+               OpBranchConditional %272 %273 %279
+        %273 = OpLabel
+               OpStore %276 %278
+               OpBranch %274
+        %279 = OpLabel
+               OpStore %276 %280
+               OpBranch %274
+        %274 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %12 = OpFunction %6 None %9
+         %10 = OpFunctionParameter %8
+         %11 = OpFunctionParameter %8
+         %13 = OpLabel
+         %25 = OpAccessChain %24 %10 %23
+         %26 = OpLoad %6 %25
+         %28 = OpAccessChain %24 %11 %27
+         %29 = OpLoad %6 %28
+         %30 = OpFMul %6 %26 %29
+         %31 = OpAccessChain %24 %11 %23
+         %32 = OpLoad %6 %31
+         %33 = OpAccessChain %24 %10 %27
+         %34 = OpLoad %6 %33
+         %35 = OpFMul %6 %32 %34
+         %36 = OpFSub %6 %30 %35
+               OpReturnValue %36
+               OpFunctionEnd
+         %20 = OpFunction %14 None %15
+         %16 = OpFunctionParameter %8
+         %17 = OpFunctionParameter %8
+         %18 = OpFunctionParameter %8
+         %19 = OpFunctionParameter %8
+         %21 = OpLabel
+        %287 = OpVariable %286 Function %285
+        %282 = OpVariable %110 Function
+         %39 = OpVariable %24 Function
+         %62 = OpVariable %8 Function
+         %63 = OpVariable %8 Function
+         %65 = OpVariable %24 Function
+         %88 = OpVariable %8 Function
+         %89 = OpVariable %8 Function
+        %111 = OpVariable %110 Function
+        %124 = OpVariable %123 Function
+        %130 = OpVariable %110 Function
+        %141 = OpVariable %110 Function
+        %142 = OpVariable %110 Function
+        %143 = OpVariable %110 Function
+        %150 = OpVariable %110 Function
+        %151 = OpVariable %110 Function
+        %162 = OpVariable %110 Function
+        %198 = OpVariable %24 Function
+        %221 = OpVariable %8 Function
+        %222 = OpVariable %8 Function
+               OpSelectionMerge %281 None
+               OpSwitch %23 %284
+        %284 = OpLabel
+         %40 = OpAccessChain %24 %16 %23
+         %41 = OpLoad %6 %40
+         %42 = OpAccessChain %24 %17 %23
+         %43 = OpLoad %6 %42
+         %44 = OpFSub %6 %41 %43
+         %45 = OpAccessChain %24 %16 %27
+         %46 = OpLoad %6 %45
+         %47 = OpAccessChain %24 %17 %27
+         %48 = OpLoad %6 %47
+         %49 = OpFSub %6 %46 %48
+         %50 = OpCompositeConstruct %7 %44 %49
+         %51 = OpAccessChain %24 %18 %23
+         %52 = OpLoad %6 %51
+         %54 = OpLoad %6 %42
+         %55 = OpFSub %6 %52 %54
+         %56 = OpAccessChain %24 %18 %27
+         %57 = OpLoad %6 %56
+         %59 = OpLoad %6 %47
+         %60 = OpFSub %6 %57 %59
+         %61 = OpCompositeConstruct %7 %55 %60
+               OpStore %62 %50
+               OpStore %63 %61
+         %64 = OpFunctionCall %6 %12 %62 %63
+               OpStore %39 %64
+         %67 = OpLoad %6 %40
+         %69 = OpLoad %6 %51
+         %70 = OpFSub %6 %67 %69
+         %72 = OpLoad %6 %45
+         %74 = OpLoad %6 %56
+         %75 = OpFSub %6 %72 %74
+         %76 = OpCompositeConstruct %7 %70 %75
+         %77 = OpAccessChain %24 %19 %23
+         %78 = OpLoad %6 %77
+         %80 = OpLoad %6 %51
+         %81 = OpFSub %6 %78 %80
+         %82 = OpAccessChain %24 %19 %27
+         %83 = OpLoad %6 %82
+         %85 = OpLoad %6 %56
+         %86 = OpFSub %6 %83 %85
+         %87 = OpCompositeConstruct %7 %81 %86
+               OpStore %88 %76
+               OpStore %89 %87
+         %90 = OpFunctionCall %6 %12 %88 %89
+               OpStore %65 %90
+         %94 = OpFOrdLessThan %91 %64 %93
+         %96 = OpFOrdLessThan %91 %90 %93
+         %97 = OpLogicalAnd %91 %94 %96
+         %98 = OpLogicalNot %91 %97
+               OpSelectionMerge %100 None
+               OpBranchConditional %98 %99 %100
+         %99 = OpLabel
+        %102 = OpFOrdGreaterThanEqual %91 %64 %93
+        %104 = OpFOrdGreaterThanEqual %91 %90 %93
+        %105 = OpLogicalAnd %91 %102 %104
+               OpBranch %100
+        %100 = OpLabel
+        %106 = OpPhi %91 %97 %284 %105 %99
+        %107 = OpLogicalNot %91 %106
+               OpSelectionMerge %109 None
+               OpBranchConditional %107 %108 %109
+        %108 = OpLabel
+               OpStore %111 %112
+               OpBranch %113
+        %113 = OpLabel
+        %290 = OpPhi %14 %112 %108 %129 %116
+               OpLoopMerge %115 %116 None
+               OpBranch %117
+        %117 = OpLabel
+        %120 = OpSLessThan %91 %290 %119
+               OpBranchConditional %120 %114 %115
+        %114 = OpLabel
+        %126 = OpAccessChain %110 %124 %290
+               OpStore %126 %112
+               OpBranch %116
+        %116 = OpLabel
+        %129 = OpIAdd %14 %290 %128
+               OpStore %111 %129
+               OpBranch %113
+        %115 = OpLabel
+               OpStore %130 %112
+               OpBranch %131
+        %131 = OpLabel
+        %291 = OpPhi %14 %112 %115 %306 %134
+               OpLoopMerge %133 %134 None
+               OpBranch %135
+        %135 = OpLabel
+        %138 = OpSLessThan %91 %291 %137
+               OpBranchConditional %138 %132 %133
+        %132 = OpLabel
+        %140 = OpIAdd %14 %291 %128
+               OpStore %130 %140
+               OpStore %141 %128
+               OpStore %142 %128
+               OpStore %143 %112
+               OpBranch %144
+        %144 = OpLabel
+        %296 = OpPhi %14 %128 %132 %295 %147
+        %293 = OpPhi %14 %112 %132 %149 %147
+        %306 = OpPhi %14 %140 %132 %306 %147
+        %301 = OpPhi %14 %128 %132 %300 %147
+               OpLoopMerge %146 %147 None
+               OpBranch %145
+        %145 = OpLabel
+        %149 = OpIAdd %14 %293 %128
+               OpStore %143 %149
+               OpStore %150 %112
+               OpStore %151 %112
+               OpBranch %152
+        %152 = OpLabel
+        %300 = OpPhi %14 %301 %145 %188 %155
+        %295 = OpPhi %14 %296 %145 %311 %155
+        %294 = OpPhi %14 %112 %145 %161 %155
+        %303 = OpPhi %14 %112 %145 %302 %155
+               OpLoopMerge %154 %155 None
+               OpBranch %156
+        %156 = OpLabel
+        %159 = OpSLessThan %91 %294 %158
+               OpBranchConditional %159 %153 %154
+        %153 = OpLabel
+        %161 = OpIAdd %14 %294 %128
+               OpStore %151 %161
+               OpStore %162 %112
+               OpBranch %163
+        %163 = OpLabel
+        %302 = OpPhi %14 %303 %153 %186 %166
+        %298 = OpPhi %14 %112 %153 %171 %166
+        %311 = OpPhi %14 %295 %153 %312 %166
+               OpLoopMerge %165 %166 None
+               OpBranch %167
+        %167 = OpLabel
+        %169 = OpSLessThan %91 %298 %158
+               OpBranchConditional %169 %164 %165
+        %164 = OpLabel
+        %171 = OpIAdd %14 %298 %128
+               OpStore %162 %171
+        %174 = OpIMul %14 %302 %173
+        %176 = OpIAdd %14 %174 %175
+        %178 = OpExtInst %14 %1 SClamp %176 %112 %177
+        %179 = OpAccessChain %110 %124 %178
+        %180 = OpLoad %14 %179
+        %181 = OpIEqual %91 %180 %112
+               OpSelectionMerge %183 None
+               OpBranchConditional %181 %182 %183
+        %182 = OpLabel
+               OpStore %142 %300
+               OpBranch %183
+        %183 = OpLabel
+        %312 = OpPhi %14 %311 %164 %300 %182
+               OpBranch %166
+        %166 = OpLabel
+        %186 = OpIAdd %14 %302 %128
+               OpStore %150 %186
+               OpBranch %163
+        %165 = OpLabel
+               OpBranch %155
+        %155 = OpLabel
+        %188 = OpIAdd %14 %300 %128
+               OpStore %141 %188
+               OpBranch %152
+        %154 = OpLabel
+        %191 = OpIMul %14 %295 %190
+        %192 = OpIAdd %14 %128 %191
+        %193 = OpExtInst %14 %1 SClamp %192 %112 %177
+        %194 = OpAccessChain %110 %124 %193
+               OpStore %194 %128
+               OpBranch %147
+        %147 = OpLabel
+        %196 = OpSLessThan %91 %149 %158
+               OpBranchConditional %196 %144 %146
+        %146 = OpLabel
+               OpBranch %134
+        %134 = OpLabel
+               OpBranch %131
+        %133 = OpLabel
+               OpStore %287 %288
+               OpStore %282 %112
+               OpBranch %281
+        %109 = OpLabel
+        %200 = OpLoad %6 %40
+        %202 = OpLoad %6 %77
+        %203 = OpFSub %6 %200 %202
+        %205 = OpLoad %6 %45
+        %207 = OpLoad %6 %82
+        %208 = OpFSub %6 %205 %207
+        %209 = OpCompositeConstruct %7 %203 %208
+        %211 = OpLoad %6 %42
+        %213 = OpLoad %6 %77
+        %214 = OpFSub %6 %211 %213
+        %216 = OpLoad %6 %47
+        %218 = OpLoad %6 %82
+        %219 = OpFSub %6 %216 %218
+        %220 = OpCompositeConstruct %7 %214 %219
+               OpStore %221 %209
+               OpStore %222 %220
+        %223 = OpFunctionCall %6 %12 %221 %222
+               OpStore %198 %223
+        %225 = OpFOrdLessThan %91 %64 %93
+        %227 = OpFOrdLessThan %91 %223 %93
+        %228 = OpLogicalAnd %91 %225 %227
+        %229 = OpLogicalNot %91 %228
+               OpSelectionMerge %231 None
+               OpBranchConditional %229 %230 %231
+        %230 = OpLabel
+        %233 = OpFOrdGreaterThanEqual %91 %64 %93
+        %235 = OpFOrdGreaterThanEqual %91 %223 %93
+        %236 = OpLogicalAnd %91 %233 %235
+               OpBranch %231
+        %231 = OpLabel
+        %237 = OpPhi %91 %228 %109 %236 %230
+        %238 = OpLogicalNot %91 %237
+               OpSelectionMerge %240 None
+               OpBranchConditional %238 %239 %240
+        %239 = OpLabel
+               OpStore %287 %288
+               OpStore %282 %112
+               OpBranch %281
+        %240 = OpLabel
+               OpStore %287 %288
+               OpStore %282 %128
+               OpBranch %281
+        %281 = OpLabel
+        %292 = OpPhi %14 %112 %133 %112 %239 %128 %240
+               OpReturnValue %292
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# resolution
+BUFFER variant_resolution DATA_TYPE vec2<float> DATA
+ 256.0 256.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 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 reference_framebuffer EQ_HISTOGRAM_EMD_BUFFER variant_framebuffer TOLERANCE 0.005
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-triangle-nested-for-loop-and-true-if.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-triangle-nested-for-loop-and-true-if.amber
new file mode 100644 (file)
index 0000000..345efbd
--- /dev/null
@@ -0,0 +1,771 @@
+#!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 nested for loop and always true if
+
+# The test passes because both shaders render the same image.
+
+# Optimized using spirv-opt with the following arguments:
+# '--if-conversion'
+# '--eliminate-local-multi-store'
+# '--eliminate-dead-inserts'
+# '--scalar-replacement=100'
+# '--simplify-instructions'
+# '--reduce-load-size'
+# '--copy-propagate-arrays'
+# '--private-to-local'
+# '--ccp'
+# '--redundancy-elimination'
+# '--vector-dce'
+# '--eliminate-local-multi-store'
+# '--eliminate-dead-code-aggressive'
+# '--private-to-local'
+# '--convert-local-access-chains'
+# '--if-conversion'
+# '--inline-entry-points-exhaustive'
+# '--eliminate-dead-code-aggressive'
+# '--eliminate-local-single-block'
+# '--if-conversion'
+# spirv-opt commit hash: 230f363e6da32791f640b02205e0645cc67c3f1d
+
+
+
+SHADER vertex reference_vertex_shader PASSTHROUGH
+
+# reference_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 resolution;
+# };
+# float cross2d(vec2 a, vec2 b)
+# {
+#     return ((a.x) * (b.y) - (b.x) * (a.y));
+# }
+# int pointInTriangle(vec2 p, vec2 a, vec2 b, vec2 c)
+# {
+#     float pab = cross2d(vec2(p.x - a.x, p.y - a.y), vec2(b.x - a.x, b.y - a.y));
+#     float pbc = cross2d(vec2(p.x - b.x, p.y - b.y), vec2(c.x - b.x, c.y - b.y));
+#     if (!((pab < 0.0 && pbc < 0.0) || (pab >= 0.0 && pbc >= 0.0)))
+#     {
+#         return 0;
+#     }
+#     float pca = cross2d(vec2(p.x - c.x, p.y - c.y), vec2(a.x - c.x, a.y - c.y));
+#     if (!((pab < 0.0 && pca < 0.0) || (pab >= 0.0 && pca >= 0.0)))
+#     {
+#         return 0;
+#     }
+#     return 1;
+# }
+# void main()
+# {
+#     vec2 pos = gl_FragCoord.xy / resolution;
+#     if (pointInTriangle(pos, vec2(0.7, 0.3), vec2(0.5, 0.9), vec2(0.1, 0.4)) == 1)
+#     {
+#         _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#     }
+#     else
+#     {
+#         _GLF_color = vec4(0.0, 0.0, 0.0, 1.0);
+#     }
+# }
+SHADER fragment reference_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 236
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %162 %191
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %20 "pointInTriangle(vf2;vf2;vf2;vf2;"
+               OpName %16 "p"
+               OpName %17 "a"
+               OpName %18 "b"
+               OpName %19 "c"
+               OpName %62 "param"
+               OpName %63 "param"
+               OpName %88 "param"
+               OpName %89 "param"
+               OpName %135 "param"
+               OpName %136 "param"
+               OpName %162 "gl_FragCoord"
+               OpName %165 "buf0"
+               OpMemberName %165 0 "resolution"
+               OpName %167 ""
+               OpName %181 "param"
+               OpName %183 "param"
+               OpName %184 "param"
+               OpName %185 "param"
+               OpName %191 "_GLF_color"
+               OpDecorate %162 BuiltIn FragCoord
+               OpMemberDecorate %165 0 Offset 0
+               OpDecorate %165 Block
+               OpDecorate %167 DescriptorSet 0
+               OpDecorate %167 Binding 0
+               OpDecorate %191 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 2
+          %8 = OpTypePointer Function %7
+         %14 = OpTypeInt 32 1
+         %15 = OpTypeFunction %14 %8 %8 %8 %8
+         %22 = OpTypeInt 32 0
+         %23 = OpConstant %22 0
+         %24 = OpTypePointer Function %6
+         %27 = OpConstant %22 1
+         %91 = OpTypeBool
+         %93 = OpConstant %6 0
+        %110 = OpConstant %14 0
+        %156 = OpConstant %14 1
+        %160 = OpTypeVector %6 4
+        %161 = OpTypePointer Input %160
+        %162 = OpVariable %161 Input
+        %165 = OpTypeStruct %7
+        %166 = OpTypePointer Uniform %165
+        %167 = OpVariable %166 Uniform
+        %168 = OpTypePointer Uniform %7
+        %172 = OpConstant %6 0.699999988
+        %173 = OpConstant %6 0.300000012
+        %174 = OpConstantComposite %7 %172 %173
+        %175 = OpConstant %6 0.5
+        %176 = OpConstant %6 0.899999976
+        %177 = OpConstantComposite %7 %175 %176
+        %178 = OpConstant %6 0.100000001
+        %179 = OpConstant %6 0.400000006
+        %180 = OpConstantComposite %7 %178 %179
+        %190 = OpTypePointer Output %160
+        %191 = OpVariable %190 Output
+        %192 = OpConstant %6 1
+        %193 = OpConstantComposite %160 %192 %93 %93 %192
+        %195 = OpConstantComposite %160 %93 %93 %93 %192
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %181 = OpVariable %8 Function
+        %183 = OpVariable %8 Function
+        %184 = OpVariable %8 Function
+        %185 = OpVariable %8 Function
+        %163 = OpLoad %160 %162
+        %164 = OpVectorShuffle %7 %163 %163 0 1
+        %169 = OpAccessChain %168 %167 %110
+        %170 = OpLoad %7 %169
+        %171 = OpFDiv %7 %164 %170
+               OpStore %181 %171
+               OpStore %183 %174
+               OpStore %184 %177
+               OpStore %185 %180
+        %186 = OpFunctionCall %14 %20 %181 %183 %184 %185
+        %187 = OpIEqual %91 %186 %156
+               OpSelectionMerge %189 None
+               OpBranchConditional %187 %188 %194
+        %188 = OpLabel
+               OpStore %191 %193
+               OpBranch %189
+        %194 = OpLabel
+               OpStore %191 %195
+               OpBranch %189
+        %189 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %20 = OpFunction %14 None %15
+         %16 = OpFunctionParameter %8
+         %17 = OpFunctionParameter %8
+         %18 = OpFunctionParameter %8
+         %19 = OpFunctionParameter %8
+         %21 = OpLabel
+        %223 = OpVariable %24 Function
+        %210 = OpVariable %24 Function
+        %197 = OpVariable %24 Function
+         %62 = OpVariable %8 Function
+         %63 = OpVariable %8 Function
+         %88 = OpVariable %8 Function
+         %89 = OpVariable %8 Function
+        %135 = OpVariable %8 Function
+        %136 = OpVariable %8 Function
+         %40 = OpAccessChain %24 %16 %23
+         %41 = OpLoad %6 %40
+         %42 = OpAccessChain %24 %17 %23
+         %43 = OpLoad %6 %42
+         %44 = OpFSub %6 %41 %43
+         %45 = OpAccessChain %24 %16 %27
+         %46 = OpLoad %6 %45
+         %47 = OpAccessChain %24 %17 %27
+         %48 = OpLoad %6 %47
+         %49 = OpFSub %6 %46 %48
+         %50 = OpCompositeConstruct %7 %44 %49
+         %51 = OpAccessChain %24 %18 %23
+         %52 = OpLoad %6 %51
+         %54 = OpLoad %6 %42
+         %55 = OpFSub %6 %52 %54
+         %56 = OpAccessChain %24 %18 %27
+         %57 = OpLoad %6 %56
+         %59 = OpLoad %6 %47
+         %60 = OpFSub %6 %57 %59
+         %61 = OpCompositeConstruct %7 %55 %60
+               OpStore %62 %50
+               OpStore %63 %61
+        %199 = OpAccessChain %24 %62 %23
+        %200 = OpLoad %6 %199
+        %201 = OpAccessChain %24 %63 %27
+        %202 = OpLoad %6 %201
+        %203 = OpFMul %6 %200 %202
+        %204 = OpAccessChain %24 %63 %23
+        %205 = OpLoad %6 %204
+        %206 = OpAccessChain %24 %62 %27
+        %207 = OpLoad %6 %206
+        %208 = OpFMul %6 %205 %207
+        %209 = OpFSub %6 %203 %208
+               OpStore %197 %209
+         %67 = OpLoad %6 %40
+         %69 = OpLoad %6 %51
+         %70 = OpFSub %6 %67 %69
+         %72 = OpLoad %6 %45
+         %74 = OpLoad %6 %56
+         %75 = OpFSub %6 %72 %74
+         %76 = OpCompositeConstruct %7 %70 %75
+         %77 = OpAccessChain %24 %19 %23
+         %78 = OpLoad %6 %77
+         %80 = OpLoad %6 %51
+         %81 = OpFSub %6 %78 %80
+         %82 = OpAccessChain %24 %19 %27
+         %83 = OpLoad %6 %82
+         %85 = OpLoad %6 %56
+         %86 = OpFSub %6 %83 %85
+         %87 = OpCompositeConstruct %7 %81 %86
+               OpStore %88 %76
+               OpStore %89 %87
+        %212 = OpAccessChain %24 %88 %23
+        %213 = OpLoad %6 %212
+        %214 = OpAccessChain %24 %89 %27
+        %215 = OpLoad %6 %214
+        %216 = OpFMul %6 %213 %215
+        %217 = OpAccessChain %24 %89 %23
+        %218 = OpLoad %6 %217
+        %219 = OpAccessChain %24 %88 %27
+        %220 = OpLoad %6 %219
+        %221 = OpFMul %6 %218 %220
+        %222 = OpFSub %6 %216 %221
+               OpStore %210 %222
+         %94 = OpFOrdLessThan %91 %209 %93
+         %96 = OpFOrdLessThan %91 %222 %93
+         %97 = OpLogicalAnd %91 %94 %96
+         %98 = OpLogicalNot %91 %97
+               OpSelectionMerge %100 None
+               OpBranchConditional %98 %99 %100
+         %99 = OpLabel
+        %102 = OpFOrdGreaterThanEqual %91 %209 %93
+        %104 = OpFOrdGreaterThanEqual %91 %222 %93
+        %105 = OpLogicalAnd %91 %102 %104
+               OpBranch %100
+        %100 = OpLabel
+        %106 = OpPhi %91 %97 %21 %105 %99
+        %107 = OpLogicalNot %91 %106
+               OpSelectionMerge %109 None
+               OpBranchConditional %107 %108 %109
+        %108 = OpLabel
+               OpReturnValue %110
+        %109 = OpLabel
+        %114 = OpLoad %6 %40
+        %116 = OpLoad %6 %77
+        %117 = OpFSub %6 %114 %116
+        %119 = OpLoad %6 %45
+        %121 = OpLoad %6 %82
+        %122 = OpFSub %6 %119 %121
+        %123 = OpCompositeConstruct %7 %117 %122
+        %125 = OpLoad %6 %42
+        %127 = OpLoad %6 %77
+        %128 = OpFSub %6 %125 %127
+        %130 = OpLoad %6 %47
+        %132 = OpLoad %6 %82
+        %133 = OpFSub %6 %130 %132
+        %134 = OpCompositeConstruct %7 %128 %133
+               OpStore %135 %123
+               OpStore %136 %134
+        %225 = OpAccessChain %24 %135 %23
+        %226 = OpLoad %6 %225
+        %227 = OpAccessChain %24 %136 %27
+        %228 = OpLoad %6 %227
+        %229 = OpFMul %6 %226 %228
+        %230 = OpAccessChain %24 %136 %23
+        %231 = OpLoad %6 %230
+        %232 = OpAccessChain %24 %135 %27
+        %233 = OpLoad %6 %232
+        %234 = OpFMul %6 %231 %233
+        %235 = OpFSub %6 %229 %234
+               OpStore %223 %235
+        %141 = OpFOrdLessThan %91 %235 %93
+        %142 = OpLogicalAnd %91 %94 %141
+        %143 = OpLogicalNot %91 %142
+               OpSelectionMerge %145 None
+               OpBranchConditional %143 %144 %145
+        %144 = OpLabel
+        %147 = OpFOrdGreaterThanEqual %91 %209 %93
+        %149 = OpFOrdGreaterThanEqual %91 %235 %93
+        %150 = OpLogicalAnd %91 %147 %149
+               OpBranch %145
+        %145 = OpLabel
+        %151 = OpPhi %91 %142 %109 %150 %144
+        %152 = OpLogicalNot %91 %151
+               OpSelectionMerge %154 None
+               OpBranchConditional %152 %153 %154
+        %153 = OpLabel
+               OpReturnValue %110
+        %154 = OpLabel
+               OpReturnValue %156
+               OpFunctionEnd
+END
+
+# uniforms for reference
+
+# resolution
+BUFFER reference_resolution DATA_TYPE vec2<float> DATA
+ 256.0 256.0
+END
+
+BUFFER reference_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics reference_pipeline
+  ATTACH reference_vertex_shader
+  ATTACH reference_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER reference_framebuffer AS color LOCATION 0
+  BIND BUFFER reference_resolution AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR reference_pipeline 0 0 0 255
+
+CLEAR reference_pipeline
+RUN reference_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 resolution;
+# };
+# layout(set = 0, binding = 1) uniform buf1
+# {
+#     vec2 injectionSwitch; // x == 0.0, y == 1.0
+# };
+#
+# void func()
+# {
+#     vec4 vec4_a = vec4(1.0, 1.0, 1.0, 1.0);
+#     // Iterates once.
+#     for (int int_i = 0; int_i < int(injectionSwitch.y); int_i++)
+#     {
+#         // _GLF_color == 1.0, 1.0, 1.0, 1.0
+#         _GLF_color = vec4_a;
+#         // Iterates once.
+#         for (int int_j = 0; int_j < int(injectionSwitch.y); int_j++)
+#         {
+#             // _GLF_color == 1.0, 1.0, 1.0, 1.0
+#             _GLF_color = vec4_a;
+#         }
+#     }
+# }
+#
+# float cross2d(vec2 a, vec2 b)
+# {
+#     return ((a.x) * (b.y) - (b.x) * (a.y));
+# }
+# int pointInTriangle(vec2 p, vec2 a, vec2 b, vec2 c)
+# {
+#     float pab = cross2d(vec2(p.x - a.x, p.y - a.y), vec2(b.x - a.x, b.y - a.y));
+#     float pbc = cross2d(vec2(p.x - b.x, p.y - b.y), vec2(c.x - b.x, c.y - b.y));
+#     if (!((pab < 0.0 && pbc < 0.0) || (pab >= 0.0 && pbc >= 0.0)))
+#     {
+#         func();
+#         return 0;
+#     }
+#     float pca = cross2d(vec2(p.x - c.x, p.y - c.y), vec2(a.x - c.x, a.y - c.y));
+#     if (!((pab < 0.0 && pca < 0.0) || (pab >= 0.0 && pca >= 0.0)))
+#     {
+#         return 0;
+#     }
+#     return 1;
+# }
+# void main()
+# {
+#     vec2 pos = gl_FragCoord.xy / resolution;
+#     if (pointInTriangle(pos, vec2(0.7, 0.3), vec2(0.5, 0.9), vec2(0.1, 0.4)) == 1)
+#     {
+#         // Always true.
+#         if ((injectionSwitch.y >= injectionSwitch.x))
+#         {
+#             _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#         }
+#     }
+#     else
+#     {
+#         _GLF_color = vec4(0.0, 0.0, 0.0, 1.0);
+#     }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 307
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %50 %204
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %22 "pointInTriangle(vf2;vf2;vf2;vf2;"
+               OpName %18 "p"
+               OpName %19 "a"
+               OpName %20 "b"
+               OpName %21 "c"
+               OpName %38 "buf1"
+               OpMemberName %38 0 "injectionSwitch"
+               OpName %40 ""
+               OpName %50 "_GLF_color"
+               OpName %107 "param"
+               OpName %108 "param"
+               OpName %133 "param"
+               OpName %134 "param"
+               OpName %179 "param"
+               OpName %180 "param"
+               OpName %204 "gl_FragCoord"
+               OpName %207 "buf0"
+               OpMemberName %207 0 "resolution"
+               OpName %209 ""
+               OpName %223 "param"
+               OpName %225 "param"
+               OpName %226 "param"
+               OpName %227 "param"
+               OpMemberDecorate %38 0 Offset 0
+               OpDecorate %38 Block
+               OpDecorate %40 DescriptorSet 0
+               OpDecorate %40 Binding 1
+               OpDecorate %50 Location 0
+               OpDecorate %204 BuiltIn FragCoord
+               OpMemberDecorate %207 0 Offset 0
+               OpDecorate %207 Block
+               OpDecorate %209 DescriptorSet 0
+               OpDecorate %209 Binding 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %8 = OpTypeFloat 32
+          %9 = OpTypeVector %8 2
+         %10 = OpTypePointer Function %9
+         %16 = OpTypeInt 32 1
+         %17 = OpTypeFunction %16 %10 %10 %10 %10
+         %24 = OpTypeVector %8 4
+         %27 = OpConstant %8 1
+         %28 = OpConstantComposite %24 %27 %27 %27 %27
+         %31 = OpConstant %16 0
+         %38 = OpTypeStruct %9
+         %39 = OpTypePointer Uniform %38
+         %40 = OpVariable %39 Uniform
+         %41 = OpTypeInt 32 0
+         %42 = OpConstant %41 1
+         %43 = OpTypePointer Uniform %8
+         %47 = OpTypeBool
+         %49 = OpTypePointer Output %24
+         %50 = OpVariable %49 Output
+         %65 = OpConstant %16 1
+         %69 = OpConstant %41 0
+         %70 = OpTypePointer Function %8
+        %137 = OpConstant %8 0
+        %203 = OpTypePointer Input %24
+        %204 = OpVariable %203 Input
+        %207 = OpTypeStruct %9
+        %208 = OpTypePointer Uniform %207
+        %209 = OpVariable %208 Uniform
+        %210 = OpTypePointer Uniform %9
+        %214 = OpConstant %8 0.699999988
+        %215 = OpConstant %8 0.300000012
+        %216 = OpConstantComposite %9 %214 %215
+        %217 = OpConstant %8 0.5
+        %218 = OpConstant %8 0.899999976
+        %219 = OpConstantComposite %9 %217 %218
+        %220 = OpConstant %8 0.100000001
+        %221 = OpConstant %8 0.400000006
+        %222 = OpConstantComposite %9 %220 %221
+        %239 = OpConstantComposite %24 %27 %137 %137 %27
+        %241 = OpConstantComposite %24 %137 %137 %137 %27
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %223 = OpVariable %10 Function
+        %225 = OpVariable %10 Function
+        %226 = OpVariable %10 Function
+        %227 = OpVariable %10 Function
+        %205 = OpLoad %24 %204
+        %206 = OpVectorShuffle %9 %205 %205 0 1
+        %211 = OpAccessChain %210 %209 %31
+        %212 = OpLoad %9 %211
+        %213 = OpFDiv %9 %206 %212
+               OpStore %223 %213
+               OpStore %225 %216
+               OpStore %226 %219
+               OpStore %227 %222
+        %228 = OpFunctionCall %16 %22 %223 %225 %226 %227
+        %229 = OpIEqual %47 %228 %65
+               OpSelectionMerge %231 None
+               OpBranchConditional %229 %230 %240
+        %230 = OpLabel
+        %232 = OpAccessChain %43 %40 %31 %42
+        %233 = OpLoad %8 %232
+        %234 = OpAccessChain %43 %40 %31 %69
+        %235 = OpLoad %8 %234
+        %236 = OpFOrdGreaterThanEqual %47 %233 %235
+               OpSelectionMerge %238 None
+               OpBranchConditional %236 %237 %238
+        %237 = OpLabel
+               OpStore %50 %239
+               OpBranch %238
+        %238 = OpLabel
+               OpBranch %231
+        %240 = OpLabel
+               OpStore %50 %241
+               OpBranch %231
+        %231 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %22 = OpFunction %16 None %17
+         %18 = OpFunctionParameter %10
+         %19 = OpFunctionParameter %10
+         %20 = OpFunctionParameter %10
+         %21 = OpFunctionParameter %10
+         %23 = OpLabel
+        %294 = OpVariable %70 Function
+        %261 = OpVariable %70 Function
+        %248 = OpVariable %70 Function
+        %107 = OpVariable %10 Function
+        %108 = OpVariable %10 Function
+        %133 = OpVariable %10 Function
+        %134 = OpVariable %10 Function
+        %179 = OpVariable %10 Function
+        %180 = OpVariable %10 Function
+         %85 = OpAccessChain %70 %18 %69
+         %86 = OpLoad %8 %85
+         %87 = OpAccessChain %70 %19 %69
+         %88 = OpLoad %8 %87
+         %89 = OpFSub %8 %86 %88
+         %90 = OpAccessChain %70 %18 %42
+         %91 = OpLoad %8 %90
+         %92 = OpAccessChain %70 %19 %42
+         %93 = OpLoad %8 %92
+         %94 = OpFSub %8 %91 %93
+         %95 = OpCompositeConstruct %9 %89 %94
+         %96 = OpAccessChain %70 %20 %69
+         %97 = OpLoad %8 %96
+         %99 = OpLoad %8 %87
+        %100 = OpFSub %8 %97 %99
+        %101 = OpAccessChain %70 %20 %42
+        %102 = OpLoad %8 %101
+        %104 = OpLoad %8 %92
+        %105 = OpFSub %8 %102 %104
+        %106 = OpCompositeConstruct %9 %100 %105
+               OpStore %107 %95
+               OpStore %108 %106
+        %250 = OpAccessChain %70 %107 %69
+        %251 = OpLoad %8 %250
+        %252 = OpAccessChain %70 %108 %42
+        %253 = OpLoad %8 %252
+        %254 = OpFMul %8 %251 %253
+        %255 = OpAccessChain %70 %108 %69
+        %256 = OpLoad %8 %255
+        %257 = OpAccessChain %70 %107 %42
+        %258 = OpLoad %8 %257
+        %259 = OpFMul %8 %256 %258
+        %260 = OpFSub %8 %254 %259
+               OpStore %248 %260
+        %112 = OpLoad %8 %85
+        %114 = OpLoad %8 %96
+        %115 = OpFSub %8 %112 %114
+        %117 = OpLoad %8 %90
+        %119 = OpLoad %8 %101
+        %120 = OpFSub %8 %117 %119
+        %121 = OpCompositeConstruct %9 %115 %120
+        %122 = OpAccessChain %70 %21 %69
+        %123 = OpLoad %8 %122
+        %125 = OpLoad %8 %96
+        %126 = OpFSub %8 %123 %125
+        %127 = OpAccessChain %70 %21 %42
+        %128 = OpLoad %8 %127
+        %130 = OpLoad %8 %101
+        %131 = OpFSub %8 %128 %130
+        %132 = OpCompositeConstruct %9 %126 %131
+               OpStore %133 %121
+               OpStore %134 %132
+        %263 = OpAccessChain %70 %133 %69
+        %264 = OpLoad %8 %263
+        %265 = OpAccessChain %70 %134 %42
+        %266 = OpLoad %8 %265
+        %267 = OpFMul %8 %264 %266
+        %268 = OpAccessChain %70 %134 %69
+        %269 = OpLoad %8 %268
+        %270 = OpAccessChain %70 %133 %42
+        %271 = OpLoad %8 %270
+        %272 = OpFMul %8 %269 %271
+        %273 = OpFSub %8 %267 %272
+               OpStore %261 %273
+        %138 = OpFOrdLessThan %47 %260 %137
+        %140 = OpFOrdLessThan %47 %273 %137
+        %141 = OpLogicalAnd %47 %138 %140
+        %142 = OpLogicalNot %47 %141
+               OpSelectionMerge %144 None
+               OpBranchConditional %142 %143 %144
+        %143 = OpLabel
+        %146 = OpFOrdGreaterThanEqual %47 %260 %137
+        %148 = OpFOrdGreaterThanEqual %47 %273 %137
+        %149 = OpLogicalAnd %47 %146 %148
+               OpBranch %144
+        %144 = OpLabel
+        %150 = OpPhi %47 %141 %23 %149 %143
+        %151 = OpLogicalNot %47 %150
+               OpSelectionMerge %153 None
+               OpBranchConditional %151 %152 %153
+        %152 = OpLabel
+               OpBranch %275
+        %275 = OpLabel
+        %276 = OpPhi %16 %31 %152 %292 %291
+               OpLoopMerge %293 %291 None
+               OpBranch %277
+        %277 = OpLabel
+        %278 = OpAccessChain %43 %40 %31 %42
+        %279 = OpLoad %8 %278
+        %280 = OpConvertFToS %16 %279
+        %281 = OpSLessThan %47 %276 %280
+               OpBranchConditional %281 %282 %293
+        %282 = OpLabel
+               OpStore %50 %28
+               OpBranch %283
+        %283 = OpLabel
+        %284 = OpPhi %16 %31 %282 %289 %288
+               OpLoopMerge %290 %288 None
+               OpBranch %285
+        %285 = OpLabel
+        %286 = OpSLessThan %47 %284 %280
+               OpBranchConditional %286 %287 %290
+        %287 = OpLabel
+               OpStore %50 %28
+               OpBranch %288
+        %288 = OpLabel
+        %289 = OpIAdd %16 %284 %65
+               OpBranch %283
+        %290 = OpLabel
+               OpBranch %291
+        %291 = OpLabel
+        %292 = OpIAdd %16 %276 %65
+               OpBranch %275
+        %293 = OpLabel
+               OpReturnValue %31
+        %153 = OpLabel
+        %158 = OpLoad %8 %85
+        %160 = OpLoad %8 %122
+        %161 = OpFSub %8 %158 %160
+        %163 = OpLoad %8 %90
+        %165 = OpLoad %8 %127
+        %166 = OpFSub %8 %163 %165
+        %167 = OpCompositeConstruct %9 %161 %166
+        %169 = OpLoad %8 %87
+        %171 = OpLoad %8 %122
+        %172 = OpFSub %8 %169 %171
+        %174 = OpLoad %8 %92
+        %176 = OpLoad %8 %127
+        %177 = OpFSub %8 %174 %176
+        %178 = OpCompositeConstruct %9 %172 %177
+               OpStore %179 %167
+               OpStore %180 %178
+        %296 = OpAccessChain %70 %179 %69
+        %297 = OpLoad %8 %296
+        %298 = OpAccessChain %70 %180 %42
+        %299 = OpLoad %8 %298
+        %300 = OpFMul %8 %297 %299
+        %301 = OpAccessChain %70 %180 %69
+        %302 = OpLoad %8 %301
+        %303 = OpAccessChain %70 %179 %42
+        %304 = OpLoad %8 %303
+        %305 = OpFMul %8 %302 %304
+        %306 = OpFSub %8 %300 %305
+               OpStore %294 %306
+        %185 = OpFOrdLessThan %47 %306 %137
+        %186 = OpLogicalAnd %47 %138 %185
+        %187 = OpLogicalNot %47 %186
+               OpSelectionMerge %189 None
+               OpBranchConditional %187 %188 %189
+        %188 = OpLabel
+        %191 = OpFOrdGreaterThanEqual %47 %260 %137
+        %193 = OpFOrdGreaterThanEqual %47 %306 %137
+        %194 = OpLogicalAnd %47 %191 %193
+               OpBranch %189
+        %189 = OpLabel
+        %195 = OpPhi %47 %186 %153 %194 %188
+        %196 = OpLogicalNot %47 %195
+               OpSelectionMerge %198 None
+               OpBranchConditional %196 %197 %198
+        %197 = OpLabel
+               OpReturnValue %31
+        %198 = OpLabel
+               OpReturnValue %65
+               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 0
+  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 1
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT reference_framebuffer EQ_HISTOGRAM_EMD_BUFFER variant_framebuffer TOLERANCE 0.005
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/vec2-modf.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/vec2-modf.amber
new file mode 100644 (file)
index 0000000..095dc26
--- /dev/null
@@ -0,0 +1,129 @@
+#!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 the GraphicsFuzz project.
+
+# Short description: A fragment shader with vec2 in modulus fraction function
+
+# The test passes because the shader always writes the color red.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {
+#     vec2 uv = vec2(1.0, 1.0);
+#     uv.x = (modf(1.0, uv.y));
+#     // uv.y == 1.0, uv.x == 0.0
+#     if (uv.y > 0.0 && uv.x < 1.0)
+#     {
+#         _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#     }
+#     else
+#     {
+#         _GLF_color = vec4(1.0);
+#     }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 38
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %34
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %9 "uv"
+               OpName %34 "_GLF_color"
+               OpDecorate %34 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 2
+          %8 = OpTypePointer Function %7
+         %10 = OpConstant %6 1
+         %11 = OpConstantComposite %7 %10 %10
+         %12 = OpTypeInt 32 0
+         %13 = OpConstant %12 1
+         %14 = OpTypePointer Function %6
+         %17 = OpConstant %12 0
+         %19 = OpTypeBool
+         %22 = OpConstant %6 0
+         %32 = OpTypeVector %6 4
+         %33 = OpTypePointer Output %32
+         %34 = OpVariable %33 Output
+         %35 = OpConstantComposite %32 %10 %22 %22 %10
+         %37 = OpConstantComposite %32 %10 %10 %10 %10
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+          %9 = OpVariable %8 Function
+               OpStore %9 %11
+         %15 = OpAccessChain %14 %9 %13
+         %16 = OpExtInst %6 %1 Modf %10 %15
+         %18 = OpAccessChain %14 %9 %17
+               OpStore %18 %16
+         %20 = OpAccessChain %14 %9 %13
+         %21 = OpLoad %6 %20
+         %23 = OpFOrdGreaterThan %19 %21 %22
+               OpSelectionMerge %25 None
+               OpBranchConditional %23 %24 %25
+         %24 = OpLabel
+         %26 = OpAccessChain %14 %9 %17
+         %27 = OpLoad %6 %26
+         %28 = OpFOrdLessThan %19 %27 %10
+               OpBranch %25
+         %25 = OpLabel
+         %29 = OpPhi %19 %23 %5 %28 %24
+               OpSelectionMerge %31 None
+               OpBranchConditional %29 %30 %36
+         %30 = OpLabel
+               OpStore %34 %35
+               OpBranch %31
+         %36 = OpLabel
+               OpStore %34 %37
+               OpBranch %31
+         %31 = 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
index ef40d60..09e0ae0 100644 (file)
@@ -756663,11 +756663,13 @@ dEQP-VK.graphicsfuzz.discard-in-loop
 dEQP-VK.graphicsfuzz.discard-in-loop-in-function
 dEQP-VK.graphicsfuzz.discards-in-control-flow
 dEQP-VK.graphicsfuzz.do-while-false-loops
+dEQP-VK.graphicsfuzz.do-while-if-return
 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.flag-always-false-if
 dEQP-VK.graphicsfuzz.for-condition-always-false
 dEQP-VK.graphicsfuzz.for-loop-with-return
 dEQP-VK.graphicsfuzz.for-with-ifs-and-return
@@ -756734,14 +756736,20 @@ dEQP-VK.graphicsfuzz.spv-stable-orbit-Os-access-chain-mutate-pointer
 dEQP-VK.graphicsfuzz.spv-stable-pillars-O-op-select-to-op-phi
 dEQP-VK.graphicsfuzz.spv-stable-quicksort-mat-func-param
 dEQP-VK.graphicsfuzz.spv-stable-rects-Os-mutate-var-push-through-var
+dEQP-VK.graphicsfuzz.stable-binarysearch-tree-false-if-discard-loop
+dEQP-VK.graphicsfuzz.stable-binarysearch-tree-nested-if-and-conditional
 dEQP-VK.graphicsfuzz.stable-binarysearch-tree-with-loop-read-write-global
+dEQP-VK.graphicsfuzz.stable-collatz-push-constant-with-nested-min-max
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-injected-conditional-true
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-true-conditional-simple-loop
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-vec3-values-from-matrix
+dEQP-VK.graphicsfuzz.stable-mergesort-reversed-for-loop
 dEQP-VK.graphicsfuzz.stable-quicksort-for-loop-with-injection
 dEQP-VK.graphicsfuzz.stable-quicksort-if-false-else-return
 dEQP-VK.graphicsfuzz.stable-quicksort-max-value-as-index
 dEQP-VK.graphicsfuzz.stable-rects-vec4-clamp-conditional-min-mix
+dEQP-VK.graphicsfuzz.stable-triangle-array-nested-loop
+dEQP-VK.graphicsfuzz.stable-triangle-nested-for-loop-and-true-if
 dEQP-VK.graphicsfuzz.struct-and-unreachable-infinite-loop
 dEQP-VK.graphicsfuzz.struct-array-data-as-loop-iterator
 dEQP-VK.graphicsfuzz.struct-controlled-loop
@@ -756776,6 +756784,7 @@ dEQP-VK.graphicsfuzz.unreachable-loops-in-switch
 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.vec2-modf
 dEQP-VK.graphicsfuzz.vector-values-multiplied-by-fragcoord
 dEQP-VK.graphicsfuzz.vectors-and-discard-in-function
 dEQP-VK.graphicsfuzz.while-function-always-false