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

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

## DirectX

| DXIL Opcode | DXIL OpName | Shader Model | Shader Stages |
| ----------- | ----------- | ------------ | ------------- |
| 118 | WaveReadLaneFirst | 6.0 | ('library', 'compute', 'amplification', 'mesh', 'pixel', 'vertex', 'hull', 'domain', 'geometry', 'raygeneration', 'intersection', 'anyhit', 'closesthit', 'miss', 'callable', 'node') |

## SPIR-V

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

## Description:
  
Result is the *Value* of the [invocation](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Invocation) from the active
invocation with the lowest id in the [group](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Group) to all active
invocations in the group.  
  
*Result Type* must be a scalar or vector of [*floating-point
type*](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Floating), [*integer type*](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Integer), or [*Boolean
type*](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Boolean).  
  
*Execution* is a [*Scope*](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Scope_-id-) that identifies the group of
invocations affected by this command. It must be **Subgroup**.  
  
The type of *Value* must be the same as *Result Type*.  
  

[Capability](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Capability):  
**GroupNonUniformBallot**  
  
[Missing before](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Unified) **version 1.3**.

<table style="width:100%;">
<colgroup>
<col style="width: 16%" />
<col style="width: 16%" />
<col style="width: 16%" />
<col style="width: 16%" />
<col style="width: 16%" />
<col style="width: 16%" />
</colgroup>
<thead>
<tr>
<th>Word Count</th>
<th>Opcode</th>
<th>Results</th>
<th>Operands</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p>5</p></td>
<td class="tableblock halign-left valign-top"><p>338</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><a
href="#Scope_-id-"><em>Scope &lt;id&gt;</em></a><br />
<em>Execution</em></p></td>
<td
class="tableblock halign-left valign-top"><p><em>&lt;id&gt;</em><br />
<em>Value</em></p></td>
</tr>
</tbody>
</table>



## Test Case(s)

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

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

Returns the value of the expression for the active lane of the current wave with the smallest index.

## Syntax

``` syntax
<type> WaveReadLaneFirst(
   <type> expr
);
```

## Parameters

<dl> <dt>

*expr* 
</dt> <dd>

The expression to evaluate.

</dd> </dl>

## Return value

The resulting value is uniform across the wave.

## Remarks

This function is supported from shader model 6.0 in all shader stages. 



 

## See also

<dl> <dt>

[Overview of Shader Model 6](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/hlsl-shader-model-6-0-features-for-direct3d-12.md)
</dt> <dt>

