Skip to content

MESA: SPIR-V offset 0: SPIR-V parsing FAILED: Invalid back or cross-edge in the CFG #7

Open
@Jack-Clark

Description

@Jack-Clark

Running the following command using branch 22.0.1 and master (commit cde1be0b) of Mesa:

amber -t spv1.3 -t 1.1 reduced-cross-edge-bug.amber

gives:

[ERROR] validation layer (../src/vulkan/runtime/vk_nir.c:59):
SPIR-V offset 0: SPIR-V parsing FAILED:
    In file ../src/compiler/spirv/vtn_cfg.c:662
    Invalid back or cross-edge in the CFG
    0 bytes into the SPIR-V binary
SPIR-V parsing FAILED:
    In file ../src/compiler/spirv/vtn_cfg.c:662
    Invalid back or cross-edge in the CFG
    0 bytes into the SPIR-V binary
[ERROR] validation layer (../src/vulkan/runtime/vk_shader_module.c:128):
spirv_to_nir failed (VK_ERROR_UNKNOWN)
[ERROR] validation layer (../src/intel/vulkan/anv_pipeline.c:1987):
VK_ERROR_UNKNOWN
reduced-cross-edge-bug.amber: Vulkan::Calling vkCreateComputePipelines Fail

Summary of Failures: 
reduced-cross-edge-bug.amber

Summary: 0 pass, 1 fail
[ERROR] validation layer (Validation):
Validation Error: [ VUID-vkDestroyDevice-device-00378 ] Object 0: handle = 0x5613ab15de10, type = VK_OBJECT_TYPE_DEVICE; Object 1: handle = 0xe7f79a0000000005, type = VK_OBJECT_TYPE_PIPELINE_LAYOUT; | MessageID = 0x71500fba | OBJ ERROR : For VkDevice 0x5613ab15de10[], VkPipelineLayout 0xe7f79a0000000005[] has not been destroyed. The Vulkan spec states: All child objects created on device must have been destroyed prior to destroying device (https://vulkan.lunarg.com/doc/view/1.3.204.1/linux/1.3-extensions/vkspec.html#VUID-vkDestroyDevice-device-00378)

This is potentially related to this bug. A patch was eventually merged for that bug so this is still valid. I think the discussion of the bug highlights the value in the formal modelling of the control flow rules.

I've compiled and validated the reduced asm from the following amber code:

#!amber

SHADER compute compute_shader SPIRV-ASM

; Follow the path:
; 8 -> <9> -> <12> -> 10
;
; 2 CFG nodes have OpBranchConditional or OpSwitch as their terminators (denoted <n>): 9 and 12.
;
; To follow this path, we need to make these decisions each time we reach 9 or 12.
; This path was generated with the seed 2641702989343433340 and has length 4.
;
; We equip the shader with 2+1 storage buffers:
; - An input storage buffer with the directions for each node 9 or 12
; - An output storage buffer that records the blocks that are executed

; SPIR-V
; Version: 1.3
; Generator: Khronos Glslang Reference Front End; 8
; Bound: 15
; Schema: 0

               OpCapability Shader
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %7 "main"
               OpExecutionMode %7 LocalSize 1 1 1

          %1 = OpTypeVoid
          %2 = OpTypeFunction %1
          %3 = OpTypeBool
       %true = OpConstantTrue %3
       
          %7 = OpFunction %1 None %2

          %8 = OpLabel ; validCFG/StructurallyReachableBlock$6
               OpBranch %9

          %9 = OpLabel ; validCFG/LoopHeader$0
               OpLoopMerge %10 %11 None
               OpBranchConditional %true %12 %15

         %12 = OpLabel ; validCFG/StructurallyReachableBlock$4
               OpBranchConditional %true %15 %10

         %10 = OpLabel ; validCFG/StructurallyReachableBlock$3
               OpReturn
               
         %15 = OpLabel ; validCFG/StructurallyReachableBlock$1
               OpBranch %11

         %11 = OpLabel ; validCFG/StructurallyReachableBlock$0
               OpBranch %17

         %17 = OpLabel ; validCFG/StructurallyReachableBlock$5
               OpBranch %9
               
               OpFunctionEnd

 END

 PIPELINE compute pipeline
   ATTACH compute_shader

 END

 RUN pipeline 1 1 1

I've removed many blocks from the original CFG, so it would be good if someone (@afd @vili-1 @johnwickerson) could double check this before I submit it as a bug.

There is something in the original CFG file that caught my eye, but doesn't affect the bug, however could indicate an error in some part of our code. There is a block B0 which is labelled as wholly unreachable (i.e. uses Block$X naming), but looks structurally reachable to me because of the path SRB6->LH0->B0. Am I missing something? I've drawn out the CFG below. Note SRBX = StructurallyReachableBlock$X and BX = Block$X.

Cross-edge-bug-cfg

Here is the skeleton asm:

; SPIR-V
; Version: 1.3
; Generator: Khronos Glslang Reference Front End; 8
; Bound: 15
; Schema: 0

               OpCapability Shader
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %7 "main"
               OpExecutionMode %7 LocalSize 1 1 1
               
               ; Below, we declare various types and variables for storage buffers.
               ; These decorations tell SPIR-V that the types and variables relate to storage buffers


          %1 = OpTypeVoid
          %2 = OpTypeFunction %1
          %3 = OpTypeBool
          %4 = OpTypeInt 32 0
       %true = OpConstantTrue %3
          %6 = OpConstant %4 0


          %7 = OpFunction %1 None %2

          %8 = OpLabel ; validCFG/StructurallyReachableBlock$6
               OpBranch %9


          %9 = OpLabel ; validCFG/LoopHeader$0
               OpLoopMerge %10 %11 None
               OpBranchConditional %true %12 %13


         %12 = OpLabel ; validCFG/StructurallyReachableBlock$4
               OpBranchConditional %true %14 %10


         %13 = OpLabel ; validCFG/Block$0
               OpBranch %14


         %10 = OpLabel ; validCFG/StructurallyReachableBlock$3
               OpReturn


         %14 = OpLabel ; validCFG/SelectionHeader$0
               OpSelectionMerge %15 None
               OpSwitch %6 %15 1 %16


         %16 = OpLabel ; validCFG/StructurallyReachableBlock$2
               OpBranchConditional %true %11 %15


         %15 = OpLabel ; validCFG/StructurallyReachableBlock$1
               OpBranch %11


         %11 = OpLabel ; validCFG/StructurallyReachableBlock$0
               OpBranch %17


         %17 = OpLabel ; validCFG/StructurallyReachableBlock$5
               OpBranch %9

               OpFunctionEnd

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions