Skip to content

Violation of the requirement to have exactly one Parent ID operand for each parent block of the current block in the CFG #2702

@VyacheslavLevytskyy

Description

@VyacheslavLevytskyy

It's a requirement of the SPIR-V specification (https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpPhi) that "There must be exactly one Parent i for each parent block of the current block in the CFG.". However, for the snippet %retval.0.i = phi i32 [ 0, %sw.default.i ], [ 1, %entry ], [ 1, %entry ] from the following reproducer

define spir_kernel void @foo(i8 %arg) {
entry:
  switch i8 %arg, label %sw.default.i [
    i8 -127, label %exit
    i8 -111, label %exit
  ]

sw.default.i:                                     ; preds = %entry
  br label %exit

exit: ; preds = %sw.default.i, %entry, %entry
  %retval.0.i = phi i32 [ 0, %sw.default.i ], [ 1, %entry ], [ 1, %entry ]
  ret void
}

Translator would generate invalid SPIR-V output containing the following fragment:

%retval_0_i = OpPhi %uint %uint_0 %sw_default_i %uint_1 %entry %uint_1 %entry

When validating Translator's output we get the following error:

$ llvm-as phi-multiple-preds.ll -o - | /localdisk2/vlevytsk/sycl/llvm/build/bin/llvm-spirv.bak -o - | spirv-val
error: line 26: OpPhi's number of incoming blocks (3) does not match block's predecessor count (3).
  %retval_0_i = OpPhi %uint %uint_0 %sw_default_i %uint_1 %entry %uint_1 %entry

SPIR-V Backend generates correctly %retval_0_i = OpPhi %uint %uint_0 %13 %uint_1 %12 where there is just one record per 2 original %entry predecessors, however, this output of SPIR-V Backend gets rejected by Translator's reverse conversion of SPIR-V to LLVM IR as the following:

$ llvm-spirv -r phi-preds.spv
Fails to verify module: PHINode should have one entry for each predecessor of its parent basic block!
  %retval.0.i = phi i32 [ 0, %2 ], [ 1, %0 ]

This error is caused by the 1:1 mapping of PHI operands back to LLVM IR so that llvm's machine verifier gets unhappy when it sees just 1 phi entry for two predecessors.

Original reproducer comes from new SYCL tests from AddressSanitizer/* that produce this specific case of multiple predecessors, showing the failure to meet the requirement of the SPIR-V specification. @MrSidims also has succeeded to create a C reproducer: https://godbolt.org/z/73cj6aE3n

Metadata

Metadata

Assignees

No one assigned

    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