[Shader Model 6](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/shader-model-6-0.md)
</dt> </dl>
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzkWV9v2zgS_zTMCyFDomwnefCD7cR7Adrtoul29y2gxJHFC0UKJOU69-kPQ8qWnDhJ93C5fbgiaMThcH4zvxn-DXdObjXAgsxWZHZzwTtfG7uouP2X0eqiMOJpkVAyW1Eyu6F3TaugAe0pmad_8B18BS4-cQ0baZ0n85SWiustLTqpvNSErUm6HIZ_kvrx50bSH9LXqForpx6k9lZqJ0s3qck8PbG5FII6aDgtaygfHa2MfRXCG-xao-I_Pt1_WkWsTadLL41ec6VQS2rUuoeGB02pt5Oybc_hlkbAFvRPYN420o8gb_etHaDWv_Ti93A8OO96i4EuwjYoI2yzNgJ-AY0YhG16Fh1hmxdOTZDSV1l8AwIZ6e0Hf-_O20_AWmPdWZi1Be6B-hrQvtT-QewfztJ2THnP0d2xBG6khdL_OfHibes3f959-tJ-5m0r9RZNmuo9UG8oqmTZ1ZAcNPM21tnUT2ItcS3Odj_0JEWtSHrEU2rXvEgrYZs-bMI275Pq2t1fZfX-t7uv38_Eeadp6LrTztsuzJN7UFB6Y7FaaXkCfhZUmR9gpd4GMhreUip9X2HvOBvm4SvoJF-SfOlC6xgGmaeTc9ygkeQ7LXj5CFoEvmnJHbzDecAmbIOlnAyL0NlZpfpixx-WE5bTQ8ai7HJNsZTolxZnMx21f-VNbN_XXICln40ANRbce74Fh5LeUDL8o--0XwqSkaEsuwr9L8IJ0vkkDb8JuyLsUsnCcvtE2CVhKLssTdN2HgYBb1olK1lyzNMgbsDVQ6uVe1BDcwfWw35o150a9QrTcDkytQXTgB87YfnTFjTYZ5hSe7AOylMp10-19KMIlHHg_Imskc6NNLhSvFCjILURsXV94PGY8FhlRxEW4Zf2F2u69lejf9eyMrZZWcNFyZ2PZT67Ieyq9r51WM9sQ9jGwlY6b58mj7U12riJsdu-FhMsRtdCKMFOy0qCyA51Oql9owjL34Nk1wh1UqjgSivbwFXoopSky6_gOuWpdHFys-V3rjogbIkLaRDNVlLvTJ_uD4jkbrDOrmllTRNweenlDki6HNDjcQE7cbFxnkqBU7v3cot8fISDgWj0zRvKlTrnmTv4EZyYBGbDf4QdGP721AZam855WgDl1JVccUuNpbuw1oWta7YibFkpw73U26Q1UnuSLn0c_BHRbXosrBis_eAATqwtWPqBuHcRoofFo1VAXhmjgOuPjfkAwq5PU3W7h7KLlbjEKcF7p-5L82G-BNsPiRRJKLGaY1mD9qjthpqipnpWcbyqoPQgaPFEfS0dLU3TcC0m9M4fqwydZsv7roizI7RGMX-rIeQ4lN5o7h-GI7zDjYs7-qKUx9ylSzJbrXnLC6mkf_oIokbWw-J2SBphy-dLIVfK-Ng18nG2-iydwyNKAZWx8BFO_h7lYd8I-DuwDpeubJL37Pd05WuPWw51_kkByW8IYz-k8DXJl1maEjYj-YowRvLbqF0aFXM4EpwbTLM5DmaMYkT_N8qEbV4w5GvgYmjZUQfJb_8wVtC16bSPw4Nw1B-PcOf74kRwrw0Ey7V4pfcnpdiyJ63TYPDKfjY0gVds5yJnocQKZcpHWnMltzpRUHm6i9_etH2F5WtkbRaR2sEf8V-xm-dXb1om6fI_tk3yNTT4m82VJ_lKCsLmW_yKQLEzXxf2pFyCeLycnSh_BAkkX3OSLmsLVRxOWB4duBNHxbFb70VE2Ib_b90db1Vjh4P8L_h7LhfD1vuTmfi7iibukT_l5Ms5fDJrURBuHVGQnh7Xv-EBd80dEHblcMcLnWE3ixqodLvH2xjQDHvnafwJTzJpv6GJffny3veAd-DwdEOTb1TJ4mH-cEUT0OhOks0L6RM8FjiafOlvu7BvjfU0nEyntNKEXfXfbRZvSauw0VJqwXdWvwQl7CqoIst4L70Z-zzEHd6eDleXr8FWPAbtkPjDrQT2rQUXdtbK2NGFgSquj1plZy1oT3_wHQyXB9dwpcL1QQvYT04vd0_a830vOjhH3VGar8OxNL89G188aqwZWaYjTfQ1IBxCHwd9RP6NW94A3mePBwShcDh--KFG2DLYY6EUYhWF7qAnjnrfTknyhgISyD0MBxAcKvqh-K1GKMGnSH9kfjBrw_qE56iYEuloFw9elJfWuJgu5HzyzFrD7aM7GJKOVv2bLJpwXYsVBiJeAV18FGnCK8l8Et6J8PLVy114LJnQk4kTiT9JJwDlypm3KZ2tvuzA7iT8wMI5eZ-ZnzskbqWvu2JSmoawzWeJMZvK35hwMvwhdc4I2xTKFEhqlApwj960ibNlPy_Ds1EuwmTt355ibEmIOZknaVIB950Fl1TGJocRScYmjehXhGf5PwnqbwnkeQyvuXqotwuxyMV1fs0vYJFdsiybp9NZdlEvLoury2w659NpNr2GPCtgmk4vq-sSWMHzsrqQC5ayaXqZzVmaXubZhAuRFSUXlcgqkZaMTFNouFQTpXYNHuQvpHMdLK6vs_n0QvEClAt_EGGsAc-Lbhu2uTVhrH9CJPny-CDb98Sn8RdqhwvCocN4ki8PurObC7tAJ5Ki2zoyTZV03g1ueekVLIa_urz1zIo26eFvGRedVYs3Utq_eAbo1pp_QukJ2wQWMJeRiN2C_TsAAP__YHXgXg">