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

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

## DirectX

| DXIL Opcode | DXIL OpName | Shader Model | Shader Stages |
| ----------- | ----------- | ------------ | ------------- |
| 7 | Saturate | 6.0 | () |

## SPIR-V

# SmoothStep:

## Description:
**SmoothStep**  
  
Result is 0.0 if *x* ≤ *edge0* and 1.0 if *x* ≥ *edge1* and performs
smooth Hermite interpolation between 0 and 1 when *edge0* \< *x* \<
*edge1*. This is equivalent to:  
  
*t* \* *t* \* (3 - 2 \* *t*), where *t* = clamp ((*x* - *edge0*) /
(*edge1* - *edge0*), 0, 1)  
  
Result is undefined if *edge0* ≥ *edge1*.  
  
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>49</p></td>
<td
class="tableblock halign-left valign-top"><p><em>&lt;id&gt;</em><br />
<em>edge0</em></p></td>
<td
class="tableblock halign-left valign-top"><p><em>&lt;id&gt;</em><br />
<em>edge1</em></p></td>
<td
class="tableblock halign-left valign-top"><p><em>&lt;id&gt;</em><br />
<em>x</em></p></td>
<td></td>
</tr>
</tbody>
</table>



## Test Case(s)

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

export float4 fn(float4 p1, float4 p2, float4 p3) {
    return smoothstep(p1, p2, p3);
}
```
## HLSL:

Returns a smooth Hermite interpolation between 0 and 1, if *x* is in the range \[*min*, *max*\].



| *ret* smoothstep(*min*, *max*, *x*) |
|-------------------------------------|



 

## Parameters



| Item                                                         | Description                                               |
|--------------------------------------------------------------|-----------------------------------------------------------|
| <span id="min"></span><span id="MIN"></span>*min*<br/> | \[in\] The minimum range of the *x* parameter.<br/> |
| <span id="max"></span><span id="MAX"></span>*max*<br/> | \[in\] The maximum range of the *x* parameter.<br/> |
| <span id="x"></span><span id="X"></span>*x*<br/>       | \[in\] The specified value to be interpolated.<br/> |



 

## Return Value

Returns 0 if *x* is less than *min*; 1 if *x* is greater than *max*; otherwise, a value between 0 and 1 if *x* is in the range \[*min*, *max*\].

## Remarks

Use the **smoothstep** HLSL intrinsic function to create a smooth transition between two values. For example, you can use this function to blend two colors smoothly.

## 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                            |
| *min* | same as input *x*                                                                                              | [**float**](/windows/desktop/WinProg/windows-data-types)                        | same dimension(s) as input *x* |
| *max* | same as input *x*                                                                                              | [**float**](/windows/desktop/WinProg/windows-data-types)                        | same dimension(s) as input *x* |
| *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 2 (DirectX HLSL)](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-sm2.md) and higher shader models | yes                 |
| [Shader Model 1 (DirectX HLSL)](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-sm1.md)                          | yes (vs\_1\_1 only) |



 

## 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/eJzsGtty4jj2a5QXFZQtBwIPPBASZlLVt-pke_stJdsHrI0seSU5JPP1W0eysU3IpXt6Z7NVQ1GApKNz17nIcGvFVgEsyOScTC5OeO0KbRYbbv7QSp6kOn9cjCiZnFMyuaBXZSWhBOUomUa21NoV1kFFphHNJFdbmtZCOqEIW5Fo2e37INTdK1voTrgCYQpp5a1QzghlRWbHBZlGA2TLPKcWSk6zArI7SzfaPMXtNM6tEOL3D9cfzgORda0yJ7RacSkRSiiEuoaSe0ihtuOsqo4RzHQOW1AvEbsshevRunyoTEdj9Vsz_RoBB9bZBqNXEGFrnCNsvdI5_AYKaRC2bvRmCVt33IxRe88q7AXcqIMGsWf06gDxCIzRxh7FvzLAHVBXACIWyt3mD7dDDe3t2ajjam_fC2Egc9_HLn8Z7cX3qw-fq4-8qoTaIkq9eZaa0xTXzjr14-6XSQytOg7-wVU-nL9t1BCWgz4DBSnvyyemImzdyEfY-nW12er-zXq7_nL19dsRka4U9UtXyjpTe2-_BgmZ0wZdj2YDqkNqUu_ACLX1cpe8olS4xl2eY8-fn2fokWRJkqX1oz3jZBqNj6kBkYy-0ZRnd6Byr1qacQuvqNfTJmyNfjnqosbwUMjGZfHNEsIS2lolzJ2tKDoI_VzhKaS98SdehvF1wXMw9KPOQfYnrh3fgsWZBtGoe9FXxk8nRj1EZ4EMd7VB_eBgOo78N2EzwuYt7F6ooML9FL32GrhGWyXLofhgMyMqNFazxPDd2-DHlJIofHwFW0tHhaXROKJiQwlbPiAEuWRkNifLU5yBfAsRzqL_xMcBJy1g3AJWYDbalJZEy2Az-juYUjg0vQNTacmRUZqC2wEoGo5lTHcFqAFVMlmRZNVR9MMgXEtwTG8KYVEO-Hct7rnEXOY0SXqyErZ07X78OhzOEjqi7GCZsDlhK-TJQLclucAkV1bBYrOWs1GfbW9JtvaEZ33dHEIh_gg_YtxyxDS1ymEjFOSN3jvFHNP9uENxUwDVFRiuckvL2jrKpaQpUE5txiU3VBt678803RXaAs10WWnllfdYARVovI3U3Am1HVVaKDceKLRh8uaxgtbsGIH8Zr3x5IYMpCFEWTx_CDXeS2opN4GB2oH3no6bcePlycrxVAJJLsMo03JrdF31J6h1jwhyQRjbidwV6AQsImxCGPMW-X8GJmz9RGhXAM-7kektkOTyU12mYMJWP9Fb-xxsQ-OXl9nLy8nLy6dPlnFkBqOhBFidHpUnx2NnbVCUd4VU6uyOFlyKrRpJ2Dh6H347XRHGcGuyQlWdzgOpKkwh0R7FnETLn0ZNkhWU-M2m0pHkXOSETbf4KxAKi8kqNQNT-ulwlgdg75PJ-L0z-fBmBo_MPvXIgQ_iRC_wRMOse4M1zYpbIGxmMaD7RR8mAwQCXT5wbLJojKvTKLx91Y141oSt84eM9ipSLIl8WU5HN1SK9HZ6O6MjUMjHKJ6mwo0wgFo6-tzUQPBQaeOoj9endKMImzW_qxjzSztg_UESKo5zH9QpNeBqo3p8EDYLu8M2D4_2wGLmoi9Lpw_fb7SVyVeP0GLK-YEiAEn1igzhq3FMHIarLfgcPTknbFliT7pEaBxwBPZrF-OBnXxttTTgs_dAtmdwsH250SvIzlajt7y68m3vB51uvnDDS3Bg7CGDVw5K-rMvX9p2xd-P7_4B-V4S_M_tbk2VrGzFFRV5iCHeQGx_bHEtDAZQH68-HYPa2xejRggaodb2LiRUcBeKpVIplCjrsvExvQnNVOOCVWu48QGm55hGR3qd6eX3Z5gOfvgGpvnDr2P6LSw_w_Ahu51fHmHaVpCJjYAcE0EN2Ium_YgA-TGGj5-oEGDoN0Q0DDnRQQiRYC11BffdResV5zQ-ANv6xtV0kI0pzql2BZidwEC_orzh_bB9-SVhqxWt5OauiRT_sNDalrBlP4j5lg6Dbu9aYdPciKFqm6uBfQR2hisrBmHX7XQQx47pWhsKIVshh4-6phlXtPb0hR2gTqVv6neaZlpqYxsS8nEoCPYHg-b0IPb5drxxlvMg0A2UFXpC21t4FV0QNiucqyymF580t8IVdTrOdEnY-qPIjLZ64y60vyrYCZUwwtap1Ckm2DCbg71zuhpZkzWJ118aJLnPxpiHR1vDq0JkdjS8fhi1ottxmftm7Wfi9F7E1b7Zes8y-tsK8Qf8QP7405nkp7LHX4CiFzmbI35g0tBWv1NTNvGGsGXo-Rs22Ypq0yyU3Bnx0ISUgWS-XuwLFhjO9a7HJGHrfwr1xehttzrKueOhVH3hyCAtrh7fVKV04dtv83cJHENtVbueYf6Lr79aM17EXJSgLEbP0GY8lXmoIf7wt4Ze1FDTD_ytoSMaOl5rfWwq5P6teQC4GVQGwlJbV9iNQt6WQBstpd4JtaU27C5xt33SqA1u5H-dqq_3_Azmf0Xf82PppOeCk_OBsIwSNmueYIQmms3_V0nElqzJ_1jVFmJbgBkazmv1EewxbT8jYPyuBIxfK-JaAQmb3VsyWd3G_oNqJR-Hz2mOHJVrAMql1fub61z6ViZZ5a67RmrP__4xGm0fZdtjunqndUV7R-Ylo81vFPckXyT5PJnzE1jEZyyOp1ESnZ4Ui3QyB5jHcRRNo7MZzOYQx7N8ns6zM5hONumJWLCInUZn8ZRF0SRKxulsMoVpEmdwmsZn6YycRlByIcdS3pdjbbYnwtoaFvN5PJmeSJ6CtP7PD4yV4Hhab7FvZSvCWPMskiTL_UPcZiXo-QlY8wBuv6AdSZYt7OTixCyQiVFaby05jaSwznZsOeEkLLp_WBx9Quu7t9b0J7WRixfs2zwz9TQro_8FmSNs7cVHwwYN3C_YfwIAAP__IgV8dQ">