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

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

## DirectX

| DXIL Opcode | DXIL OpName | Shader Model | Shader Stages |
| ----------- | ----------- | ------------ | ------------- |
| 56 | Dot4 | 6.0 | () |

## SPIR-V

# FaceForward:

## Description:
**FaceForward**  
 
If the dot product of *Nref* and *I* is negative, the result is *N*,
otherwise it is *-N*.  
  
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.

<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>70</p></td>
<td
class="tableblock halign-left valign-top"><p><em>&lt;id&gt;</em><br />
<em>N</em></p></td>
<td
class="tableblock halign-left valign-top"><p><em>&lt;id&gt;</em><br />
<em>I</em></p></td>
<td
class="tableblock halign-left valign-top"><p><em>&lt;id&gt;</em><br />
<em>Nref</em></p></td>
<td></td>
</tr>
</tbody>
</table>



## Test Case(s)

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

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

Flips the surface-normal (if needed) to face in a direction opposite to i; returns the result in n.



| *ret* faceforward(*n*, *i*, *ng*) |
|-----------------------------------|



 

This function uses the following formula: -*n*  sign(dot(*i*, *ng*)).

## Parameters



| Item | Description |
|-----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------|
| <span id="n"></span><span id="N"></span>*n*<br/>    | \[in\] The resulting floating-point surface-normal vector.<br/> |
| <span id="i"></span><span id="I"></span>*i*<br/> | \[in\] A floating-point, incident vector that points from the view position to the shading position.<br/> |
| <span id="ng"></span><span id="NG"></span>*ng*<br/> | \[in\] A floating-point surface-normal vector.<br/>                                                       |



 

## Return Value

A floating-point, surface normal vector that is facing the view direction.

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



 

## 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) | vs\_1\_1 and ps\_1\_4 |



 

