<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/99228>99228</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Implement the `pack_u8` HLSL Function
</td>
</tr>
<tr>
<th>Labels</th>
<td>
metabug,
backend:DirectX,
HLSL,
backend:SPIR-V,
bot:HLSL
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
farzonl
</td>
</tr>
</table>
<pre>
- [ ] Implement `pack_u8` clang builtin,
- [ ] Link `pack_u8` clang builtin with `hlsl_intrinsics.h`
- [ ] Add sema checks for `pack_u8` to `CheckHLSLBuiltinFunctionCall` in `SemaChecking.cpp`
- [ ] Add codegen for `pack_u8` to `EmitHLSLBuiltinExpr` in `CGBuiltin.cpp`
- [ ] Add codegen tests to `clang/test/CodeGenHLSL/builtins/pack_u8.hlsl`
- [ ] Add sema tests to `clang/test/SemaHLSL/BuiltIns/pack_u8-errors.hlsl`
- [ ] Create the `int_dx_pack_u8` intrinsic in `IntrinsicsDirectX.td`
- [ ] Create the `DXILOpMapping` of `int_dx_pack_u8` to `220` in `DXIL.td`
- [ ] Create the `pack_u8.ll` and `pack_u8_errors.ll` tests in `llvm/test/CodeGen/DirectX/`
- [ ] Create the `int_spv_pack_u8` intrinsic in `IntrinsicsSPIRV.td`
- [ ] In SPIRVInstructionSelector.cpp create the `pack_u8` lowering and map it to `int_spv_pack_u8` in `SPIRVInstructionSelector::selectIntrinsic`.
- [ ] Create SPIR-V backend test case in `llvm/test/CodeGen/SPIRV/hlsl-intrinsics/pack_u8.ll`
## DirectX
| DXIL Opcode | DXIL OpName | Shader Model | Shader Stages |
| ----------- | ----------- | ------------ | ------------- |
| 220 | Pack4x8 | 6.6 | () |
## SPIR-V
# [OpBitcast](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpBitcast):
## Description:
Bit pattern-preserving type conversion.
*Result Type* must be an [**OpTypePointer**](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpTypePointer), or a
scalar or vector of [*numerical-type*](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Numerical).
*Operand* must have a type of [**OpTypePointer**](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpTypePointer), or a
scalar or vector of [*numerical-type*](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Numerical). It must be a
different type than *Result Type*.
Before **version 1.5**: If either *Result Type* or *Operand* is a
pointer, the other must be a pointer or an integer scalar.
Starting with **version 1.5**: If either *Result Type* or *Operand* is a
pointer, the other must be a pointer, an integer scalar, or an integer
vector.
If both *Result Type* and the type of *Operand* are pointers, they both
must point into same [storage class](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Storage_Class).
Behavior is undefined if the [storage class](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Storage_Class) of *Result
Type* does not match the one used by the operation that produced the
value of *Operand*.
If *Result Type* has the same number of components as *Operand*, they
must also have the same component width, and results are computed per
component.
If *Result Type* has a different number of components than *Operand*,
the total number of bits in *Result Type* must equal the total number of
bits in *Operand*. Let *L* be the type, either *Result Type* or
*Operand’s* type, that has the larger number of components. Let *S* be
the other type, with the smaller number of components. The number of
components in *L* must be an integer multiple of the number of
components in *S*. The first component (that is, the only or
lowest-numbered component) of *S* maps to the first components of *L*,
and so on, up to the last component of *S* mapping to the last
components of *L*. Within this mapping, any single component of *S*
(mapping to multiple components of *L*) maps its lower-ordered bits to
the lower-numbered components of *L*.
<table>
<colgroup>
<col style="width: 20%" />
<col style="width: 20%" />
<col style="width: 20%" />
<col style="width: 20%" />
<col style="width: 20%" />
</colgroup>
<thead>
<tr>
<th>Word Count</th>
<th>Opcode</th>
<th>Results</th>
<th>Operands</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p>4</p></td>
<td class="tableblock halign-left valign-top"><p>124</p></td>
<td
class="tableblock halign-left valign-top"><p><em><id></em><br />
<em>Result Type</em></p></td>
<td class="tableblock halign-left valign-top"><p><a
href="#ResultId"><em>Result <id></em></a></p></td>
<td
class="tableblock halign-left valign-top"><p><em><id></em><br />
<em>Operand</em></p></td>
</tr>
</tbody>
</table>
## Test Case(s)
### Example 1
```hlsl
//dxc pack_u8_test.hlsl -T lib_6_8 -enable-16bit-types -O0
export uint8_t4_packed fn(int4 p1) {
return pack_u8(p1);
}
```
## HLSL:
## Syntax
```syntax
p32u8 pack_u8(any_int16or32<4> v);
```
## Type Description
| Name | [**Template Type**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3dhlsl/dx-graphics-hlsl-data-types.md)| [**Component Type**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3dhlsl/dx-graphics-hlsl-data-types.md) | Size |
|-------|--------------------------------------------------------------------|----------------------------------------------------------------------|------|
| *ret* | [**scalar**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3dhlsl/dx-graphics-hlsl-scalar.md) | [**uint8_t4_packed**](../WinProg/windows-data-types) | 1 |
| *v* | [**vector**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3dhlsl/dx-graphics-hlsl-vector.md) | [**int**](../WinProg/windows-data-types), [**int16_t**](https://github.com/microsoft/DirectXShaderCompiler/wiki/16-Bit-Scalar-Types), [**uint**](../WinProg/windows-data-types), or [**uint16_t**](https://github.com/microsoft/DirectXShaderCompiler/wiki/16-Bit-Scalar-Types) | 4 |
## Minimum Shader Model
This function is supported in the following shader models.
|Shader Model | Supported|
|-------------|----------|
|[Shader Model 6.6](https://microsoft.github.io/DirectX-Specs/d3d/HLSL_ShaderModel6_6) and higher shader models | yes |
## Shader Stages
## See also
- [**Intrinsic Functions (DirectX HLSL)**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3dhlsl/dx-graphics-hlsl-intrinsic-functions.md)
- **See [Pack Intrinsics](https://microsoft.github.io/DirectX-Specs/d3d/HLSL_SM_6_6_Pack_Unpack_Intrinsics#pack-intrinsics)**
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWltzKjfy_zTyi2qoQWPG8MADYJO_q3ziU8H_JG-UGDWM1hppVtJgk0-_JWmuBttnszmbpGpdLhvd-vLrVqvVghrDDxJgjiZLNLm9opXNlZ7vqf5NSXG1U-w0jzCaLDGa3OL7ohRQgLQYpXFJs-dtNUVpjDNB5QHvKi4sl4isULzoFj1w-fzRfPzCbe4m5MKILZdWc2l4ZkY5SuMBpQVj2EBBcZZD9mzwXuk3hK1yHSs3_H8Pm4dl4LCuZGa5kisqhJvFpZu1gYL6mVweRllZXuKWKQYHkO9yuiu47TG6ey11x2D1Q939GXULxpqaoocGkbXrQ2S9Ugx-AOl4ILKuETOIrGtRRg60d3H6gLDTvqbqpbzvU41Aa6XNReIrDdQCtjk4qlzaLXvd9oBpDVijcN8a9JZryOyvI8s-pnn76_3DY_mFliWXB0dS7S-zsgq7AULiDnS3-GMOPUOOgj9QyXqd21r5MBYgDLSFOBZnpkFkXSuGyPpzsEx5_Da0Nl_vf_r5gib3Evuhe2msrrxfb0BAZpV2foazAcseK6FeQHN58OoWtMSY29o3Lgrm98g7nFCyQMnC-FYrMkrj0SXtHZHoZ7yj2TNI5hHFGTXwCaqeNyJr54RRFxZ6vi9q53S_JEEkwY0lQt_NCjt3wI-l22m41_6RFqG9ySkDjb8oBqLfsbH0AMb11ISi7gd_0j7viHqECIn9-FeaPV-_Tv3ndJT6_4hMEZk1k1utAoBtl8P3sVxym1Fj0eQWkWlubWmcUcgakbWGAzdWn0bPuVZSmZHShxrQyCFqSvA4VpLvObBxA_Yot4VAJOmIk5kjOkAYTKZ56ZwhDGGM4sWSW1xSa0HLqNRgQB-dp9lTCThT8gjacCVHfq7_g8jiJzCVsPjpVAIiC1xUxuIdYCqdfoi4KY-lG_2quLSgQ9f30XfAZobICiuNKYoXJqOCatc6esf3sciLJ6sCNM-oiGzQ4HtI9mPDBJHZEL3HEjSVrEUup0fANCDeyvg_CN9CeG87R0PxgvH9HrRLaDxwNnfe99Y1e8AvYa804IBj7dV4PJrUwCYLfL_HwG0O-pyOg2BoOW68FGUD28qHbeWXt2LietjjKd2JAQfQOMAaZNtYqq3bcCGV-jOkc8Nn0jVe0PajeBGcoIfp_R7vVBD7jUTuoHIsW6ceiEc1NMxNLdzJU0LxwovnBx1nhY2P95OlsUrTA7gE1Jjv4W2bwGC78gwGm3YJOT1ypR2ulWSw5xIY5vtwVP8JstWQBtBRvGhgZwoMlsrigtosD0aXgCsDDO9Ooe3M4M4At2UsLrViVQbeWs7EVFTnBhua_NzaOTWetreVrIod-FCRqaJUEqQ1mJohxcbqjcGpMCoEwpZOuxq_cGbz4KUMa8_aeB9yUyoLDJfeP9sV3yIvxV0EuShyE1EGQqN44d1aWSp6y3a8zjQvn43wz4oKfGEhihe9pX3AH8C6rgdHYwftXnIofBAGhgfMHUHTGM1mxg02q73VG4MJqt2Wv6R_K8ImiFBrHmJIQ8wHLW-xggrxLqWnHAY691AOmj-8SSOaWFRUwvJSeI-0nxHZeOAcrz3XLlFtHQiRqVebmzYUSnEKeLnc2tgoUAbWreq2mUegoKW_j9lz-qae99D6iHNUo7ByN2pclc06QQdiDamXPu3qJg5V7DiM8C_c5tztX26ahWF3nLDh8iDgIg_vG9MeoxbcdxSZBZ2df_oLSKQ08xB5l7Wq9ogwdo7fQOY6EU1Wlu4EoOQutDIlDlpVZb8DG3tyU24RIWHnJwtMYkQmiBDs4unfeTIi6zOlbQ6UdS3dG0DJ3S9KM7xSlbRhue_sjYcr0uWxECDMewt9mHhn9KzXtfSgNRR7p9jpohKsPhc9Ot7-O6GyZ5xTwQ8yErC3-Bg-W1UiQgJ3h8914FR28rA_hO6YfEzZ7b3fSxslKyjcf5IKi5IlZ4ikB_cpMAqDyWqnB47hu_sBfTD5e4CAkpVLEnMN-7AckSQIcM_aiX2xPtMIkTX9TNw_C9nmTPwmVM9dfeDcrqMXxuLhNfsJjMUragCRqcvVwqBPSMIMN-nulRYu9I7daBqHX1-zi-uUkb1muClrWTDWV_Rw9IQF323T7RRHIJ0Q0TjdceuvYQZHj3VRBV5LpS2uuLTTrb325SFgeC8RmXJpr3E5DuWKpU-UMNZgKy0bjohM_QQHbbxAN7d9MTtVfRXyTZVhc5KWvnagNKtM018mpJr2GFF52nJpx6nSCUHJ6hold_jYMe-zHeDsrhb9mkZbOfIlolCVae7ST1CUglpocqV3bqwHbvNqN8pUgcj6C8-0Mmpvb5VPzl-4TAgi651QO2eg0MvAPFtVRkZnteF8ISth3ppkPRqd97HX6KBpmfPMRL5GxqilwYSjgjnV-7Kv2sP87yF8KMbx36ArndW1tO7Tf_TzB5HpEepqfIgsNFiXkg1s0FyK_2rY16WEDvdW4jdbvy-6p_wLl1-1OgTxmHoxPTs2xMZ4AMzxDJZQEfjrwVJXKi7Awl1i_-9B4XLr_vpxurXfqHLRqNw9NYQqtdvTXID2PJ85IutxGi25jTbeoNHTJd7V7xRe6SGN_6YCHv3rs7r4Fy55URWDIn6Y8ORuNfv62Q9zg01VurMMGPZ3HsB7JYR6cZcYE1YXbrUZBUd9-yyA4tmmofA2Hl0IJ-0UNFkOSKWj9BJaLUCjGjeuOqiiTV3XYQlDZO2Oy20g6mmm29Qh5C6LOT-4e_VAIQ_dqXvK6I7Y_kPHhQxkA-ALKm1_1Nm_ffLBzdOqcdfjWuBwojuv-avt6PYVKWp8ozkqvXpeXqc3miy_0uwZd69xf4zVvmzTbbp1pLf_L33y0uNAEtczeOmqIbxi84TNkhm9gvn4hozH6Ti-GV_lc7KjGcv20_0OZtcsI8CSOB5njIwnk2l6nV7xOYnJdXwzTkk8vpmMR5M0nWXAyITss5sJ3KDrGArKxUiIYzFS-nDFjalgPpsRMr0SdAfC-O8GEFKApbvq4FP8FSKkfs9DyaJ9_6xHgv3PpjWFymZAWZQsmrmT2ys9d0JEu-pg0HUsuLGmE8tyK2DefQHh_H3TUWr98arSYv6B09WPjp5hqdU_IHPByevujBbUP87JvwIAAP__KOgdRg">