<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/112056>112056</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [SPIRV] Don't lower switch statements to OpSwitch
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            HLSL,
            backend:SPIR-V
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          llvm-beanz
      </td>
    </tr>
</table>

<pre>
    **Description**
`OpSwitch` even as defined with [SPV_KHR_maximal_reconvergence](https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/KHR/SPV_KHR_maximal_reconvergence.asciidoc#divergence), doesn't require converging on switch cases that have fall through.

The only way to get SPIR-V to implement switch statements that converge correctly is with `OpBranch` instead.

**Steps to Reproduce**

Given the following HLSL:
```hlsl
RWBuffer<int> value;

[numthreads(4, 1, 1)]
void main(uint3 threadID : SV_DispatchThreadID) {
  uint sum = 0;
  switch (value[threadID.x]) {
    case 0:
      sum += WaveActiveSum(1);
 default:
      sum += WaveActiveSum(10);
      break;
  }
 value[threadID.x] = sum;
}
```
[CE](https://godbolt.org/z/EocEd43EW)

If given the input `[ 0, 0, 1, 2]`, the computed output should be `[ 42, 42, 40, 40 ]`.

**Actual Behavior**

Even with the KHR maximal reconvergence extension the `OpSwitch` is not guaranteed to converge the tangles between case 0 and the default case.

However, if instead these were generated as a chain of `OpBranch` statements, the control flow would converge at each new `OpBranch`, which would result in the correct tangle grouping.

The HLSL example above does not compile in Clang today due to missing features, a Clang example that is closer to compiling is https://godbolt.org/z/nbhbd8fdK.

Any switch with fallthrough cases that have behavior dependent on participating lanes converging will be undefined behavior if the SPIRV `OpSwitch` instruction is used, so we should just not generate it ever for HLSL.

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyMVstu27wSfhp6M0ggU7bjLLyQ4_hPkQKnSIp0GVDiSGJLkTq8WHGf_mAoyekNPX8QyBA11--bC4X3qjGIO7bes_VhIWJordtpfequShTm-6K08rxjvGC8OKCvnOqDsmY8YFnBNtl_-udBhaplmwzwhAaEB4m1MihhUKEFtt4_f3p5fXx4eu3Em-qEfnVYWXNC16CpkK0PjG_bEHrP8oLxI-PHRoU2lteV7Rg_PrbOGuv_cTb2jB-fP314erl6wkb54M6MH0ttS8aPnVCG8SO-BTReWeNJ9eEpafzF_bXwlVLSVoznUl2C4reM34G06A3jNwEc_jcqhzBpKtOANeBT6lAJjx5CKwK04oRQC60htM7Gpr0mmLLic4tgjT7DIM4QLDQYgDK5eqE31fUaOzRhtuiDCOlgMjsHDJV1Dqugz6D8hC9xsHfCjBwo4wMKObkdmXoO2Hvy84S9szJSfjODWfGPItpCi1Bbre1AuT18fP5IbCSKx_9We82y4unLPtY1OpbfKRNYfg8noSOyfD95XO9N7ELrUEjP-HZFOC6nxy2RnRUnqySMfG2jMiGHUf7DAVhewPPL60H5XoSq_TydM34L7IZcAJAG-NgByw-QjY5hBo7x7RjPej_bvH5LJfZuABJhpFpM7zDa43sy-UWcsKiCOuFz7BjfprhHLxJrEXX4t4rZu2b6Kx2Kb_MBuyEo4I_RptR87CZUk-SFiBHku_s_No6VpdXh2rqG8eN3xo_3trqXq_z-C8WSGPpQQ3OhXJk-Bqohtt5DRjRlF8I4edikdxKtbNfHgBJsDKTkWxu1hBJn9RUn0emZjU8YbfxUjkUVotCwx1aclHU_1uI9xZXKmjw-PjzB1LTwU9PCpcuT3C9jSHkwNkAThRMmIEoq_UsHkUIQptHoocQwIJqpHkAYmT5PNKfjKfIHO-AJHSWl6rnJSNgjDOgQGjToBMEjPAioWqEM2PrX9nxv7HdYTXBWQ63tAEOC9BKrCICiasHg8Ish0h5aVbWTikNPESsz2UxTYsoTGhqdyjQ_zCJqcMA3QYMHRGlPmIZdAo6IVppqA-60MA0EK8UZZEQCslPe04ioUYToMOUhJsHZYJpZykOlrUc3wk82SU95-H81a8q2lNtaPk4BF-Y893eqDZqv03j9bfaWU1WBxB6NpJlqDfTCBVWpXgQKQQuD_sdRPiitqZCjmVfXxYyqE6Jp6_xWaMYHFytaiZRW9CgJDW9hwLk9vkYfxnKcCgRUoEXpoLYu0UBJLuQul7f5rVjgbnnDt5vtJrtZLtpdnUlcSSwzvKmwypY1Yp7V8rbMNrKspVyoHc_4apktl5znq3x5Xa7WUmYoatxscbVZsVWGnVD6mtY6gbxQ3kfcLZc8W28WWpSofboBcJ7GPqcGZpyXovqGRrK8GBcVfVgfFvP9IDaerTKtfPDvpoMKOl0nEl40yQ52XKDaDuj-tN4szJAuotO7v1wEyMv0c9U7-xWrwPgxZUPLfkrotOP_CwAA__8-e9sE">