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

    <tr>
        <th>Summary</th>
        <td>
            Implement the `pack_s8` 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_s8` clang builtin,
- [ ] Link `pack_s8` clang builtin with `hlsl_intrinsics.h`
- [ ] Add sema checks for `pack_s8` to `CheckHLSLBuiltinFunctionCall` in `SemaChecking.cpp`
- [ ] Add codegen for `pack_s8` to `EmitHLSLBuiltinExpr` in `CGBuiltin.cpp`
- [ ] Add codegen tests to `clang/test/CodeGenHLSL/builtins/pack_s8.hlsl`
- [ ] Add sema tests to `clang/test/SemaHLSL/BuiltIns/pack_s8-errors.hlsl`
- [ ] Create the `int_dx_pack_s8` intrinsic in `IntrinsicsDirectX.td`
- [ ] Create the `DXILOpMapping` of `int_dx_pack_s8` to  `220` in `DXIL.td`
- [ ] Create the  `pack_s8.ll` and `pack_s8_errors.ll` tests in `llvm/test/CodeGen/DirectX/`
- [ ] Create the `int_spv_pack_s8` intrinsic in `IntrinsicsSPIRV.td`
- [ ] In SPIRVInstructionSelector.cpp create the `pack_s8` lowering and map  it to `int_spv_pack_s8` in `SPIRVInstructionSelector::selectIntrinsic`.
- [ ] Create SPIR-V backend test case in `llvm/test/CodeGen/SPIRV/hlsl-intrinsics/pack_s8.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>&lt;id&gt;</em><br />
<em>Result Type</em></p></td>
<td class="tableblock halign-left valign-top"><p><a
href="#ResultId"><em>Result &lt;id&gt;</em></a></p></td>
<td
class="tableblock halign-left valign-top"><p><em>&lt;id&gt;</em><br />
<em>Operand</em></p></td>
</tr>
</tbody>
</table>



## Test Case(s)

 
 ### Example 1
```hlsl
//dxc pack_s8_test.hlsl -T lib_6_8 -enable-16bit-types -O0

export int8_t4_packed fn(int4 p1) {
    return pack_s8(p1);
}
```
## HLSL:

## Syntax


