<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">