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

    <tr>
        <th>Summary</th>
        <td>
            Implement the `WaveMultiPrefixProduct` 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 `WaveMultiPrefixProduct` clang builtin,
- [ ] Link `WaveMultiPrefixProduct` clang builtin with `hlsl_intrinsics.h`
- [ ] Add sema checks for `WaveMultiPrefixProduct` to `CheckHLSLBuiltinFunctionCall` in `SemaChecking.cpp`
- [ ] Add codegen for `WaveMultiPrefixProduct` to `EmitHLSLBuiltinExpr` in `CGBuiltin.cpp`
- [ ] Add codegen tests to `clang/test/CodeGenHLSL/builtins/WaveMultiPrefixProduct.hlsl`
- [ ] Add sema tests to `clang/test/SemaHLSL/BuiltIns/WaveMultiPrefixProduct-errors.hlsl`
- [ ] Create the `int_dx_WaveMultiPrefixProduct` intrinsic in `IntrinsicsDirectX.td`
- [ ] Create the `DXILOpMapping` of `int_dx_WaveMultiPrefixProduct` to  `166` in `DXIL.td`
- [ ] Create the `WaveMultiPrefixProduct.ll` and `WaveMultiPrefixProduct_errors.ll` tests in `llvm/test/CodeGen/DirectX/`
- [ ] Create the `int_spv_WaveMultiPrefixProduct` intrinsic in `IntrinsicsSPIRV.td`
- [ ] In SPIRVInstructionSelector.cpp create the `WaveMultiPrefixProduct` lowering and map  it to `int_spv_WaveMultiPrefixProduct` in `SPIRVInstructionSelector::selectIntrinsic`.
- [ ] Create SPIR-V backend test case in `llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveMultiPrefixProduct.ll`

## DirectX

| DXIL Opcode | DXIL OpName | Shader Model | Shader Stages |
| ----------- | ----------- | ------------ | ------------- |
| 166 | WaveMultiPrefixOp | 6.5 | ('library', 'compute', 'amplification', 'mesh', 'pixel', 'vertex', 'hull', 'domain', 'geometry', 'raygeneration', 'intersection', 'anyhit', 'closesthit', 'miss', 'callable', 'node') |

## SPIR-V

# [OpGroupNonUniformFMul](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpGroupNonUniformFMul):

## Description:
  
A floating point multiply [group operation](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Group_Operation) of all
*Value* operands contributed by active [invocations](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Invocation) in the
[group](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Group). 
  
*Result Type* must be a scalar or vector of [*floating-point
type*](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Floating). 
  
*Execution* is a [*Scope*](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Scope_-id-) that identifies the group of
invocations affected by this command. It must be **Subgroup**.  
  
The identity *I* for *Operation* is 1. If *Operation* is
**ClusteredReduce**, *ClusterSize* must be present.  
  
The type of *Value* must be the same as *Result Type*. The method used
to perform the group operation on the contributed *Value*(s) from active
invocations is implementation defined.  
  
