Hi,

This patch enables Loop Invariant Code Motion (LICM) to hoist loads that
alias with stores rom the loaded value.

The pattern a[i] = a[0] is common in TSVC benchmarks (s293):

  for (int i = 0; i < N; i++)
    a[i] = a[0];

Previously, GCC conservatively rejected hoisting a[0] due to potential
aliasing when i==0. However, this is a "self write" - even when aliasing
occurs, we're writing back the same value, making hoisting safe.

The optimization checks that:
1. One reference is a load, the other is a store
2. The stored SSA value equals the loaded SSA value
3. Only simple cases with single accesses per reference

This enables vectorization of these patterns by allowing the vectorizer
to see the hoisted loop-invariant value.

With the patch, the loop now vectorizes and generates:

        .L2:
-       ldr     s31, [x1]
-       str     s31, [x0], 4
-       cmp     x0, x2
+       str     q31, [x0], 16
+       cmp     x0, x1
        bne     .L2

gcc/ChangeLog:

        * tree-ssa-loop-im.cc (is_self_write): New.
        (refs_independent_p): Allow hoisting when aliasing references
        form a self write pattern.

gcc/testsuite/ChangeLog:

        * gcc.dg/vect/vect-licm-hoist-1.c: New.
        * gcc.dg/vect/vect-licm-hoist-2.c: Likewise.

Bootstrappped and regression tested on aarch64-linux-gnu with no New
regressions.

Is this Ok?

Signed-off-by: Kugan Vivekanandarajah <[email protected]>

Thanks,
Kugan




Attachment: 0001-tree-optimization-Allow-LICM-to-hoist-loads-in-self-.patch
Description: 0001-tree-optimization-Allow-LICM-to-hoist-loads-in-self-.patch

Reply via email to