Integrated: 8325520: Vector loads and stores with indices and masks incorrectly compiled

Damon Fenacci dfenacci at openjdk.org
Fri May 24 13:42:13 UTC 2024


On Mon, 18 Mar 2024 12:20:34 GMT, Damon Fenacci <dfenacci at openjdk.org> wrote:

> # Issue
> When loading multiple vectors using indices or masks (e.g. `LongVector::fromArray(LongVector.SPECIES_256, storage, 0, indices, 0` or `LongVector::fromArray(LongVector.SPECIES_256, storage, 0, longMask)`) there is an error in the C2 compiled code that makes different vectors be treated as equal even though they are not.
> 
> # Causes
> On vector-capable platforms, vector loads with masks and indices (for Long, Integer, Float and Double) create specific nodes in the ideal graph (i.e. `LoadVectorGather`, `LoadVectorMasked`, `LoadVectorGatherMasked`). Vector loads without mask or indices are mapped as `LoadVector` nodes instead.
> The same is true for `StoreVector`s.
> When running GVN loops we can get to the situation where we check if a Load node is preceded by a Store of the same address to be able to replace the Load with the input of the Store (in `LoadNode::Identity`). Here we call
> 
> https://github.com/openjdk/jdk/blob/87e864bf21d71daae4e001ec4edbb4ef1f60c36d/src/hotspot/share/opto/memnode.cpp#L1258
> 
> where we do an extra check for types if we deal with vectors but we don’t make sure that neither masks nor indices interfere.
> Similarly, in `StoreNode::Identity`  we first check if there is a Load and then a Store:
> 
> https://github.com/openjdk/jdk/blob/87e864bf21d71daae4e001ec4edbb4ef1f60c36d/src/hotspot/share/opto/memnode.cpp#L3509-L3515
> 
> but we don’t make sure that there are no masks or indices. 
> A few lines below, we check if there are 2 stores for the same value in a row. We need to check for masks and indices here too but in this case we can include these cases if the masks and indices of the vector stores are equivalent.
> 
> # Solution
> To avoid folding `Load`- and `StoreVector`s with masks and indices we add a specific `store_Opcode` method to `LoadVectorGatherNode`, `LoadVectorMaskedNode` and `LoadVectorGatherMaskedNode` that doesn’t return a store opcode but instead returns -1. In this way, the checks in `MemNode::can_see_stored_value`
> 
> https://github.com/openjdk/jdk/blob/87e864bf21d71daae4e001ec4edbb4ef1f60c36d/src/hotspot/share/opto/memnode.cpp#L1164-L1166
> 
> and `StoreNode::Identity`
> 
> https://github.com/openjdk/jdk/blob/87e864bf21d71daae4e001ec4edbb4ef1f60c36d/src/hotspot/share/opto/memnode.cpp#L3509-L3515
> 
> will fail if masks or indices are used.
> For 2 stores of the same value we instead check for mask and indices equality.
> 
> Regression tests for all versions of `Load/StoreVectorGather/Masked` have been added too.

This pull request has now been integrated.

Changeset: 0c934ff4
Author:    Damon Fenacci <dfenacci at openjdk.org>
URL:       https://git.openjdk.org/jdk/commit/0c934ff4e2fb53a72ad25a080d956745a5649f9b
Stats:     1465 lines in 5 files changed: 1463 ins; 0 del; 2 mod

8325520: Vector loads and stores with indices and masks incorrectly compiled

Reviewed-by: epeter, thartmann

-------------

PR: https://git.openjdk.org/jdk/pull/18347


More information about the hotspot-compiler-dev mailing list