Skip to content

spirv-val fails to validate for OpSwitch case-to-case branching #2686

@HansKristian-Work

Description

@HansKristian-Work
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 7
; Bound: 35
; Schema: 0
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %main "main" %vIndex %vCond %FragColor
               OpExecutionMode %main OriginUpperLeft
               OpSource GLSL 450
               OpName %main "main"
               OpName %vIndex "vIndex"
               OpName %vCond "vCond"
               OpName %a "a"
               OpName %b "b"
               OpName %c "c"
               OpName %FragColor "FragColor"
               OpDecorate %vIndex Flat
               OpDecorate %vIndex Location 0
               OpDecorate %vCond Flat
               OpDecorate %vCond Location 1
               OpDecorate %FragColor Location 0
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
        %int = OpTypeInt 32 1
%_ptr_Input_int = OpTypePointer Input %int
     %vIndex = OpVariable %_ptr_Input_int Input
      %vCond = OpVariable %_ptr_Input_int Input
      %int_0 = OpConstant %int 0
       %bool = OpTypeBool
%_ptr_Function_int = OpTypePointer Function %int
     %int_10 = OpConstant %int 10
    %int_100 = OpConstant %int 100
     %int_20 = OpConstant %int 20
     %int_30 = OpConstant %int 30
      %float = OpTypeFloat 32
    %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
  %FragColor = OpVariable %_ptr_Output_v4float Output
       %main = OpFunction %void None %3
          %5 = OpLabel
          %a = OpVariable %_ptr_Function_int Function
          %b = OpVariable %_ptr_Function_int Function
          %c = OpVariable %_ptr_Function_int Function
          %9 = OpLoad %int %vIndex
               OpSelectionMerge %merge_block None
               OpSwitch %9 %12 1 %12 0 %11 2 %12
         %10 = OpLabel
         %14 = OpLoad %int %vCond
         %17 = OpINotEqual %bool %14 %int_0
               OpBranchConditional %17 %12 %merge_block
         %11 = OpLabel
               OpStore %b %int_20
               OpStore %c %int_30
               OpBranch %merge_block
         %12 = OpLabel
		 	   OpBranch %11
         %merge_block = OpLabel
               OpReturn
               OpFunctionEnd

This shader passes validation even if we have a construct like:

               OpSwitch %9 %12 1 %12 0 %11 2 %12
         %12 = OpLabel
		 	   OpBranch %11

The rule which seems to be violated here is:

if Target T1 branches to Target T2, or if Target T1 branches to the Default and the Default branches to Target T2, then
T1 must immediately precede T2 in the list of the OpSwitch Target operands

Is it legal to emit case label targets out of order like this?

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions