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

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

## DirectX

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

## SPIR-V

# Reflect:

## Description:
**Reflect**  
  
For the incident vector *I* and surface orientation *N*, the result is
the reflection direction:  

*I* - 2 \* dot(*N*, *I*) \* *N*  

*N* must already be normalized in order to achieve the desired result.  
  
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>71</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>N</em></p></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>



## Test Case(s)

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

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

Returns a reflection vector using an incident ray and a surface normal.



| *ret* reflect(*i*, *n*) |
|-------------------------|



 

## Parameters



| Item | Description |
|--------------------------------------------------------|------------------------------------------------------|
| <span id="i"></span><span id="I"></span>*i*<br/> | \[in\] A floating-point, incident vector.<br/> |
| <span id="n"></span><span id="N"></span>*n*<br/> | \[in\] A floating-point, normal vector.<br/> |



 

## Return Value

A floating-point, reflection vector.

## Remarks

This function calculates the reflection vector using the following formula: v = i - 2 \* n \* dot(i n) .

## 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 |
|-------|-------------------------------------------------------------------------------------|----------------------------------------------------------------|--------------------------------|
| *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) | any                            |
| *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) | same dimension(s) as input *i* |
| *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 dimension(s) as input *i* |



 

## Minimum Shader Model

This function is supported in the following shader models.



| Shader Model | Supported |
|------------------------------------------------------------------------------------|-----------|
| [Shader Model 1 (DirectX HLSL)](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/dx-graphics-hlsl-sm1.md) and higher shader models | yes       |



 

## 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/eJzsWVtv2zoS_jX0CyFDpmLHfvCDI9dnDbRp0QTd8xZQIm1xQ5ECSeXSX78YUtfYuWwPsNsFjmHEImc0l2-GMyOFWiuOivM1ml-h-XZCa1dosz5Q81MrOck0e15HGM2vMJpv8b6sJC-5chgtYsMPkucOLWKcS6qOOKuFdEIhkqJ409_0Waj7t_jxo3AFMBTSyjuhnBHKitxOC7SIR5I2jGHLS4rzguf3Fh-0eSHYadhIgfyPzzefr4KGXa1yJ7RKqZTAJRRw3fCSek6hjtO8qs5pyzXjR65e1fSpFG6g6NNTZXoF6R_N9nvSHbfONhI9NIjsYA-RXaoZ_4Mr0IHIrkHMIrJrTJkCaK_i9IZg8L6R6q3cD6VG3Bht7FnhqeHUcewKDlKFcnfs6W4ATBfABoV9F9CtMDx3f04de1vm9s_956_VF1pVQh1BpD6cV-U0BsJ80WMO976roMUuZANVbLB517geaAHAIFrKh_IkMIjsGrcQ2b0Pla0ePobVzbf99x9nHNkr7El7ZZ2pfVbfcBCnDWQZzs85CqqkfuRGqKN3t6QVxsI1mXHWMH9CXtGEkg1KNtavOpPRIp6e8x6ERD9wRvN7rphHFOfU8ndQ9boR2UEKRn1RGGS-bFITviRBJMFtJMLeZYohG_DXCs4ZHqyvaRnWNwVl3OAvmnE53Lhx9Mgt7DSCov6D31mfbkQDQfNFMES7C3-xmMb-F5ElIquWsfMogNdt4e9NiJLN2HFucyMqiFFDIvBtuf0CYxSHPzttfIIIlQsGxfzBRxUjstkDI2SIrc2B5hxrI7hyFCQD_drLSv3thttaOiwsijdh7bUBJ_OBCNZ4lcEkLz3CBKN5CpdMO-93J7bh8UgEloY4EOKXZW0dptJwyp5xxrHSpqRS_OQM0kobCKLTmOaF4A_hODBuheGsMXvaw3FbcKwrbqhithUsQSjFNqeSGqxNC9FjoS3HuS4rrQA591zxgMBBauqEOkaVFqoVHyz-HoC6fa54Cy8Y5O_VB69trD8LFltIU-CaNs4nqaOZ5Cj5FFa5lkej62q4ga17BpYtIuRRMFdACEiMyBwRgqFI_T8zI7I7cdoVnLJ-ZQYElHy6rsuMm3Cr3xjQvgbU8extMnmbnLxNvjghw8qMVmMPYOg66w-DwcnaAJRPhUzq_B4XVIqjiiQ_OPwQrp2uECFwa5ICVJeNj1XYAqUDjQzFm18WjZKUl_BLFtKh5EowRBZHuAqKAjFJMzMKpd_ej1l-PwOvP2zgh3dPwz8KOGwMTnk8rvS30D5TajkiS4vIKhBDsfEcwPTpicKgjmdAXcTh62c5kLNDZMee8rZe30Hr9ZMejm6xFNnd4m6JI67AiGi2yISLoAhZHH1t2i1_qrRx2Je8C3xQiCyb62oGZbxdkNDSrsA6w11tVKsUkWVg9TwQCWiP26G9vc9-TG073ncvx2I67DdNda5tGHD6zmbos6-3tGtooVNMR9D6_rsxHDrlwEJENqJvTKptTG0vj1779E28C07vzDdqaMkdN_alCXvHyzAc9N38A9re-fzyrf3MgpLUVoAqC6dPdKcLkR1QwmLEsz_H0-AJJy0ctDD6zFM0vxLK_27xBo9bKcD_YlKZvhDxip3qA3Zen7dT_ZqdIbnesPJ8ToScxj-orHkgnBN-ku_TF0JKau6brLothMWH5rEX51TmtaSOW_xiUBsdHKAdtJT6EVYHbcpaUmjFDxglWyyGo5saz3ACKzgbY4tg4BmNpi8SvhvD0fwqzKi3vKzAznZWgu98i8iycK6yUAN89ToKV9TZNNfw5PBF5EZbfXBb7R8PHoVKCDwrS51BpQu7jNt7p6vImrypgH5ETZgvi1AQo6OhVSFyG40fOaIWRjstWVMAeovTbhT83U2-ET_5STn5C4XlveLxXxAxOPqhtGA8jk5I7985Kp2p_rwPLQ0WMP040IrI7p9CfTP62FMjRh0NHboVStUzfuMzgk39DVsr1D9vMVFyZaFahQELU4uFqmrX5dgIvmZo-Bu-_xS-853wi1CirMvRi5lzHU1YbOsKptDwxD9uXTbcXcLd9mTUO33p00n6y9PWxwvaIIvmVyOTZhiRZfMqK8y-ZPW_SiNbzpq0gSm6EMeCmzG8HsFnbse15Xx0bzjHVFrdvc5g0s9GScpc_7jT5mb3ZhG37-_tOWR-z2PWPct5z3BzDe5O2Dphq2RFJ3w9uySz2SJOZvGkWM_YiiRsdrlaXS5nJM5onOUHsprHlwtO2HI-EWsSk4v4crYgcTyfxdMVW2YkJtmSJoyR5SW6iHlJhZxK-VBOtTlOhLU1X69WszmZSJpxaf0_eggpuaNZfYTpl6SIkOb1LEo23evshhJwPmFr3kx2BO1Qsml559uJWYMRUVYfLbqIpbDO9mY54SRf9_9NOn1dDZK6uE9qI9dvBLd5h-wVVkb_yz--7bzvENXg_sOa_DsAAP__8Y7N5g">