<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/99170>99170</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Implement the `WaveActiveMax` 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 `WaveActiveMax` clang builtin,
- [ ] Link `WaveActiveMax` clang builtin with `hlsl_intrinsics.h`
- [ ] Add sema checks for `WaveActiveMax` to `CheckHLSLBuiltinFunctionCall` in `SemaChecking.cpp`
- [ ] Add codegen for `WaveActiveMax` to `EmitHLSLBuiltinExpr` in `CGBuiltin.cpp`
- [ ] Add codegen tests to `clang/test/CodeGenHLSL/builtins/WaveActiveMax.hlsl`
- [ ] Add sema tests to `clang/test/SemaHLSL/BuiltIns/WaveActiveMax-errors.hlsl`
- [ ] Create the `int_dx_WaveActiveMax` intrinsic in `IntrinsicsDirectX.td`
- [ ] Create the `DXILOpMapping` of `int_dx_WaveActiveMax` to `119` in `DXIL.td`
- [ ] Create the `WaveActiveMax.ll` and `WaveActiveMax_errors.ll` tests in `llvm/test/CodeGen/DirectX/`
- [ ] Create the `int_spv_WaveActiveMax` intrinsic in `IntrinsicsSPIRV.td`
- [ ] In SPIRVInstructionSelector.cpp create the `WaveActiveMax` lowering and map it to `int_spv_WaveActiveMax` in `SPIRVInstructionSelector::selectIntrinsic`.
- [ ] Create SPIR-V backend test case in `llvm/test/CodeGen/SPIRV/hlsl-intrinsics/WaveActiveMax.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
# [OpGroupNonUniformFMax](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpGroupNonUniformFMax):
## Description:
A floating point maximum [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 by
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 -INF. 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. From the set of *Value*(s)
provided by active invocations within a subgroup, if for any two
*Value*s one of them is a NaN, the other is chosen. If all *Value*(s)
that are used by the current invocation are NaN, then the result is an
undefined value.
*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>358</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><a
href="#Scope_-id-"><em>Scope <id></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><id></em><br />
<em>Value</em></p></td>
<td class="tableblock halign-left valign-top"><p>Optional<br />
<em><id></em><br />
<em>ClusterSize</em></p></td>
</tr>
</tbody>
</table>
## Test Case(s)
### Example 1
```hlsl
//dxc WaveActiveMax_test.hlsl -T lib_6_8 -enable-16bit-types -O0
export float4 fn(float4 p1) {
return WaveActiveMax(p1);
}
```
### Example 2
```hlsl
//dxc WaveActiveMax_1_test.hlsl -T lib_6_8 -enable-16bit-types -O0
export uint4 fn(uint4 p1) {
return WaveActiveMax(p1);
}
```
### Example 3
```hlsl
//dxc WaveActiveMax_2_test.hlsl -T lib_6_8 -enable-16bit-types -O0
export int4 fn(int4 p1) {
return WaveActiveMax(p1);
}
```
## HLSL:
Returns the maximum value of the expression across all active lanes in the current wave and replicates it back to all active lanes.
## Syntax
``` syntax
<type> WaveActiveMax(
<type> expr
);
```
## Parameters
<dl> <dt>
*expr*
</dt> <dd>
The expression to evaluate.
</dd> </dl>
## Return value
The maximum value.
## Remarks
The order of operations is undefined.
This function is supported from shader model 6.0 in all shader stages.
## Examples
``` syntax
float3 maxPos = WaveActiveMax( myPoint.position );
BoundingBox.max = max( maxPos, BoundingBox.max );
```
## 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/eJzsWl9T47iy_zTiRRWXI5OQPPBgAtmbqplhapid3TdKtjuxLrLkkuSQ7Ke_1ZIT2yTAnTnL2fNwttjBbrX6z69bcrcEt1ZsFMA1mdyQye0Fb1ypzfWam7-0kheZLvbXI0omN5RMbumqqiVUoBwl0_gPvoU0d2ILn_mOTGOaS642NGuEdEIRtiBx2k39JNTT-7Pos3AlspXSykehnBHKitxGJZnGA3lpUVALFad5CfmTpWttzop3GskLZPqfTw-fboKeZaNyJ7RacCmRSyjkeoCKe06hNlFe1-d05rqADah39N1VwvXU3e1q06lZ_NaS39PhwDrbSvQwEbZEGmHLhS7gN1Cog7Bli54lbDkwKEIYX0XuDfGIRCvb27o6lT0CY7SxZ1UsDHAH1JWAsoVyj8Xu8QSqY3hbXFbHcN8KA7n7M3LF25Jv_1x9uq8_87oWaoMi9fothU5THB6P510wUMTbek7CHIWc4ao4GXpsQQkcAeCgR8ptdRI-wpatq4Qt3wfR1tufQfHh6-rbjzO-rRT1QytlnWn8OngACbnTBjOS5gPFJwqlfgYj1MYDUPGaUuHaLHrDSL--XtFKkpQkqfVvR_PJNI7O4YFCRj9oxvMnUIXHmObcwjs4e92ELTFdR93GcrJiZJvM-MMSwhJ6iFCgXS0opgy9r3GV0t77F16F94eSF2DoZ12A7BMeHN-ARUoraNT9R995PyWMeoLG47kf71y5rz1hGsX-N2Ezwq6kyAw3e8KuCEPaVa6runHQEXhVS7EWOcfwdOQKbNm91WIHsnvdgnGw697LRvZGC11x0RO1AV2B6xth-H4DCswLnUI5MBbyIZWrfSlczwOpLVg3oFXC2h4Hl5Jnsuek0kV4mx8gPMY6JNeRhLl3X_9mdFN_0ep3JdbaVEvM6cktYbPSudpi8rIlYUsDG2Gd2UdPpdFK20ibTZt4I8w8W4PPt0aJtYBifEjKqHSVJCw5r4jNUcEgH8HmRtQeFz9EKYnTlK6l5g7XZa2FcrTiO1E1FbqwQblU1weMP8B4b_rj_VEFm-NejF9XtDv9wWUDhKXBCFVYmmtcg1njoKDZnnKftWisUFsd8s9-hKGro3i0USia7UmceoQiD6T_h7D0G9hGOvp9X3vDq8Y6mgHl1OZcckO1oVu_e_mPzuSGsPQQgZGPAIlTFyZ_hB_LVhdh86HddzvIm-BfSoWlvDXuIdcfZoyX_TgSxQhBdSV3VBSgHHJb_yFpU3BN4rQXYMrXa8jbFHClwLSoKq6KiK7cEXI0mqUPTeaFhLeez99LaLW5PfKu0HFfnrG0l5AejNHqyzKiq_WZsYAeYelCNtaBgeIbFE0OgRi2jsPYg_hrkBS1AQvKvTAKo--To5f_hxmIicUPBrf0JNkiitMrcKUuaGOhwFTStAaD20Ifz4MLVCtP7q-qnlrCZhYjsza6apfai0AIS8WhuA8SC1gLBUVElzjJ2wvuhTutXBKntdFbUQzWcl88lvVC4eI5RnFBxdqHias9dc96uFFYqpUHz5VQhTT-wr_gLLREuxIMUvNSW1A-olzK86b5dOQGPJIh0YDmjTHYx3RGepZOR8DThLigfkXitFEtKnSLaoYL70VuiJD4Vvzl_cjDKBZKjYXojWTiJE4Pe8xhZ8GP4QZnf9yGsgoqEDO2oM8ILBr5gO1hoQA_qcftG53z1dkrXuS6gjbZWgdyrazjflMUXQH4Qa4sWmWrvqZ5RG-g5FuhfeZ0oWyURO9eiSF3VAK3jo59vctpjeUvRoYdNpKTSf6DgsWqwb1QDfLAV9XtJ_nDPsRtECF8CtQm7K194OM0pLZvTzosshahqK04JjcLXvNMSOH2HxKpTrovdA5ribD0RTGUGuHKCpzIBxvyKeNx-z7yvSbyKzdOIBpQfPkROHoLenLzWViL4GWw1gY-wv3fA91Xol7_FozFvWgcJe13rg1EsnC-iE3uwluuZUihHoFat0eWW8LYsyhciYCOGWETwhhFi__L_C8zE7Y8wd6VwIvuzfQGSHL3hzYFXehGuTDdE3vjoZM8PxbqAvvaxFBLnx_9ACq-mcHb0PFMF_uzMBQ0l9zagK9P5Ezq_ImWXIqNGklYO_yi4rPTNWEsaEeEp5SwG7rlRoT8R7V1Z1zxtyhJJrM3JZM4_WXZJFlAhb_ZVDqS3IiCsOkGn4KiMJgsMjPIM0_ul4UD5o8AgSQLLD1KA-swnbAkGLAqjox9s97ziLAl__ea2-9D-gZ7-k_Yey4WXV_1j0TipMHu--cHaTf4E269Puk_bC2Ewv7Dsb_3BytcvmLFr1jerw__X_af7rODnRUJvWIgHh4PfQfr6IJb6DogrGn8_54Dme52HLs9OsbRaRx-_El-3JY2xS6nw6NtB9b50346-k6lyB6njzM6AoWmjMbTTLgRtieWju7bA1TY1dq4cDB1SdeKsFn7XI_D6duNL7coNeAao4YKCZt5NsQ4TsnVbd_W8-6wn3Bn_OsONUId_AmPH-RO8hPusF93p_Pmb3OmdcRfIR2OL795OaErPhxO-jb60BbBrjZgff3Lc6Ot9T19e5oguQLfrPS792e-Bd-WGailyLlDFufvBrDRfjk9Gp717pXju5Z0sJ3aIzVZ-G47uTtxPfQIC0bSuMeF5nvpB1T6eBy1fuWGV-DA2GNlX0icjg-uW9Is9fKYX7lh0fthz1cc-b4PcXOaAmLKHXSdA04t2qn4LHtavE0hMiEYndhBjKIXEypunmzHq00RmuLjiZQdNNnRgVVYum7vXpHBNjWmIBThtMCGi5LK35xMI39vhEFs6dZfoER0sOuFMPSta5ePfTW0YUdK0MOv2lKS3J6EmFb7r1ooF9Xa-h6RHuOKa-JGN6oQanOjd1HFd15E1U70QrE9PWF6OzMeACiXVr-dF5Ob-y2YrYBnhHtw1TQ916JuhCubLMp1Rdjys8B1pdfuVvu-9FmohBG2zKTOMDMCtQD75HQ9siZvdxt_A5YUfgtqr9BCSEY-VKPpKB6tgbvGgB2ttRkdZozGLKqK9iv0IokHTv0jjrz04TVTD4vmorhOinky5xdwPb5i4_E0noyTi_L6MgN-eZXNJtlsNmfZdDYZT2azK5aPJ5eTOYMLcc1idhlfjacsjmcJi3IOV_N8BpdQ8NkkA3IZQ8WFjKTcVpE2mwthbQPX8_n4Kr6QPANp_d9oMFaB41mz8WXhgjDW3oSSJD3eJbcj4Qb_hO1wPHEY0I4k6YF3cnthrtGIUdZsLLmMpbDOdmY54SRcd38I8totMcqjhz-zuGiMvH4jnO2lrVdbG_2_kDvClh4BjGMAYXvN_i8AAP__LqyHpw">