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

    <tr>
        <th>Summary</th>
        <td>
            [HLSL] Add checks to the SPIRVInstructionSelector's `selectExtInst` functions for SPIR-V extended instruction set availability
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

    <tr>
      <th>Reporter</th>
      <td>
          Icohedron
      </td>
    </tr>
</table>

<pre>
    Certain SPIR-V instructions are supported only with the [OpenCL extended instruction set](https://registry.khronos.org/SPIR-V/specs/unified1/OpenCL.ExtendedInstructionSet.100.html) but not the [GLSL extended instruction set](https://registry.khronos.org/SPIR-V/specs/unified1/GLSL.std.450.html), and vice-versa.

For example, the `reflect` instruction is supported in GLSL, but not OpenCL. Without adding a check that the extended instruction set is usable by the current SPIR-V target, the compiler will simply crash when attempting to select `G_INTRINSIC intrinsic(@llvm.spv.reflect)` in an OpenCL SPIR-V target.

#122992 implements the check as follows in `llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp`:
```c++
bool SPIRVInstructionSelector::selectExtInst(Register ResVReg,
 const SPIRVType *ResType,
 MachineInstr &I,
 GL::GLSLExtInst GLInst) const {
  if (!STI.canUseExtInstSet(
 SPIRV::InstructionSet::InstructionSet::GLSL_std_450)) {
    std::string DiagMsg;
    raw_string_ostream OS(DiagMsg);
    I.print(OS, true, false, false, false);
    DiagMsg += " is only supported with the GLSL extended instruction set.\n";
    report_fatal_error(DiagMsg.c_str(), false);
 }
  return selectExtInst(ResVReg, ResType, I,
 {{SPIRV::InstructionSet::GLSL_std_450, GLInst}});
}
```

There should be similar checks made for the other overloaded versions of the `selectExtInst` to keep things consistent.
```c++
  bool selectExtInst(Register ResVReg, const SPIRVType *ResType,
                     MachineInstr &I, CL::OpenCLExtInst CLInst) const;
  bool selectExtInst(Register ResVReg, const SPIRVType *ResType,
                     MachineInstr &I, CL::OpenCLExtInst CLInst,
                     GL::GLSLExtInst GLInst) const;
  bool selectExtInst(Register ResVReg, const SPIRVType *ResType,
 MachineInstr &I, const ExtInstList &ExtInsts) const;
```

A non-exhaustive list of OpenCL-only instructions:
- `vstoren`
- `vloadn`
- `shuffle`

(Note: AFAIK, these OpenCL-only instructions do not have corresponding HLSL intrinsics. I am not sure if there are any OpenCL-only instructions that have a direct [HLSL intrinsic](https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-intrinsic-functions) equivalent.)

A non-exhaustive list of GLSL-only instructions:
- `Reflect`
- `Refract`
- `FaceForward`

A full list of exclusive instructions may be constructed by comparing the [OpenCL extended instruction set](https://registry.khronos.org/SPIR-V/specs/unified1/OpenCL.ExtendedInstructionSet.100.html) and [GLSL extended instruction set](https://registry.khronos.org/SPIR-V/specs/unified1/GLSL.std.450.html) specifications.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzMV01z4jgT_jXi0oXLiGDsAwcCQ17qzcxsJdnsMSXsNtaOkLySDOHfb7VsE5gJM3PYrZ2Uq2JEqz-e7qe7Ec7JrUacscktmywHovGVsbN1biosrNGDjSmOswVaL6SGx9_WD8NnkNp52-ReGu1AWATX1LWxHgswWh3hIH0FvkJgk9vPNerFPeCrR11gcX4XHHo2WTKeVt7Xjo3njK8YX1ncSuftMfpSWaONi4zdMr5qjTO-cjXmjvFVo2UpsRgxvmqtRB86K-s3I4_oo1EcR5XfKcYz2DQetPG9e3f3j_-6c2Qjcr6IbiYnPxhfgNAF7GWOwz1aJyIWz1k8XxkL-Cp2tUKSCW4mscVSYe5ZEl_4KN0Z9FIDWaJbfZAdLPCH9JVpPIiikHoLAvIK8y_gK9ECcQ0AMtA4sVEIm2OQzBtrUfu-ErywW_S9o7nZ1VKhhYNUCpzc1eoIuRWugkOFGoT3uKs9ueANOKSQKLq7l_Wnp4f1p8f1AqT2Vmonc8ZTdhMrtd9Frt5HPQI8a0EAobvwLn3pYGR8POI8yziQF7hD7V3rY4hcOCiNUubgSBVLgh3GV0puGF89dVGFrD73_y-KinwxNsrrmiUxFUc8p5fw5Izf0hPPN8YouHaZbo3nLQofXj1JMJ4-hPpCCw_onh9wy_iCxXPIjXYt6s9PxxqB8fkDOnrtBD6KvJIagx1gPFl353f3rR0qjc4K3N23xrJOLZuSswCyBEKdjx6f1lEu9O8OuyuPBEdKQi0kQeUly66fkekX54uXm0kcSj87WQRwvuiAoLxvYSnF9qPbsnEvYMXhpf3uxThvUezg8yPjaS_IszfZdVRbqclVElmAt01gUSmUe_fl7G6nDyhz4yUwzqn6Qz9749ips323b0RsstCM87MgkBS8lMIL9YLWGvsWQZRTfAH47B3X2HQZlFj0jdXwbb30ZQJvBQF99gnn6e0PcnaZn0VfHtMlPb0frRunGm9Z9lQhdf_KNKqADRLlpRK2JZmDnSgQSmMDYsZXaMHs0SojCDTqemGCmLJvc5fBJTG1iS-INfhK6q0L5Urs0C3NvyUcQKDcT5Dqx4x67-89lsGio1jbjnqSLS5J1tfCL-ffVV0_0Tn--aDeDaC91Wm-l9SxeNJ9dF8581WFzkEbPcTXSjTOyz2Couum7GbHMPD7fJ9pe_mQqnHvvLGoW13tCZXu-YGrmrJUeDLHePrJeGTjOcxX8_X_u8no8Ko9KEwY1ZXY0wC1Fl1tdBjT_6Mec5qHLoI1iF0Qdo1F6tY-8I82MKGP102EOR8MCCikDVN3cnup_r1dR6GwOtrJ3BpnSh_lhmYk6mFDG85B6sIcurcxZ3zV6h4XlXKKPr4Ot1bUlczdkI6GJ2PDstEd3DwD_KuRe6ECq3n2g7xRNX43aw-nVensxIqLk5XIcWXsQdjirFLKRqmTHXzNVePI8gWUO3GkRhcKjg6xoM2IFh8RxtcvuvXSqvkfbrtAcrKUuQgoRoNiNi6ycSYGOBtNx9NJPBqnyaCaYboZ8bTENE-SJE3LNCkxjvlmUkzTmyxLBnLGYz6JR3zEx6OEJ5EY5fEkw3SKXIynccZuYtwJqaKwORq7HUjnGpyN-Di9mQ6U2KBy4dcO5xoPEL6lWT1ZDuyMLg03zdbR6imdd29qvPQq_Ewi3rDJEuZF0Q86b0Lir256fOreHW8nGoQp2e2xV5dxsRdSiY1U0h8HjVWzy1xtpa-aTUfSfp-leGpr_gyr8yoES_nq0NjP-N8BAAD__2Y4iR4">