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

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

## DirectX

| DXIL Opcode | DXIL OpName | Shader Model | Shader Stages |
| ----------- | ----------- | ------------ | ------------- |
| 83 | DerivCoarseX | 6.0 | ('library', 'pixel', 'compute', 'amplification', 'mesh', 'node') |

## SPIR-V

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

## Description:
  
Result is the same as computing the sum of the absolute values of
[**OpDPdx**](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpDPdx) and [**OpDPdy**](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpDPdy) on *P*.  
  
*Result Type* must be a scalar or vector of [*floating-point
type*](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Floating) using the IEEE 754 encoding. The component width must
be 32 bits.  
  
The type of *P* must be the same as *Result Type*. *P* is the value to
take the derivative of.  
  
This instruction is only valid in the **Fragment** [Execution
Model](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Execution_Model).

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

<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>209</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>P</em></p></td>
</tr>
</tbody>
</table>



## Test Case(s)

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

export float4 fn(float4 p1) {
    return fwidth(p1);
}
```
## HLSL:

Returns the absolute value of the partial derivatives of the specified value.



| *ret* fwidth(*x*) |
|-------------------|



 

This function computes the following: [**abs**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-abs.md)([**ddx**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-ddx.md)(*x*)) + [**abs**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-abs.md)([**ddy**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-ddy.md)(*x*)).

This function is only supported in pixel shaders.

## Parameters



| Item | Description |
|--------------------------------------------------------|----------------------------------------|
| <span id="x"></span><span id="X"></span>*x*<br/> | \[in\] The specified value.<br/> |



 

## Return Value

The absolute value of the partial derivatives of the *x* parameter.

## 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 |
|-------|----------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------|--------------------------------|
| *x*   | [**scalar**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-intrinsic-functions.md), **vector**, or **matrix** | [**float**](/windows/desktop/WinProg/windows-data-types) | any                            |
| *ret* | same as input *x* | [**float**](/windows/desktop/WinProg/windows-data-types) | same dimension(s) as input *x* |



 

## Minimum Shader Model

This function is supported in the following shader models.



| Shader Model | Supported |
|------------------------------------------------------------------------------------|---------------------|
| [Shader Model 3 (DirectX HLSL)](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-sm3.md) and higher shader models | yes                 |
| [Shader Model 2 (DirectX HLSL)](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-sm2.md) | yes (ps\_2\_x only) |
| [Shader Model 1 (DirectX HLSL)](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-sm1.md) | no                  |



 

## See also

<dl> <dt>

[**Intrinsic Functions (DirectX HLSL)**](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/eJzUWUtv4zgS_jXMhZAhU7FjH3xQ5Hg2QPd2MGnM9C2gJNrmhiIFkkrs-fWLIqlX20l6eyYzWSGIxVc9vioWqyhqDN9JxlZodo1m6wva2L3Sqy3VfygpLnJVHlcRRrNrjGZrfFvVglVMWozm8faZl3aP5jEuBJU7nDdcWC4RyVCc9ms-cfn4ynT8zO0exvfCiAcurebS8MJMYOqIUFqW2LCK4mLPikeDt0qP6VoF7QxG__Xp_tO1Z7BpZGG5khkVAmZxCbPuWUXdTC53k6KuzzErVMl2TL7E6KbidsDn5lDrnn72S-h-i7hlxppA0QGDyAb6ENlkqmS_MAk8ENkEvAwiGy_JBBB7EaRX6ILugagT8nZANGJaK23O0s40o5Zhu2dAlEv7UB4eelQ62wUIbjtbrrlmhf02seXrJNffbj99qT_TuuZyByTV9iwnqzD0L5Ieb1j6Jv2Am_cDKsu-7yGo7Yc8dp6wEE_ViUkQ2QSdENm8DZOpn34Ip_u7219_O6PFrcRu6FYaqxvnzfdMsMIqDe6FizNaAiehnpnmcud0rWiNMbfBJc6J5fbFC3xQkqIkNa7VCYzm8eSc6kAk-g3ntHhksnRw4oIa9gakjjciG_C9qI8EvcOL4JLwRxJEEtxawfddZRj8AH-pYXfhQfvftPLt-z0tmcafVcnEsOPe0h0z0BMIRf2D32ifdkQDQovEC8I0f8oU1YZ9cx3zSex-EVkgciV4rqk-InKFCPRd1fzARN8sVFU3lvUdtKoF3_KCgpX67oqZfd-SqvRLlq1AHXLeRl0XmPBLvfHeMFsjsthbWxswO9kgstFsx43Vx8njXiupzETpXTBZBDYzNXOWaiTfclZOW3NO9rYSiCQdbbIEmiMbMlNoXjs93BDGKE5_ZaYRFnPj3NqA_ajBHgZwadfbVBAi4JXmRonGMvxERcMMVltgMLtGJEUk_VKv78qDf38f7Tz9pY8qI7bHd2Z7BLZKYkTSO0TSiUPP_UOkRfHrsWaIpLhqjMU5wxSbggqqsdL4ye1vF2qd3FuhKCAc1YpLi-LU-sXvocAm8AIVGtOa9fbm5gZfzS4xk4Uq4YDGX_fM2V5JSD6cJzllUJzmDCcE59yageowH-R2anlgOuWH_nQC0aSbHjzP-RO2CoCgj351CXuZWv4E9EdcORwbXfAEGkqKIxDhJUQ_F6KdP2w03UEm5VuA_c2BFY3bBXHq4tN7IN4xefAsyHISNuPsOqM1zbng9vgenAfUXQwIHopI6kNw2CZemCSzNBcMJTe-VSix06qphx3Y2CNMWSNCfGxJUkxiRGaIEAxC_z9PRmRzorTdM1r2LT0YQMnN70qXOFONtH656xyM-1Px_JjfBOalhUxTWb4wetILLT1qjcWGmuKsEiVUBsZ4dJz9c6GKR7yngu9kJNjWup20k5FVNSLEcwd8Lj2nupen_Evoknj5KmUUpz9NGyUZq-CXzIVFyTUvEZnv4M0z8oNJluuRY7juYdAaTX4PEFCSURSne822fjkiiRfgtuwmDsV6SyNENvQtcf8pZO9-DM9TJx-5NXQMAlg8zni-QkKcUcMQWRiIhm7QHSN-Bky6OUCKx_AURuex_3NlWRwicnkocChfIJd2NRuOvmLB84f5wwJHTIIM0XSecxvBcWhw9CUk0OxQK22xO-0v8VYisgjv9dTni9fuWMNYM9toGTghsnDjgCXkt-uhdL2Grrxs87xfHQFzJk9rs7eaasupGBysph2CY8UdKH7FZASnS59TzeAU7QVEJPW53rJPw6PTp8-IO_jbM3wb7gxCvsm87FslhHqGdCVJ-ySP5ublDG_H7b7JJ4WCguczL7QyamvXyp2Uz1wmBCp7oXIwp-8tmXm0qo6MLoKZXY2TlM72YPVop2m954WJXKVEczOpSrAJWXRSla-lu3-HVGV56KXqDOJsQq4_PnqvZO1_D3rH8-hNznlpm2aapoZNzVyq6QpIbFxuZSaj-HNHNa2YZdp8v5tuLatCudoVZa9uoh96_oelfd2MkszUVGJe-iPg0IV4l2xS6RujOd_OzQnwQbj30d6X3bMMza65dL9rV2CchJrxkjPBIuDpAxz-DVa19vmJUBckhSnePGOrwWE_Kpa_s5274wi6BT_-yqpaUMva6uYf9OjuPidq3Tbsu7HEWVfkfXSR7_kf7GRr_IlN8rPPX8DyB0gM9mXw0u9czV8ofFCD-eswEM3fdgQxSYaVDgMVtZof2mp8qJlLi4aKeYFL9TwQEpHN71zeabXrR6OSWurzrtZpqDziV54RyiGtgVZ7XcFl3djOAu8mpWNX8opJ4y4XXZJ6lv_LMfEzl7xqqtGF6wtn1-jYGiVa4fjCFaw2J7nf6WVuR-lPn1k_s18G5ptdj4RLMCKLcFntk2Oy_Kd2iamSEMaoLPGe7_ZMj4F2WB6Zec0_v1OQfCgFySBOgx5QtRg0yx4I_Du4bGlUHpzoM_1Q-kwH-kj1Ytw4vxPvGcNUGNVdrZXCZTRJVtq-Pm3jSPdxB7cfTs05KD5onG-Lb6cZDu-g7kW5SsplsqQXbDW9ItPpPI6T-cV-xbbJ_LKIrxZskU-3cVnQaTGdLxeMxPF8XsQXfEVichlfTeckhjUTSuL5nMxLyq7IFV1M0WXMKsrFRIinaqL07oIb07DVcjkl8YWgORPGfV4npGKW5s3OXaFkiJDwhQwlafc5MYx4nE-mtbet7YCyKEnbubP1hV6BEFHe7Ay6jAU31vRiWW4FW_Xf8E--FwKhzuwXjRarV2wbvuI5frVW_2GFRWTjVAejeu2fVuS_AQAA__-XEIM3">