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

            Bug ID: 127201
           Summary: dr_may_alias_p ignores DR_PTR_INFO, emitting runtime
                    alias checks for provably disjoint references
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ptomsich at gcc dot gnu.org
  Target Milestone: ---

Created attachment 65489
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65489&action=edit
proposed patch

ptr_derefs_may_alias_p treats "no points-to information" as "may alias".
However, passes that run after the last points-to computation create new
pointer SSA names with no SSA_NAME_PTR_INFO.  We observed this in PRE
materialising a load. The the
vectorizer can then no longer disambiguate these new names, causing versioning
of the loop with runtime alias checks that are provably unnecessary.

Note that all the needed alias information is available: the same pointer was
originally (i.e., before given a new SSA name) analyzed and dr_analyze_alias
recorded it in DR_PTR_INFO.

Testcase (reduced from SPEC2026's palm), compiled with -O3 -ffast-math:

  struct desc { double *data; long span; };
  struct desc g;
  int lo, hi;
  double res;
  void
  f (int c)
  {
    int n = hi - lo + 2;
    double t[n], u[n];          /* VLAs -> __builtin_alloca_with_align */
    /* g.data is loaded on both arms, so PRE materialises it as a fresh
       "pretmp" pointer SSA name -- after the last points-to run.  */
    if (c)
      res = g.data[0];
    else
      res = g.data[1];
    for (int k = 2; k < n - 2; k++)
      {
        u[k] = g.data[k + 1] + g.data[k];
        t[k] = u[k] * (37.0 * (g.data[k + 1] + g.data[k])
                       - 8.0 * (g.data[k + 2] + g.data[k - 1]));
      }
    double s = 0;
    for (int k = 2; k < n - 2; k++)
      s += t[k] + u[k];
    res += s;
  }

t and u are local VLAs whose address never escapes; g.data points to
non-local, escaped memory.  The two categories are disjoint so no runtime check
is needed; yet, trunk emits them:

  $ gcc -O3 -ffast-math -fdump-tree-vect-details -c t.c
  $ grep -c "versioning for alias required" t.c.*t.vect
  16

each of the form "global-derived pointer vs VLA":
  missed: versioning for alias required: can't determine dependence between
          *_16 and (*t.3_49)[k_63]

-fdump-tree-ifcvt-alias shows the missing PT:

  # PT = { D.4524 }
  # ALIGN = 8, MISALIGN = 0
  t.3_49 = __builtin_alloca_with_align (_7, 64);
  # PT = { D.4525 }
  # ALIGN = 8, MISALIGN = 0
  u.5_51 = __builtin_alloca_with_align (_7, 64);
  ...
  pretmp_117 = g.data;                             <- no "# PT" line at all

If we delete the "if (c) ... else ..." block, the base then stays on its
orginal name (_6 = g.data) and the the PT solution survives.

A proposed patch (dr_may_alias_p checks the already recorded DR_PTR_INFO) is
attached.

Confirmed against f96a6b0bb573cd2ceb1936dd0c886f2e3520c275 for
aarch64-unknown-linux-gnu today.

Reply via email to