RFR: 8316679: C2 SuperWord: wrong result, load should not be moved before store if not comparable [v3]
Tobias Hartmann
thartmann at openjdk.org
Tue Oct 3 07:31:46 UTC 2023
On Tue, 3 Oct 2023 07:25:19 GMT, Emanuel Peter <epeter at openjdk.org> wrote:
>> **Context**
>> In `SuperWord::output`, we replace the scalars with vectors, pack by pack.
>>
>> In [JDK-8052081](https://bugs.openjdk.org/browse/JDK-8052081) ([changeset](https://github.com/openjdk/jdk/commit/7764490363a5963212e040baa2b79946cf4487bf)) we added an optimization to move the memory state of a LoadVector as early as possible. We go up the memory chain, and skip any `StoreVector` that provably can never alias with the `LoadVector` (provably no overlap).
>>
>> **Details**
>>
>> For this, we must understand the following function `VPointer::cmp`:
>>
>> https://github.com/openjdk/jdk/blob/96781ba33d4717c8df2b9ba4cd5d66858cf5c2d1/src/hotspot/share/opto/vectorization.hpp#L110-L120
>>
>> We have 4 possible states: `NotComparable` means that we cannot determine the relative offsets between the two memory addresses. We have no guarantee about aliasing at all. `Less` means that one address lies before the other, `Greater` means that it comes after. `Equal` means that the two memory regions have an overlap or are identical. To determine overlap, we must know the position of the pointer, as well as the `memory_size` of each memory reference. `VPointer::not_equal` is true iff we get states `Less` or `Greater` (we know there cannot be overlap). `VPointer::comparable` is true iff the state is `NotComparable`, hence we have no guarantee about aliasing.
>>
>> **Problem**
>>
>> Currently, there are 2 bugs in this "move-load-before-store" logic:
>> 1. [JDK-8316679](https://bugs.openjdk.org/browse/JDK-8316679) ([PR](https://github.com/openjdk/jdk/pull/15864)): We do not only skip the `not_equal` but also the `!comparable` case. However, when the two pointers are not comparable, that could be due to different invariants for example (see `TestMovingLoadBeforeStore.java`). The two pointers are not comparable, because we do not know the relative position, due to the invariants. But this exactly means that we cannot know at compile-time that there will not be aliasing. Thus, we cannot allow moving a load before such a store. Otherwise we may get wrong results. (*)
>> 2. [JDK-8316594](https://bugs.openjdk.org/browse/JDK-8316594) ([PR](https://github.com/openjdk/jdk/pull/15866)): Currently, we only compare the first element of the load-pack with the `StoreVector`. This is not correct, we need to compare all elements of the load-pack with the `StoreVector`. Otherwise it may be that the first element lays below/before the memory region of the `StoreVector` (Less), but the last el...
>
> Emanuel Peter has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains eight additional commits since the last revision:
>
> - Merge branch 'master' into JDK-8316679
> - review fixes for TobiHartmann
> - beatify code
> - flip flag
> - fix diagnostic option
> - whitespace
> - Merge branch 'master' into JDK-8316679
> - 8316679: C2 SuperWord: wrong result, load should not be moved before store if not comparable
Marked as reviewed by thartmann (Reviewer).
-------------
PR Review: https://git.openjdk.org/jdk/pull/15864#pullrequestreview-1654515854
More information about the hotspot-compiler-dev
mailing list