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

            Bug ID: 126605
           Summary: Do not version for alignment when the runtime check
                    cannot hold
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ktkachov at gcc dot gnu.org
  Target Milestone: ---

vect_create_cond_for_align_checks builds either
"(a_1 | ... | a_n) & mask == 0" or "((a_1 ^ a_2) | ...) & mask == 0" over
the references recorded in LOOP_VINFO_MAY_MISALIGN_STMTS.  Both forms
require every checked address to have the same value modulo the target
alignment.  Nothing verified that such a value exists.

An early break over a two-field struct splits the loads into two
interleaving groups over the same base, four bytes apart, and both group
leaders are recorded for the runtime check.  The condition then asks for p
and p + 4 to be 32-byte aligned at the same time, which no address
satisfies, so the vector loop is emitted, reported as vectorized, costed,
and never entered.

For

  struct P { int a, b; };
  int allequal (const struct P *x, const struct P *y, long n)
  {
    for (long i = 0; i < n; i++)
      if (x[i].a != y[i].a || x[i].b != y[i].b)
        return 0;
    return 1;
  }

aarch64 -O3 emits a guaranteed-taken guard in front of unreachable vector
code

        add     x3, x1, 4
        add     x4, x0, 4
        orr     x3, x1, x3
        orr     x4, x0, x4
        orr     x3, x3, x4
        tst     x3, 31
        bne     .L14
        [30 instructions of vector loop]

Reply via email to