*ClusterSize* is the size of cluster to use. *ClusterSize* must be a
scalar of [*integer type*](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Integer), whose *Signedness* operand is 0.
*ClusterSize* must come from a [*constant
instruction*](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#ConstantInstruction). Behavior is undefined unless
*ClusterSize* is at least 1 and a power of 2. If *ClusterSize* is
greater than the size of the [group](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Group), executing this instruction
results in undefined behavior.

[Capability](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Capability): 
**GroupNonUniformArithmetic**, **GroupNonUniformClustered**,
**GroupNonUniformPartitionedNV**  
 
[Missing before](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Unified) **version 1.3**.

<table>
<colgroup>
<col style="width: 12%" />
<col style="width: 12%" />
<col style="width: 12%" />
<col style="width: 12%" />
<col style="width: 12%" />
<col style="width: 12%" />
<col style="width: 12%" />
<col style="width: 12%" />
</colgroup>
<thead>
<tr>
<th>Word Count</th>
<th>Opcode</th>
<th>Results</th>
<th>Operands</th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p>6 + variable</p></td>
<td class="tableblock halign-left valign-top"><p>352</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><a
href="#Scope_-id-"><em>Scope &lt;id&gt;</em></a><br />
<em>Execution</em></p></td>
<td class="tableblock halign-left valign-top"><p><a
href="#Group_Operation"><em>Group Operation</em></a><br />
<em>Operation</em></p></td>
<td
class="tableblock halign-left valign-top"><p><em>&lt;id&gt;</em><br />
<em>Value</em></p></td>
<td class="tableblock halign-left valign-top"><p>Optional<br />
<em>&lt;id&gt;</em><br />
<em>ClusterSize</em></p></td>
</tr>
</tbody>
</table>



## Test Case(s)

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

export float4 fn(float4 p1, uint4 p2) {
    return WaveMultiPrefixProduct(p1, p2);
}
```
 ### Example 2
```hlsl
//dxc WaveMultiPrefixProduct_1_test.hlsl -T lib_6_8 -enable-16bit-types -O0

export uint4 fn(uint4 p1, uint4 p2) {
    return WaveMultiPrefixProduct(p1, p2);
}
```
 ### Example 3
```hlsl
//dxc WaveMultiPrefixProduct_2_test.hlsl -T lib_6_8 -enable-16bit-types -O0

export int4 fn(int4 p1, uint4 p2) {
    return WaveMultiPrefixProduct(p1, p2);
}
```
## HLSL:

## Syntax


```syntax
numeric<> WaveMultiPrefixProduct(numeric<> value, uint<4> mask);
```


## 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), [**vector**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3dhlsl/dx-graphics-hlsl-vector.md), or [**matrix**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3dhlsl/dx-graphics-hlsl-matrix.md) | [**float**](../WinProg/windows-data-types) or [**int**](../WinProg/windows-data-types) | any |
| *value* | [**scalar**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3dhlsl/dx-graphics-hlsl-scalar.md), [**vector**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3dhlsl/dx-graphics-hlsl-vector.md), or [**matrix**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3dhlsl/dx-graphics-hlsl-matrix.md) | [**float**](../WinProg/windows-data-types) or [**int**](../WinProg/windows-data-types) | any |
| *mask* | [**vector**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3dhlsl/dx-graphics-hlsl-vector.md) | [**uint**](../WinProg/windows-data-types) | 4 |

## Minimum Shader Model

This function is supported in the following shader models.
|Shader Model | Supported|
|-------------|----------|
|[Shader Model 6.5](https://microsoft.github.io/DirectX-Specs/d3d/HLSL_ShaderModel6_5) and higher shader models | yes |

## Shader Stages

* **Library Shader**
* [**Compute Shader**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3d11/direct3d-11-advanced-stages-compute-shader.md)
* [**Amplification Shader**](https://microsoft.github.io/DirectX-Specs/d3d/MeshShader.html#amplification-shader-and-mesh-shader)
* [**Mesh Shader**](https://microsoft.github.io/DirectX-Specs/d3d/MeshShader.html)
* [**Pixel Shader**](../direct3dhlsl/dx-graphics-hlsl-writing-shaders-9.md#pixel-shader-basics)
* [**Vertex Shader**](../direct3dhlsl/dx-graphics-hlsl-writing-shaders-9.md#vertex-shader-basics)
* [**Hull Shader**](https://learn.microsoft.com/en-us/windows/uwp/graphics-concepts/hull-shader-stage--hs-)
* [**Domain Shader**](https://learn.microsoft.com/en-us/windows/uwp/graphics-concepts/domain-shader-stage--ds-)
* [**Geometry Shader**](https://learn.microsoft.com/en-us/windows/uwp/graphics-concepts/geometry-shader-stage--gs-)
* [**Raygeneration Shader**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3d12/ray-generation-shader.md)
* [**Intersection Shader**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3d12/intersection-shader.md)
* [**Anyhit Shader**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3d12/any-hit-shader.md)
* [**Closesthit Shader**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3d12/closest-hit-shader.md)
* [**Miss Shader**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3d12/miss-shader.md)
* [**Callable Shader**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3d12/callable-shader.md)
* **Node Shader**


## See also


- [**Intrinsic Functions (DirectX HLSL)**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/../direct3dhlsl/dx-graphics-hlsl-intrinsic-functions.md)
- **See [WaveMultiPrefix*() Functions](https://microsoft.github.io/DirectX-Specs/d3d/HLSL_ShaderModel6_5#wavemultiprefix-functions)**
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsW91u2zjTvhrmhJBgU7GTHORAceq-Bpq2aLrdPQsoaWzxK0UKJOXEe_Uf-CNL8k_SZtfdLLBFgVrkkPPMM0NqSE2p1mwlAK7R5AZNbs9oY0qprpdU_SkFP8tksbmOMJrcYDS5xYuq5lCBMBhNR7_TNdw13LDPCpbs6bOSRZMbNB3hnFOxwlnDuGECkRkapd0cH5j4_hPD8SMzpZUvueYPTBjFhGa5jks0HQ0mTosCa6gozkvIv2u8lOp5PUba_pmV_t-H-w83XuG8EblhUswo51aKCSt1DxV1kkys4ryuDynPZQErED-q-F3FTE_vu6dadfpm70PzS8oMaKPDjI44ROa2DZH5TBbwHoTVgcg88KkRmR9GFluGj5L6jB7LTVDiQC-eURKBUlLpg7pmCqgBbEqwSpgwD8XTw3EWt7EQKFtsY-OWKcjNH7Epnldx-8fiw6f6jtY1Eys7pVz-kGYjsZUbT6edw-xcLyo8QrwPNCqK4zIPgTcv6p3hFXO-rvZ8jsg8kIDI_GWedb1-FdH3nxdfvh2weiGw61oIbVTjltM9cMiNVDaecf4DrFjNXD6CYmLluKlojTEzIQZ_BLZbuEdwoCRFSard09YgNB3Fh6iyk0TfcEbz7yAKRz_OqYYXXOB0IzK3wR51W9fxFcjDmrB_SYJIglsv-raLGbZxhj_Vdvnj3vNHWvnn-5IWoPCdLID3G-4NXYG2LWGiqPuDX3jeb4h6E42nU9e_Y9On2rVO44n7F5FLRC44yxRVG0QuELFtF7ms6sZA10CrmrMly6l1VtdcgS67p5o9Ae8e16AMPHXPZcN7vYWsKOtNtQJZgemDUHSzAgFqRycTBpSGfNhKxaZkpmcBlxq0GbRVTOueBOWcZrxnpJCFf7pqedw63IfatslG4qf6vZJN_VGK3wRbSlXN7xqOJreIXJbG1NqGMpkjMlewYtqoTfy9VFJIHUu1CmEY2TjUNbjoawRbMijGbYjGpak4IslhReTKKhgEJehcsdrx4rowRqM0xUsuqbHLtZZMGFzZYKj5xtqwshNjWbcknwC9w_7waauCXNn93L7FLfD0G-UNIJJ6EKLQOJd2SWaNgQJnG0xzw9ZgwTKxlj4A9SmALrbTW4xM2H3QYgwsnYwbRK5i3HoLkfQL6IYb_HVTO16qRhucAaZY55RThaXCa7dXuvfi5AaRtPVw5DyMRqnxg0-BeR507cJ-9wR549lLMdOYBmz3uTwZFjf3Q8SKyLrMlNRgVoAwVlq791gI8CUapb3wwXS5hDwEmCmZDbqqoqKI8cJsGbegSXrfZN7_7inGW5u_lhC0mY2VXVjDXZJJ0l64OzLGMV4sD3R46hBJZ7zRBhQUX6BocvCNfltq--7Zn4OAqBVoEGYHkfW8C4ze0mpHWEK0fSNRjfcCLcZ2eAWmlAVuNBQ2jCSuQdktp09mawKWbo0MFmxPLSKX2rplqWQVVvGOF5jGrD26-BkLWDIBRc-mffuZ96xmfzpDc99r849GQ_wMYRSN0nYNtSvHvkxWdvTpFszCq7AbNpnhx1JqF1r39oBXCLCvpO3uZ41zuc4RK3JZQSA0GJBLoQ11i5516dSJTJkFZYu-pqsY30BJ10wqC78RwYm4Edxad8SH1GAOVBs8dmkkxbXNKq1nSLtY9gahUbpyqZ-yi10M4sBlrb9gr7ZOBL_XiZXfPPrEj1LllpU7B3RcZIGhOLyxJzczWtOMcWY2J_FUN7tLFPB2p9nJJVLFTFmBYflgz9kX3O5QW7ljU36myjBLBhQfv3kJv5694XdMa0tdBkup4BTG_-bbXR7n1K9Babu9jOMkbOPBDcnMuBQweeefcsl9APUasDYbK3KLCHlkhSktnWOCyAQRgi3i_4T_sjAi8z3uTQm06J5UrwMl736XqsAz2Qjjh7vGXr8_jB3u828-fWygT0QP956g1T6pwdPQ8EwWm4M0FDjnVGvPrwvkjMv8Oy4pZysRcVgavPa_jawRIV67ZXiKEbnBa6qYj3-rtu7AFX-LkmRCnp0ZjdJXz42SGVT2XzLlBiU3rEBkurK_vCLfmcwyNYgz19xPfAbCpyABJTObeJQKln44IokHsCi2gn1YL1mEyJz-Wrj9NLsP2LX_BN5DvuiODf-IJ_ZOp337XCfuOn_CrOOD3tha8Nn6ybn_5K4lKD-C4jXI-9nhD-Hf32cHO6tt6CUDo-HlylfQBs-ohnCs8Z0-rXESVujdE7XnGTy2vdOR_-vu1EchtSme8t0bufYq2YD2l_04-oo5yx6mD5c4AmExReNpxkxkTykaR5_CZSQ81VIZf79zjpcCkcvwux7bPK5hwv4m_kLrxh2pMFZgGiWOoEDk0o91o6wfRim6uO3bc9hk8hqTx6832tvmbA5m_nKTk9eYTF5vcmfxrzA4GOu-IO1cNN5vhKFP3QppR-m2XTQVKJbbRZW8O45iKLb29wbeJJTMzm1jRfX3DmQf3mBxbmoYXH9u7-XdBby_6XbHZUTSr1DVnBpoLz6OnJVXzJRNFueyQmR-x3IltVyaW-lOHo9MJASRecZlZv3tWwvQ342sI63yEAfuM0FSuOAg8zjebyueopWidclyHbkPEgU11AdAXNkjzAD7TFa1FCDMvwS8_9RhT-jbDxPhS0X36y_9-Zum6U3UfUFBJFVg7Ol14AN_hfT2uPe4QtCQHmB_W_z2AHtcHWCpOswVNYo9vT3MHlcvuLeI3Zu3D9jN9zsTn5VceVCFfNS9JeI-hfRsttvez463EKjY4EHUrtuL3__i9r-4_RfFrX_Z74TtvyEKhoib1xJyvvfZ-Y4JVjXVoHzAC3wtmcbLUBSFmca6qW2WCEX4dImXknP5yMQKaz-6sqN17PneLUhAo6v7dobdd_WBV-1WBE1uBlNN48khL1WtY-LgLya7YpjoPlzoFkmByNymnA9-Ujfn9GFiGaKiwCVblaCGBjnqNl0RRZem9kss2p40XAl_8CUPQSi4Kwj0s63GwFDmHwjB8bj3EI3HES3WVORQRNrZFoVyjcjzEnamHWPSfgXHiyb9jL_uQJd-vvYCflAtElBFVBRRBboMzwcg2olOi2xP5Wf2BPyAzh_aAh4Vc1_dvUE6unLMJ64MprU6o762aE_zN1cd8zer9iU3L-r-X8MPGT0kmgNVIu7o9uENImp0t4shMm8ea7sGWni5FDnUxvaUDd_y4CI1ikodHcBz62qBfgEiX3S0g6k4iOl9qEf6Baja0qcdXKuDuL70q6L--a3Jjld0E3WYnt2FFr3irbcBvl9O9vwG6irM3gZoKjZRycyzeGfbCri3gTlU5L2I-45p_TYQV0zr5ykOJYRvA25b0HgQsoP2URawl_EMUiYATLmW2_ZosHRDvXFbi68xIpfhzesvCu2B6K0l6tsK36hNl_WWmqgt8gJXPLJzU-mLmGzuubX4JLlt8kjX4Msynd4O6JbQs-I6Ka6SK3oG1-MLMh5PR5dkfFZeT4slGZ9nY3J-TsYX51cXMEqSbEovALJpsZyesWsyIueji_GUjMbJ-Si-SPIMljSHnGSjq-kSnY-goozHnK-rWKrVGdO6geurKzImZ5xmwLX7fyiEVGBo1qzcp7MZIiRUXqMk3Za1hx4fDXtibQlH2yENStJWdnJ7pq4tiChrVhqdjzjTRnewDDMcrrv_7PJinbqdeOu6s0bx62ciMlSLO_21kv8HubFvB0uFdZ9nY31N_j8AAP__GD_VSA">