#!amber # Copyright 2022 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 coverage-gap found by the GraphicsFuzz project. # Short description: A fragment shader that covers specific LLVM code paths # The test passes because the shader always writes red. # Optimized using spirv-opt with the following arguments: # '--copy-propagate-arrays' # '--eliminate-local-multi-store' # '--if-conversion' # '--eliminate-local-single-block' # '--eliminate-dead-inserts' # '--redundancy-elimination' # '--eliminate-local-single-store' # '--eliminate-dead-code-aggressive' # '--eliminate-dead-code-aggressive' # '--redundancy-elimination' # '--scalar-replacement=100' # '--eliminate-local-multi-store' # '--inline-entry-points-exhaustive' # '--eliminate-dead-branches' # '--merge-return' # '--eliminate-dead-branches' # '--merge-blocks' # '--ccp' # '--copy-propagate-arrays' # '--combine-access-chains' # '--if-conversion' # '--private-to-local' # '--reduce-load-size' # '--scalar-replacement=100' # spirv-opt commit hash: a0370efd589be33d5d9a85cfde2f85841b3755af SHADER vertex variant_vertex_shader PASSTHROUGH # variant_fragment_shader is derived from the following GLSL: # #version 320 es # # #define _int_1 _GLF_uniform_int_values[0] # #define _int_0 _GLF_uniform_int_values[1] # # precision highp float; # precision highp int; # # // Contents of _GLF_uniform_int_values: [1, 0] # layout(set = 0, binding = 0) uniform buf0 # { # int _GLF_uniform_int_values[2]; # }; # # const int _GLF_global_loop_bound = 10; # int _GLF_global_loop_count = 0; # # layout(location = 0) out vec4 _GLF_color; # # int arr0[10] = int[10](1, 1, 1, 1, 1, 1, 1, 1, 1, 1); # # int func() # { # int a = _int_1; # int b = _int_0; # int arr1[10] = int[10](_int_1, _int_1, _int_1, _int_1, _int_1, _int_1, _int_1, _int_1, _int_1, _int_1); # # // Iterates ten times. # while(b >= _int_0 && _GLF_global_loop_count < _GLF_global_loop_bound) # { # _GLF_global_loop_count++; # # // Reads zero as an index and then decrements b to -1. Reads value one, so a stays at one. # a = arr1[b--]; # # // arr0[1] = arr0[0]. No effect. # arr0[_int_1] = arr0[a]; # # // Always true. # if(a > _int_0) # { # // Increments b to zero and indexes with that. Writes one to arr1[0] but that value already existed. # arr1[++b] = a; # } # } # # // Returns zero. # return b; # } # # void main() # { # // Always true. # if(func() == _int_0) # { # _GLF_color = vec4(_int_1, _int_0, _int_0, _int_1); # } # else # { # _GLF_color = vec4(_int_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: 157 ; Schema: 0 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %4 "main" %104 OpExecutionMode %4 OriginUpperLeft OpSource ESSL 320 OpName %4 "main" OpName %8 "func(" OpName %11 "_GLF_global_loop_count" OpName %17 "arr0" OpName %24 "buf0" OpMemberName %24 0 "_GLF_uniform_int_values" OpName %26 "" OpName %34 "arr1" OpName %104 "_GLF_color" OpDecorate %23 ArrayStride 16 OpMemberDecorate %24 0 Offset 0 OpDecorate %24 Block OpDecorate %26 DescriptorSet 0 OpDecorate %26 Binding 0 OpDecorate %104 Location 0 %2 = OpTypeVoid %3 = OpTypeFunction %2 %6 = OpTypeInt 32 1 %7 = OpTypeFunction %6 %10 = OpTypePointer Private %6 %11 = OpVariable %10 Private %12 = OpConstant %6 0 %13 = OpTypeInt 32 0 %14 = OpConstant %13 10 %15 = OpTypeArray %6 %14 %16 = OpTypePointer Private %15 %17 = OpVariable %16 Private %18 = OpConstant %6 1 %19 = OpConstantComposite %15 %18 %18 %18 %18 %18 %18 %18 %18 %18 %18 %20 = OpTypePointer Function %6 %22 = OpConstant %13 2 %23 = OpTypeArray %6 %22 %24 = OpTypeStruct %23 %25 = OpTypePointer Uniform %24 %26 = OpVariable %25 Uniform %27 = OpTypePointer Uniform %6 %33 = OpTypePointer Function %15 %64 = OpTypeBool %67 = OpConstant %6 10 %101 = OpTypeFloat 32 %102 = OpTypeVector %101 4 %103 = OpTypePointer Output %102 %104 = OpVariable %103 Output %4 = OpFunction %2 None %3 %5 = OpLabel %125 = OpVariable %33 Function %126 = OpVariable %20 Function OpStore %11 %12 OpStore %17 %19 %128 = OpAccessChain %27 %26 %12 %12 %129 = OpLoad %6 %128 %130 = OpAccessChain %27 %26 %12 %18 %131 = OpLoad %6 %130 %132 = OpCompositeConstruct %15 %129 %129 %129 %129 %129 %129 %129 %129 %129 %129 OpStore %125 %132 OpBranch %133 %133 = OpLabel %134 = OpPhi %6 %131 %5 %154 %155 %136 = OpSGreaterThanEqual %64 %134 %131 %137 = OpLoad %6 %11 %138 = OpSLessThan %64 %137 %67 %139 = OpLogicalAnd %64 %136 %138 OpLoopMerge %156 %155 None OpBranchConditional %139 %140 %156 %140 = OpLabel %141 = OpLoad %6 %11 %142 = OpIAdd %6 %141 %18 OpStore %11 %142 %143 = OpISub %6 %134 %18 %144 = OpAccessChain %20 %125 %134 %145 = OpLoad %6 %144 %146 = OpAccessChain %10 %17 %145 %147 = OpLoad %6 %146 %148 = OpAccessChain %10 %17 %129 OpStore %148 %147 %149 = OpSGreaterThan %64 %145 %131 OpSelectionMerge %153 None OpBranchConditional %149 %150 %153 %150 = OpLabel %151 = OpIAdd %6 %143 %18 %152 = OpAccessChain %20 %125 %151 OpStore %152 %145 OpBranch %153 %153 = OpLabel %154 = OpPhi %6 %143 %140 %151 %150 OpBranch %155 %155 = OpLabel OpBranch %133 %156 = OpLabel OpStore %126 %134 %95 = OpLoad %6 %126 %96 = OpAccessChain %27 %26 %12 %18 %97 = OpLoad %6 %96 %98 = OpIEqual %64 %95 %97 OpSelectionMerge %100 None OpBranchConditional %98 %99 %118 %99 = OpLabel %105 = OpAccessChain %27 %26 %12 %12 %106 = OpLoad %6 %105 %107 = OpConvertSToF %101 %106 %110 = OpConvertSToF %101 %97 %117 = OpCompositeConstruct %102 %107 %110 %110 %107 OpStore %104 %117 OpBranch %100 %118 = OpLabel %121 = OpConvertSToF %101 %97 %122 = OpCompositeConstruct %102 %121 %121 %121 %121 OpStore %104 %122 OpBranch %100 %100 = OpLabel OpReturn OpFunctionEnd %8 = OpFunction %6 None %7 %9 = OpLabel %34 = OpVariable %33 Function %28 = OpAccessChain %27 %26 %12 %12 %29 = OpLoad %6 %28 %31 = OpAccessChain %27 %26 %12 %18 %32 = OpLoad %6 %31 %55 = OpCompositeConstruct %15 %29 %29 %29 %29 %29 %29 %29 %29 %29 %29 OpStore %34 %55 OpBranch %56 %56 = OpLabel %123 = OpPhi %6 %32 %9 %124 %59 OpLoopMerge %58 %59 None OpBranch %60 %60 = OpLabel %65 = OpSGreaterThanEqual %64 %123 %32 %66 = OpLoad %6 %11 %68 = OpSLessThan %64 %66 %67 %69 = OpLogicalAnd %64 %65 %68 OpBranchConditional %69 %57 %58 %57 = OpLabel %70 = OpLoad %6 %11 %71 = OpIAdd %6 %70 %18 OpStore %11 %71 %73 = OpISub %6 %123 %18 %74 = OpAccessChain %20 %34 %123 %75 = OpLoad %6 %74 %79 = OpAccessChain %10 %17 %75 %80 = OpLoad %6 %79 %81 = OpAccessChain %10 %17 %29 OpStore %81 %80 %85 = OpSGreaterThan %64 %75 %32 OpSelectionMerge %87 None OpBranchConditional %85 %86 %87 %86 = OpLabel %89 = OpIAdd %6 %73 %18 %91 = OpAccessChain %20 %34 %89 OpStore %91 %75 OpBranch %87 %87 = OpLabel %124 = OpPhi %6 %73 %57 %89 %86 OpBranch %59 %59 = OpLabel OpBranch %56 %58 = OpLabel OpReturnValue %123 OpFunctionEnd END # uniforms for variant # _GLF_uniform_int_values BUFFER variant__GLF_uniform_int_values DATA_TYPE int32[] STD140 DATA 1 0 END BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM PIPELINE graphics variant_pipeline ATTACH variant_vertex_shader ATTACH variant_fragment_shader FRAMEBUFFER_SIZE 32 32 BIND BUFFER variant_framebuffer AS color LOCATION 0 BIND BUFFER variant__GLF_uniform_int_values 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 32 32 EXPECT variant_framebuffer IDX 0 0 SIZE 32 32 EQ_RGBA 255 0 0 255