<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/99117>99117</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Implement the `fma` 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 `fma` clang builtin,
- [ ] Link `fma` clang builtin with `hlsl_intrinsics.h`
- [ ] Add sema checks for `fma` to `CheckHLSLBuiltinFunctionCall` in `SemaChecking.cpp`
- [ ] Add codegen for `fma` to `EmitHLSLBuiltinExpr` in `CGBuiltin.cpp`
- [ ] Add codegen tests to `clang/test/CodeGenHLSL/builtins/fma.hlsl`
- [ ] Add sema tests to `clang/test/SemaHLSL/BuiltIns/fma-errors.hlsl`
- [ ] Create the `int_dx_fma` intrinsic in `IntrinsicsDirectX.td`
- [ ] Create the `DXILOpMapping` of `int_dx_fma` to `47` in `DXIL.td`
- [ ] Create the `fma.ll` and `fma_errors.ll` tests in `llvm/test/CodeGen/DirectX/`
- [ ] Create the `int_spv_fma` intrinsic in `IntrinsicsSPIRV.td`
- [ ] In SPIRVInstructionSelector.cpp create the `fma` lowering and map it to `int_spv_fma` in `SPIRVInstructionSelector::selectIntrinsic`.
- [ ] Create SPIR-V backend test case in `llvm/test/CodeGen/SPIRV/hlsl-intrinsics/fma.ll`
## DirectX
| DXIL Opcode | DXIL OpName | Shader Model | Shader Stages |
| ----------- | ----------- | ------------ | ------------- |
| 47 | Fma | 6.0 | () |
## SPIR-V
# Fma:
## Description:
**Fma**
Computes *a* \* *b* + *c*. In uses where this operation is decorated
with **NoContraction**:
- **fma** is considered a single operation, whereas the expression *a*
\* *b* + *c* is considered two operations.
\- The precision of **fma** can differ from the precision of the
expression *a* \* *b* + *c*.
\- **fma** will be computed with the same precision as any other **fma**
decorated with **NoContraction**, giving invariant results for the same
input values of *a*, *b*, and *c*.
Otherwise, in the absence of a **NoContraction** decoration, there are
no special constraints on the number of operations or difference in
precision between **fma** and the expression *a* \* *b* +*c*.
The operands must all be a scalar or vector whose component type is
floating-point.
*Result Type* and the type of all operands must be the same type.
Results are computed per component.
<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>Number</th>
<th>Operand 1</th>
<th>Operand 2</th>
<th>Operand 3</th>
<th>Operand 4</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p>50</p></td>
<td
class="tableblock halign-left valign-top"><p><em><id></em><br />
<em>a</em></p></td>
<td
class="tableblock halign-left valign-top"><p><em><id></em><br />
<em>b</em></p></td>
<td
class="tableblock halign-left valign-top"><p><em><id></em><br />
<em>c</em></p></td>
<td></td>
</tr>
</tbody>
</table>
## Test Case(s)
### Example 1
```hlsl
//dxc fma_test.hlsl -T lib_6_8 -enable-16bit-types -O0
export double4 fn(double4 p1, double4 p2, double4 p3) {
return fma(p1, p2, p3);
}
```
## HLSL:
Returns the double-precision fused multiply-addition of a \* b + c.
| *ret* fma(double *a*, *b*, *c*); |
|----------------------------------|
## Parameters
<dl> <dt>
<span id="a"></span><span id="A"></span>*a*
</dt> <dd>
\[in\] The first value in the fused multiply-addition.
</dd> <dt>
<span id="b"></span><span id="B"></span>*b*
</dt> <dd>
\[in\] The second value in the fused multiply-addition.
</dd> <dt>
<span id="c"></span><span id="C"></span>*c*
</dt> <dd>
\[in\] The third value in the fused multiply-addition.
</dd> </dl>
## Return Value
The double-precision fused multiply-addition of parameters *a* \* *b* + *c*. The returned value must be accurate to 0.5 units of least precision (ULP).
## Remarks
The **fma** intrinsic must support NaNs, INFs, and Denorms.
To use the **fma** intrinsic in your shader code, call the [**ID3D11Device::CheckFeatureSupport**](/windows/desktop/api/d3d11/nf-d3d11-id3d11device-checkfeaturesupport) method with [**D3D11\_FEATURE\_D3D11\_OPTIONS**](/windows/desktop/api/d3d11/ne-d3d11-d3d11_feature) to verify that the Direct3D device supports the [**ExtendedDoublesShaderInstructions**](/windows/desktop/api/d3d11/ns-d3d11-d3d11_feature_data_d3d11_options) feature option. The **fma** intrinsic requires a WDDM 1.2 display driver, and all WDDM 1.2 display drivers must support **fma**. If your app creates a rendering device with [feature level](/windows/desktop/direct3d11/overviews-direct3d-11-devices-downlevel-intro) 11.0 or 11.1 and the compilation target is shader model 5 or later, the HLSL source code can use the **fma** intrinsic.
### Type Description
| Name | [**Template Type**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-intrinsic-functions.md) | [**Component Type**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-intrinsic-functions.md) | Size |
|-------|----------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------|------------------------------|
| *a* | [**scalar**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-intrinsic-functions.md), **vector**, or **matrix** | [**double**](/windows/desktop/WinProg/windows-data-types) | any |
| *b* | same as input *a* | [**double**](/windows/desktop/WinProg/windows-data-types) | same dimensions as input *a* |
| *c* | same as input *a* | [**double**](/windows/desktop/WinProg/windows-data-types) | same dimensions as input *a* |
| *ret* | same as input *a* | [**double**](/windows/desktop/WinProg/windows-data-types) | same dimensions as input *a* |
### Minimum Shader Model
This function is supported in the following shader models.
| Shader Model | Supported |
|-------------------------------------------------------------|-----------|
| [Shader model 5 or later](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/d3d11-graphics-reference-sm5.md) | yes |
## Requirements
| Requirement | Value |
|-------------------------------------|--------------------------------------------------------------------------------------------|
| Minimum supported client<br/> | Windows 8 \[desktop apps \| UWP apps\]<br/> |
| Minimum supported server<br/> | Windows Server 2012 \[desktop apps \| UWP apps\]<br/> |
| Header<br/> | <dl> <dt>Corecrt\_math.h</dt> </dl> |
## See also
<dl> <dt>
[Intrinsic Functions](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-intrinsic-functions.md)
</dt> </dl>
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzUWltz4rjy_zTKi8qUkQMJD3kgEHZTNZNMTbI7-5aS7Qb0H1nyX5Ih2U9_qiUZc81lzs6pWSoVrFv3ry-Suhtza8VCAVyRwTUZTM9445baXM25-VsreZbr8uUqoWRwTclgSm-rWkIFylEyTOcVJ8OUFpKrBc0bIZ1QhE1IOu4WfBLq-6m5dC3cEgeX0sonoZwRyorC9pZkmO5QGZcltVBxWiyh-G7pXJstok5jY4JDv396-HQdqM8aVTih1YRLibOEwlkPUHE_U6hFr6jrY5wKXcIC1FEuN5VwW0xunmvTEZ_8FrvfouzAOhspepUQNsM-wmYTXcJvoJAHYbOoKUvYbF7xHirqpG5eIYpSR4oe4W1LMQFjtLFHCU8McAfULQEpCuWeyuenqIyNsaLktxvjTYWBwv3Vc-Xr9KZ_3X66rz_zuhZqgST1_JCN0xQ7zy86HeO614lHm_WC2bkqY8dTlDX0B20FmlKuqgMLEDaLshA2e1s3tl69rZyHL7df_zyC_lZRP3SrrDONd9sHkFA4bdCVaLHDLrKReg1GqIUXseI1pcJF8x8A8q5_ggPJxiQbW9_aQCXDtHdMYiSS_ElzXnwHVXot0oJbeEOTnjdhM_SzpNvp0a1l9D38YxlhGW01H_ouJhTNTu9r3EB0q33Hq9B-WPISDP2sS5DbHQ-OL8BiTySUdB_6RvuwI9kidH7hh2cV99_DXuq_CbskbNTO2wgU9LbpwmWo9x2ZwRZG1GiaOMTwD2f6B0pJGv5NdFU3DsViYxykZDDxX2ych-9rfC4IG_fQtxoLlq6XYNCFhKW6BsORDxWWllBowx2UJB2HA9lzu9MTrZzh3lVCF8kihuAYvm--QScsLbSyogQDJeXUCrWQ0PEibBIwcOsdGZ5rA9YiiigGinxSkD36bq070rbncYX1CX1cAq0NFMITx3NlD2rBFS3FfA6Gzo2uPJydBW4JJB0fInxV0dsQ9jmuhZQ0B1oEy5Xh6kO-Fj24Y84t5eqFarcEs0-FpOONsegbpmITuhArPB2EWnEjuHLUgG2kC7dny5qkY6HqxtEVlw3YqC0eSUQ58dGfo9ui-n_3iHMtLOAUoTxZnltQBSApfhph63fRM5z3Tm4QkNLU1lAILr3FneFCOUt1IK-aKgeD1Dv7U22iQT1noUg67nSag1sDqAOjoEjHPfGInQ9lRzfzEFRpadVYR3kwMqe24JIbRLXyRyxdL7UN1tcKoyf3UgMVlqTjudTcCbVIai2U2yJP2PirNxh9fKlhG69fjNqVcg9ADp1P4Sw8wr9Gq3Oz5X41mA5NLzpuNnE8l0Cym9AqtFwY3dTbHdS6F5wyJYytRemWeCiwlLABYYziTflvnkzY7EBotwRedi2zNUCymzvvjWGp79gauw-2of3Xh9nrw9nrw-cHw9gyO61dCTCkPypPieG5tUFR3hVyqYvvdMmlWKhEwtwfE_jsdE0Yw6XZBFU1SAOrOnQh0y2OeLX8MGmSTaDCbzaUjmTXoiRsuMCnwCgMZpPc7JjSd_PdKb8ewPxXB1i8G-CR3kNP3PE97Ng6cNLdcOgRQ8sJx6vl0hI2CoMh_vAzcNLNM8eMlPZxdJiGP5_MIJ0ZYbPyuaAY_GNI6tMcmjxSKfKn4dMlTUAhgKQ_zIVL8MS0NLmPoSg819o4Wuoml3BO54qwy7ZR9_HS2rTYTisLAeC1P8kpNeAao6i_dy7DwrDAT0QrYEA53Zag04LP2tpA8aunFMKnwC3pbrl5Y6GkVSOdqOVLwstSuBjO8PY-y33EUvR21O2D1rEBhzMCykD8RCQQb8KAvQuIkzc_XUy8MWUn6BdueAUOjN3cRqUk2Q3FB9e5SDaxNVdUlGEn8I2nEzbDkdDYmTM-NqcLOX23Z-F5lR2vwYQMroXy31MfVs6FsTFWasOdE3rvLlWkXr4tSf4OSa6PS5L_gCQWCq3KnyNK8Q5RJsdFKX5AFLcU5r-RBJ9lxyD4Y9hr9E-kGgYeP7jr6o1Hvyt9QPLhqIBWmDam40XRGF8A0DTtDWijhPOhugRu3Vb2QNjlH5--EDbq7clScfPddmIc5G6bioVnaZvaH313_M7ijr-9m9k2B5iC0qaykcGjxuQyFCZO0hSKvujGUBtScszhkVqB8atfObgOa26n2bTfn8JKFBCqEr5UNwPuGgMPAVVMcAZTn2nP1kKVem3RhmC_-6tvxmuB7azs9wmbqXniHxPhv0pPPvGVxHmgbFvKI1qBW-o2u2pxeVhkMHma3Ywf__h6g4-bvvsvj7f3dw8fhwURlv__FKEgBqfpCoyYv1C35M6rKNRDsikN6FsL2V393Tw7UCWUU--lNpRAtio-9uMg7TGQTyV3_Cl06TpSHtE4SkNX8OjTXmHg_xthwFJOv02nn2m_x2gpbC35Cy2NWIFpXQ795MQUu-uwe9x69HYeXI9vimjIz6CWfOksqrM1dyuBhBXIV9VUBoMELekVmJWAtU3a7gRV5mnbpNRr5Qn6wpdGTfX7vRSzw36_19-kdZiPCRnqMo6bBTgqbLtpKl_YGuAiyV3QDS7C-IBa3ZgC_MbytY03t-TO8eCDLUwptwtQewGCr7OF-lbrbI9Q1QilTU83jrV0rra4fX38tRBu2eS9QleEzT6Lwmir526qffFvLVTGCJvlUueo1NAbtZxYU8QYLmrVB3YY0iULw-ulKGyyW1BM5rHob3tVGctwHeLJJv3-1SE_iL_hILJ6V4z1z37-AZZvkugqqu0tuedooZjyi5orBsSEjUOlpyu_6bZ-V3FnxHPcgjuShWjiHYfyN6G-GL3oRhM8gUPC0voMVy_05GdHyXmnZF8p4paGGuAmTPlpID2_UlSgrK_bHWPdAS3-LUBj8vQrAz2adeHR_1koUTXVzi8obaQoLG393d9F4ZqFchNmayn1Gi_S7WvKHuSXO7_OfPDj128YfyDdfPehtGXKwfXDifv2f3Tw-GBrc_YYiCXtxFaDrfvhBezuxj6eU38NIVYFytl9k2yNeZI-0fmgen_yjdTZpfXRzgELKUA5X7QKNSsvxLewTeglDWliVDeGf9Z3XUzoH9---HZIILcpfMQlTwKzYFa-IHwU2IMfpSztsx-C2HH-HdBPX4fvXXq_jjLRBgrjMHWpuFv2lnu5dpsN77tW-0MmAOXS6terNIPrzS_JtH0Rw_56l_dBoaEV_qy8yspRNuJncNW_YP3-YHR5np4try6LvLwYMs762fCinJ8PWFoAnM_7owFcZGV2Jq5Yys7Ti_6wPxpcsLR3PszzwXwwYkVxcdGHETlPoeJC9qRcVT1tFmfC2gauRqN-_-JM8hyk9S_jMFaB43mzIIwRXy-Jv7qTbLx5MyGOhJc7DqbFX503A9qRbNzOHUzPzBWCSPJmYcl5KoV1toPlhJNw1b3xs_v2gU88WtOeNUZevWLY-FqAZ1Yb_X9QOMJmXm60aBB9dcX-EwAA___zAqFY">