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

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

## DirectX

| DXIL Opcode | DXIL OpName | Shader Model | Shader Stages |
| ----------- | ----------- | ------------ | ------------- |
| 119 | WaveActiveOp | 6.0 | ('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 WaveActiveProduct_test.hlsl -T lib_6_8 -enable-16bit-types -O0

export float4 fn(float4 p1) {
    return WaveActiveProduct(p1);
}
```
 ### Example 2
```hlsl
//dxc WaveActiveProduct_1_test.hlsl -T lib_6_8 -enable-16bit-types -O0

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

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

Multiplies the values of the expression together across all active lanes in the current wave and replicates it back to all active lanes.

## Syntax

``` syntax
<type> WaveActiveProduct(
   <type> expr
);
```

## Parameters

<dl> <dt>

*expr* 
</dt> <dd>

The expression to evaluate.

</dd> </dl>

## Return value

The product value.

## Remarks

The order of operations is undefined.

This function is supported from shader model 6.0 in all shader stages. 



 

## See also

<dl> <dt>

[Overview of Shader Model 6](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/hlsl-shader-model-6-0-features-for-direct3d-12.md)
</dt> <dt>

[Shader Model 6](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/shader-model-6-0.md)
</dt> </dl>
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWl9T4zgS_zTiRRWXI5NAHngwgeylalimhtnZfaMUqxPrkCWXJAeyn_6qJTtxSICZuc3uPdwUNditVv_5dbfckuDOyZUGuCKjazK6OeONL429WnL7p9HqbGHE5mpAyeiaktENnVe1ggq0p2Sc_s7XkBderuGzNaIpPBmntFBcr-iikcpLTdiUpPlu-iepn75vJn2WvkTWUjn1KLW3UjtZuKQk43RPZi4EdVBxWpRQPDm6NPZNFd7g0BQZ__Xp4dN11DVrdOGl0VOuFHJJjVwPUPHAKfUqKer6mN7CCFiB_g6dt5X0PZW3L7XdqZr-0pI_0uPBeddKDHARNkMaYbOpEfALaNRB2KxF0RE2OzAqQUjfRPEdFYhIKz_YOz8ufwDWGuuOqpla4B6oLwHlS-0fxcvjUdi2IW8xmm9T4EZaKPwfiRfvS7_5Y_7pvr7jdS31CkWa5UdKvaHIMhxOdsFBMe_rOhr6JOYS1-Lo8GMLUuSKoEd9Sq2rg7ASNmvdJmz2MaiuXv8oqg-f51--HfFzrmkYmmvnbRPq5AEUFN5YzFZa7Ck_qlSZZ7BSrwIYFa8plb7NsA-MDXX4hnaS5STLXXjbukHGaXIMGxQy-EYXvHgCLQLetOAOPsA86CZshqk82C1CR6tKtcmOPywjLKNdxCLtYkoxleh9jdVMe--_8iq-P5RcgKV3RoDqEx48X4FDSitosPtHP3g_JAx6gobDSRjfuXNfB8I4ScNvwi4Ju1ByYbndEHZBGNIuClPVjYcdgVe1kktZcAzRjlyBK3dvtXwBtXtdg_XwsnsvG9UbFabisidqBaYC3zfC8s0KNNhXOqX2YB0U-1SuN6X0PQ-UceD8Hq2SzvU4uFJ8oXpOaiPi26SDcBvrmGBbEubfff2LNU39q9G_abk0tprdNYqMbgi7LL2vHSYwmxE2s7CSzttN8lRao41LjF21yTfA7HM1hJxrtFxKEMMuMZPSV4qw7LgiNkEFe_kIrrCyDriEIUpJmud0qQz3WJ-1kdrTqlFe1mqDPqxQMDV1B_IJrA-2P95vVbAJLtT4KUbD829cNUBYHo3QwtHCYCEuGg-CLjaUh7RFY6Vem5iA7hSGzrfi0Uapcc1DG1uUToYNYZMkRCr8R1j-BVyjPP26qQMwVeM8XQDl1BVccUuNpeuwRIYv3uiasLwL8SCEmKS5j5NPYfSs1XVg9-0LFE3EL6fSUd4a91CYkxkTZD8OpBhg0HzJPZUCtEduF75abYovSZr3Eojy5RKKNsV8KTHtqoprkdC530KORrP8oVnEDAhvPZ-_ltBq8xvknaPjoVdkeS_hAxjDhM6XRwYidITlU9U4DxbEFxBNAZEYF6Zu7EH-uZcRtQUH2r-yCEMfMqNXXN0MBMTh54g7epBpCcXpFfjSCNo4EJhHhtZgcdHpg9m5QE2okr2S7akl7NJhWJbWVG0dv4qCdFR2W44oUcBSahD7mfXKfxkj6-SfwdEijmLL0ThI3gGMkzTviqgrHfycrHD26SpmHlXgks2m9Lk0LqTWA27MhAb8KG3XP3Qu9DhveFGYClpAWwcKo53noerlro06kSvTVtm8r2mS0Gso-Voai-Y3ug0ibbRC796IIfdUAXeeDkPnyGmNjSRGhnXFcjCJpPkqtHwWi13v5UHoUf-G1RqDCHGt06u4ePSBT3Mbyio0_DssFi1CSfvNHl1Pec0XUkm_OUmkdtJDq9DVEmH5q3Yit9KXFXhZ7C06h4zbJWrL95bIz9x6iWiA-PVb5OgV9Oj6TjqH4C1gaSycwv3fIj30ckH_GqzDBWaYZO1C3gYim_rQBma38a0wKqZQj0Cd3yDLDWHsWQpfIqBDRtiIMEbR4v8z_9fMhM0OsPclcLF7s70Bkt3-bqygU9NoH6cHYm887sWOj8Vvn3trYmxGj4-egIpvdu9t3_GFEZujMAhaKO5cxDck8kKZ4omWXMmVHihYerqOz97UhLGoHREeU8Ku6ZpbGfMf1dY748RfoiQbsXclkzT_adkkm0KFv9lYeZJdS0HYeIVPUVEczKYLu5dngdxvffaYTwECyabYepQWlnE6YVk0YC62jH2zPvKIsBn_e83tN9p9gwP9B-w9FovdxuEficTBDrXvXxiku8EfcOvtSf9jtRD79ZNjfx-OJrh6w4qfsbzfH36X_Yfr7N7KioReM5DuH7B8BefplDtoNzZxMPQ1kQOZbl847mjoEEfHafwJZ-Vp29qIl4IeHhh7cPHong6-UiUXj-PHSzoAjeYMhuOF9APcojg6uG-PIeGlNtbH451zutSEXbbP9TCeYV2HlotSC76x-lApYZeBFbFOc3Jx07f5uFvsB90a_rxjjdSdX_HxhG5lP-gW-3m3dl79pU61DoULnO5g8C4e9XVHIWusc9dtleCltuBCT-zNCnwJlvLCGucoV6o7d1Ncg2tPw2jRWAva02e-hrBns1ArWXCPLD4cv-Mu_PX0ZP8odaM9f2lJnQPUbanZNGzFs9ujGMRNxJSRPO1xoi9BQwdPH5it5s_c8go8WLdt_YXC6fjgdzXP8iCPhdKOq0IYDnxiy_f1NYgUEGHuYbe1wKminYrPqqcl2PQlhjuEZie2jv5GcvJqQsXtk9vxGivirnl7LOP2duFJxyodXbZXocjgmhrzEUQ8TnDxLqIKlxPjJFzPYCBbugt3FAndWxZjGPaCC0C5cuZ9gEfX92uwawnPaPfetcj42GZwJX3ZLJLCVITN7iQmqVn6GxN2gM9SZ4yw2UKZBUIcqQLckzf1wNmireNwW5OJUNztlU_0bRB8HowH6WAJ3DcW3GBp7KCbMRiypBLtev8qG_ac-kccee3DW6Z22XcmrjIxySb8DK6GF2w4HKfn55Oz8iothnw8Ogc2HmXDy_PJaLw8v0iX4_NiMkrZSJzJK5ay8_RiOGZpesEmSXYplozD5YWASZZBRs5TqLhUiVLrCjfsZ9K5Bq4mk-F4dKb4ApQLf4fAWAWeL5pVaMCmhLH25o5k-fYetB2JN9IHbN1BQDdgPMnyjnd0c2av0IjBolk5cp4q6bzbmeWlV3C1-2OH9243USbt_oTgrLHq6p2QtheNQXVtzb8B16xZQAFjGYFYX7H_BAAA__-8TTba">