[Bug tree-optimization/93971] New: C++ containers considered to alias declared objects of incompatible types

msebor at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Feb 28 17:07:00 GMT 2020


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

            Bug ID: 93971
           Summary: C++ containers considered to alias declared objects of
                    incompatible types
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

Inspired by the discussion in pr93745 I tried the following to see if GCC was
able to eliminate the test: it isn't, not even after declaring
std::vector::_M_impl._M_start restrict.

In bug 49367 Jason points out a similar limitation except involving pointers of
the same type pointing to (potentially) allocated storage.  Here it's clear
that _M_impl._M_start cannot point to x because x is accessed (i.e., first read
and then written) by an incompatible type.  Another similar test case is in bug
49761.

Even declaring v __restrict doesn't help.

$ cat t.C && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout t.C

  #include <vector>

  double x;

  void f (std::vector<int> &v)
  {
    double t = x;
    v[0] = 0;
    if (t != x)
      __builtin_abort ();
  }

  ;; Function f (_Z1fRSt6vectorIiSaIiEE, funcdef_no=880, decl_uid=16170,
cgraph_uid=169, symbol_order=170)

  f (struct vector & v)
  {
    double t;
    int * _4;

    <bb 2> [local count: 1073741824]:
    t_2 = x;
    _4 = v_3(D)->D.17243._M_impl.D.16553._M_start;
    MEM[(value_type &)_4] = 0;
    if (t_2 != t_2)
      goto <bb 3>; [0.00%]
    else
      goto <bb 4>; [100.00%]

    <bb 3> [count: 0]:
    __builtin_abort ();

    <bb 4> [local count: 1073741824]:
    return;

  }

The roughly equivalent C test case is:

  struct V { int *restrict p; };

  double x;

  void f (struct V * /* restrict */ p)   // restrict here makes no difference
  {
    double t = x;
    p->p[0] = 0;
    if (t != x)
      __builtin_abort ();
  }


More information about the Gcc-bugs mailing list