## 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/eJzsGVtv4yz219AX5MjBdS4PeUjdybeR5qZpNfu9VdgQmx0MFuBevl-_OuA4dpqmndlvtV1porQxnMO5c87BUGtFqThfofQKpdcXtHWVNqsdNX9pJS9yzZ5WEUbpFUbpNd7WjeQ1Vw6jWbyjBd9p80ANQ7MYF5KqEuetkE4oRDIUrw8LPwr147U1-EG4CpAqaeWdUM4IZUVhJxWaxSNqa8aw5TXFRcWLHxbvtDlB3GmYzADlHx9vPl4FLptWFU5olVEpAUsowLrhNfWYQpWTomlOcSw04yVXZ7l9qIUbMPvw2JgDk-yPbvo1Do5bZzuK3kSIbGAOkU2mGf-DK-CByKaznEVkMxBnAgZ80WZniIMVOspe0u0x5Ygbo409ySAznDqOXcWBslDujj3eHRmpd2pnkW3v5GtheOH-nDh2nu71n9uPX5pPtGmEKoGk3r3MzmkMwHR28AGsP8_kyLeTECZUsSPAXWeLAA9WDTykvK-feQyRTacjIpvXbWeb-7cb7-br9tv3E1ptFfagrbLOtD7sb7jkhdMGQhAXI7ZH7KR-4Eao0qte0wZj4bqweVFAv5Ve4IiSNUrW1o960dEsnpyyBBCJvuOcFj-4Yt66uKCWv2JhzxuRDcRndMggR9tDdrELX5IgkuC9Z8LcPMMQJvhLAxsSD8afaR3GNxVl3OBPmnE5nLhxtOQWZjpC0eGDXxk_n4gGhNJZEES7S_8wm8T-F5EFIss9Yq9RMGA_hTe04JvOVcl6rDy3hREN-KoDEfgOV_gJjFG8hr_tzocM0w43RrO2cH4XkvVnw3eA6DcLWW_hWViseEmduOeIZH6h4baVDiCwxhMH4bWruHkQ4OQ9MALoJDCGf7cVx7rhhipmcd1ah6mUOOeYYltQSQ3WBt_7cMMPlbYcF7putIKK5Z4ajoVF8XonNXVClVGjhXID8oisvwXZbp8avtcERPaL9c6zGwuQh_1jITIAa9LZNskczSVHyYcwKrQsjW6b4QS27glQrhEhD4K5CiVrTGJEUkQIhjzx_4yMyOaZ0q7ilB1GZgBAyYfPbZ1zE5b6iQHsS7A6np4Hk_Pg5Dz48hkYRmY0GmsADdJJfRg0N9YGQ_lQyKUufuCKSlGqSPKdw_fh2ekGEQJLkwxMNY8DqyZMAdMBR4bi9S-TRknGa_glM-lQciUYIrMSngKjAEyy3Ixc6ac_j1Hen4Db9y6gz49vlfHE7PNgHIUfTAxyTjxO87dQQzNqOSILi8gyAENO9xiA9OGRQouPpwCdxeHruz2gs0Fkwx4LPOyCoAb7fhBHt1iK_G52t8ARVyBINJ3lwkWQFi2OvnQ1lz822jjss_Al3ilEFt1zM4USsR-Q4SAJRe7Kp2qMDXetUUNBEFmE5WGdXwBOgep5PdTmYBHf6u6L4UaKxoZU3hqgGyltaiqhwIodVpwzzkAIpz1b6EQoZr5xEFph3TTaCuimNBYouepEtKOKp7CajFzjC_jacAfFZqwNImsVaiOgiMMjdOzrQc2fZ9Hrn0N_0Lvd11Nh8a47EeHW8iDuTkupH6D322lTt5JCjo86gTCGEyMiC6ZdEPOEbIgsJ6Po-0oNrbnjxh7rv3W8Dq3NoQ_5KdXOqPwfrP5lnnu3JpltqMKChSyj-iyCyAYgYTDC-XwKpwsDyCghoUD8ew5phtIrofzvNb7t48w7btTjHMd0aJEmQ6IvSy7eIPn2tOTiSPITYq-PRIVAEqoQDHq2rpVzFXXYQy3eGV37IL0X_AH7PQcB43TYuxVloP5-_o0qQti-7p0_XnBP-fNavsEhv_Y5vc-7TfgtZM3vVLY8AE5ZvxMNj0QLPoBsQQswcO-BPgOO9zs00KOTxdGu9yepzlJX4Xxxy-tGwuGva77hm14jsqicaywkal-ASuGqNp8UGk6An0RhtNU7d639Me9BqIQgssmlzqFYhVnG7Q-nm8iaoitiXuiE-coGNS0qDW0qUdhofHSM9snRTmrW5dyDxFl_uHjvIt-Iv_izpPrfSpB_A903kBjs5n1hGnsnBO579kovqt-EQ0mDBEw_DLgisvmnUF-NLg_QiFFHQ4O1J0rV0xsSxLzvKn6bzRP1B3gmaq4spKvQI2NqsVBN6_oYG0ddGV6L_Dbfkfnsc8MdRV7X8v423c-Y7nRV_ySUqNt69E7yVHsvLLZtA2cvzuAoMu70bVhdw2r77JDy_H1nT-nvaNV_oQ4Moim9GolH4MjWvdENZzyy_F-Fk61JFz5UMVyJsuJmbGpvzSduz6fqIxWn70rF6WCH3FuUZndT_8_r3BwmLs_H8Q3nmEqr-xeoTPpuOsmYO7zS2O_A_goB72_07CmjvM9k0r-v8Zrh7hnUvWCrhC2TJb3gq-mcTKfpcjGdX1Srgsynl_k0nhfLYpkvFrNZOl3s4mKXp-mCJvMLsSIxuYzn09l0mc7S-YTSecwu42XBlyyZL1N0GfOaCjmR8r6eaFNeCGtbvloup9PLC0lzLq2_Biak5o7mrT8UkQwR0t3DoGTd32F1kGDnZ2jd9UMP0A4l6z1uen1hViBElLelRZexFNbZg1hOOMlXh7vm0_dTQK33_UVr5OqMg7sLI8-0MfpfvHCIbLz-4NlggvsV-XcAAAD__7paBYg">