```syntax
p32i8 pack_s8(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) | [**int8_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_zTyi2qoQQNz4IEHwCZ_V_nknAr-J3mjxKhhtNZIs5IGm3z6LUlzNdg-m83ZJFXrctno1pdft1qtFtQYfpQACzRdoentDa1srvTiQPVvSoqbvWLnRYTRdIXR9BbfF6WAAqTFKI1Lmj3tzAylMc4ElUe8r7iwXCKyRvGyW_TA5dN78_Ezt7mbkAsjdlxazaXhmRnlKI0HlJaMYQMFxVkO2ZPBB6VfEbbKdazd8P89bB9WgcOmkpnlSq6pEG4Wl27WFgrqZ3J5HGVleY1bphgcQb7J6a7gtsfo7qXUHYP1D3X3R9QtGGtqih4aRDauD5HNWjH4AaTjgcimRswgsqlFGTnQ3sTpHcJO-5qql_K-TzUCrZU2V4mvNVAL2ObgqHJpd-xl1wOmNWCNwn1r0FuuIbO_jix7n-btr_cPX8rPtCy5PDqS6nCdlVXYDRASd6C7xe9z6BlyFPyBStbr3NXKh7EAYaAtxKm4MA0im1oxRDYfg2XK07ehtf16_9PPVzS5l9gP3UtjdeX9egsCMqu08zOcDVj2WAn1DJrLo1e3oCXG3Na-cVUwv0fe4ISSJUqWxrdakVEaj65p74hEP-M9zZ5AMo8ozqiBD1D1vBHZOCeMurDQ831RO6f7JQkiCW4sEfo-rbFzB_yldDsN99o_0iK0tzlloPFnxUD0O7aWHsG4nppQ1P3gD9qXHVGPECGxH_9Ks6fJy8x_Tkep_4_IDJF5M7nVKgDYdjl8v5QrbjNqLJreIjLLrS2NMwrZILLRcOTG6vPoKddKKjNS-lgDGjlETQkex0ryAwc2bsAe5bYQiCQdcTJ3RAcIg8k0L50zhCGMUbxccYtLai1oGZUaDOiT8zR7LgFnSp5AG67kyM_1fxBZ_gSmEhY_nktAZImLyli8B0yl0w8RN-VL6Ua_Ki4t6ND1ffQdsJkjssZKY4ripcmooNq1Tt7xfSzy4smqAM0zKiIbNPgekv3YMEFkPkTvSwmaStYil9MTYBoQb2X8H4SvIby3naOheMn44QDaJTQeOJs773vtmj3gV3BQGnDAsfZqPB5Na2CTJb4_YOA2B31Jx0EwtBw3XoqygW3tw7byy1sxcT3s8ZTuxIAjaBxgDbJtLdXWbbiQSv0Z0rnhC-kaL2j7UbwMTtDD9P6A9yqI_Uoid1A5lq1TD8SjGhrmphbu7CmheOnF84OOs8LGx_vpylil6RFcAmrM9_C2bWCwW3sGg027gpyeuNIO10oyOHAJDPNDOKr_BNlqSAPoKF42sDMFBktlcUFtlgejS8CVAYb359B2ZnBngNsyFpdasSoDby1nYiqqS4MNTX5p7ZwaT9vbSlbFHnyoyFRRKgnSGkzNkGJj9cbgVBgVAmFLp12NnzmzefBShrVnbbwPuSmVBYZL75_tim-Rl-IuglwVuYkoA6FRvPRurSwVvWV7Xmea189G-GdFBb6yEMXL3tI-4A9gXdeDo7GHdi85FN4JA8MD5o6gWYzmc-MGm9Xe6o3BBNVuy1_TvxVhG0SoNQ8xpCHmg5a3WEGFeJPSYw4DnXsoB80fXqURTSwqKmF5KbxH2o-IbD1wjteBa5eotg6EyMyrzU0bCqU4B7xcbm1sFCgD61Z128wjUNDS38fsJX1Tz3tofcQ5qlFYuRs1rspmnaADsYbUS592dROHKnYcRvgXbnPu9i83zcKwO87YcHkUcJWH941Zj1EL7huKzIPOzj_9BSRSmnmIvMtaVXtEGLvEbyBznYgma0v3AlByF1qZEketqrLfgY09uym3iJCw85MlJjEiU0QIdvH07zwZkc2F0jYHyrqW7g2g5O4XpRleq0rasNx39sbDFen6WAgQ5q2FPky8MXrR61p60BqKvVfsfFUJVp-LHh1v_71Q2RPOqeBHGQk4WHwKn60qESGBu8NnEjiVnTzsD6E7Ju9Tdnvv99JGyRoK95-kwqJkxRki6dF9CozCYLLe64Fj-O5-QB9M_h4goGTtksRcwyEsRyQJAtyzdmJfrI80QmRDPxL3z0K2ORO_CdVLVx84t-vohbF4eM1-BGPxmhpAZOZytTDoE5Iww026e6GFC71jN5rG4dfX7OI6ZWQvGW7KWhaM9RU9HD1iwfe7dDfDEUgnRDRO99z6a5jB0Ze6qAIvpdI-g57t7MRXh4Dhg0RkxqWd4HIcqhUrnydhrMFWWjYMEZn5CQ7ZeIk-3fal7DT1RchXRYbtWVr60mHSrDJNf5kQPusxovK849KOU6UTgpL1BCV3-NQx77MdwOxuFv2SRls48hWiUJRprtKPUJSCWmhSpTcurEdu82o_ylSByOYzz7Qy6mBvlc_Nn7lMCCKbvVB7Z5_Qy8A8WVVGRme13XwdK2HemGQzGl32sZfoqGmZ88xEvkTGqKXBgqOCOdX7sq_bs_zvIXyoxfHfoKuc1aW07tN_9PMHkekR6kp8iCw1WJeRDWzQ3In_atjXlYQO91bi4c7vS-4J_8LlV62OQTqmnk3PjA2tMR7gcrpAJdQD_nqo1HWK66j8u1C4zLq_fpzu7DeqXDQqdw8NoUbttjQXoD3PJ47IZpxGK26jrbdn9HiNd_U7hVd6SOO_qYBHf3JRFf_MJS-qYlDCDxMe3Z3mUD_6YW6wqUp3kgHD_sYD-KCEUM_uCmPC6sKtNqPgqK8fBVA83zYUXoejK9GknYKmqwGpdJReQ6sFaFTjxlUHVbStqzosYYhs3Gm5C0Q9zXSXOoTcVTHnR3erHijkoTt3DxndCdt_5riSf2wBfDml7Y86-7cPPrh5WDXuclwLHA505zV_tR3dviFFjW80J6VXz8vr9EbT1VeaPeHuLe6PsdrnXbpLd4707v-lz116HEjiegbvXDWEN2yRsHkypzewGH8i43E6jtPZTb6YzhnZkyQbT2DKpuN0Ms4SMhvPWDYex1N6uOELEpNJ_Gmcknj8aTIbxfM9m6QpyyCez9MU0CSGgnIxEuJUjJQ-3nBjKljM54R8uhF0D8L4bwYQUoCl--roE_w1IqR-zUPJsn39rEeC_S-mNWXKZkBZlCybudPbG71wQkT76mjQJBbcWNOJZbkVsOi-fnD5uukotf54U2mxeMfp6idHz7DU6h-QueDkdXdGC-qfFuRfAQAA__-6Nxs7">