https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126369

            Bug ID: 126369
           Summary: VLA versioning can generate unreachable code
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: tnfchris at gcc dot gnu.org
            Blocks: 53947, 115130
  Target Milestone: ---
            Target: aarch64*

The following loop

char b[100];
int c(int a) {
  unsigned d = 0;
  for (; d < a; ++d)
    {
      if (b[0] + b[d + 1])
        return 0;
    }
  return 1;
}

when compiled with -march=armv9-a -mautovec-preference=sve-only -Ofast
generates a runtime alignment check.

https://godbolt.org/z/bs18h4zWb

        adrp    x4, .LANCHOR0
        add     x5, x4, :lo12:.LANCHOR0
        ldrb    w6, [x4, #:lo12:.LANCHOR0]
        cmp     w0, 2
        bls     .L2
        add     x1, x5, 1
        cntw    x2
        orr     x1, x1, x2
        sub     x3, x2, #1
        cmp     x2, 4096
        and     x1, x1, x3
        ccmp    x1, 0, 0, ls
        bne     .L2
        sub     x5, x5, x2
        add     w3, w0, 1
        mov     z30.h, w6
        add     x5, x5, 1
        mov     w1, 0
        ptrue   p6.b, all

however this is moot since the accesses of b inside the loop will always be
misaligned and so versioning for alignment will never succeed.

The dr for this access is

Statement _4 = b[_3];
 is executed at most 98 (bounded by 98) + 1 times in loop 1.
Loops range found for d_8: [irange] unsigned int [0, 99] and calculated range
:[irange] unsigned int [0, 100]
 Registering value_relation (_3 > d_8) (bb3) at _3 = d_8 + 1;
success.
        base_address: &b
        offset from base address: 0
        constant offset from base address: 1
        step: 1
        base alignment: 8
        base misalignment: 0
        offset alignment: 128
        step alignment: 1
        base_object: b
        Access function 0: {1, +, 1}<nw>_1

so it knows that access is misaligned by a byte.

However vect_compute_data_ref_alignment is very conservative for VLA. It sets
misalignment to unknown and then bails out

  unsigned HOST_WIDE_INT vect_align_c;
  if (!vector_alignment.is_constant (&vect_align_c))
    return;

and so we lose the information that the load is misaligned and can never reach
alignment.

vect_compute_data_ref_alignment should be enhanced to support this.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53947
[Bug 53947] [meta-bug] vectorizer missed-optimizations
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115130
[Bug 115130] [meta-bug] early break vectorization
  • [Bug tree-optimization/126369] ... tnfchris at gcc dot gnu.org via Gcc-bugs

Reply via email to