[Bug tree-optimization/126369] New: VLA versioning can generate unreachable code

"tnfchris at gcc dot gnu.org via Gcc-bugs" <[email protected]>
Newsgroups gmane.comp.gcc.bugs
Message-ID <[email protected]/bugzilla/>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.