Skip to content

[SPIRV][HLSL] Invalid codegen for trivial switch fallthrough #156534

@llvm-beanz

Description

@llvm-beanz

Given this HLSL:

RWBuffer<int> value;
RWStructuredBuffer<uint> Out : register(u1);

[numthreads(4, 1, 1)]
void main(uint3 threadID : SV_DispatchThreadID) {
  bool B1 = false;
  switch (value[threadID.x]) {
    case 0:
    case 2: // threads 0, 1, 2; result for each false
      Out[threadID.x] = WaveActiveAnyTrue(B1);
      B1 = true;
      break;
    default: // thread 3; result is false
      Out[threadID.x] = WaveActiveAnyTrue(B1);
      break;
  }
  // result for all threads is true because B1 is true for threads 0-2
  Out[threadID.x + 4] = WaveActiveAnyTrue(B1);
}

Compiler Explorer

LLVM generates invalid SPIRV. The following error is produced by SPIRV-val:

error: line 75: OpSelectionMerge must immediately precede either an OpBranchConditional or OpSwitch instruction. OpSelectionMerge must be the second-to-last instruction in its block.
  OpSelectionMerge %50 None

Excerpt of the generated SPIRV:

        OpSelectionMerge %67 None
        OpSelectionMerge %68 None
        OpSwitch %49 %69 0 %68 2 %68

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions