[Bug tree-optimization/90433] New: POINTER_DIFF_EXPR in vectorizer prologue

glisse at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sat May 11 11:47:00 GMT 2019


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

            Bug ID: 90433
           Summary: POINTER_DIFF_EXPR in vectorizer prologue
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: glisse at gcc dot gnu.org
  Target Milestone: ---

I am picking a random code that gets vectorized to illustrate the issue

#include <vector>
#include <memory>
#include <new>
inline void* operator new(std::size_t n){return malloc(n);}
inline void operator delete(void*p){free(p);}
typedef std::unique_ptr<int> T;
typedef std::vector<T> V;
void f(V&v){v.reserve(1024);}

Compiling with -O3 on x86_64, the vectorizer produces

  <bb 3> [local count: 354334802]:
  _9 = MEM[(struct unique_ptr * *)v_2(D) + 8B];
  _10 = _9 - _4;
  _24 = malloc (8192);
  if (_4 == _9)
    goto <bb 5>; [11.00%]
  else
    goto <bb 15>; [89.00%]

  <bb 15> [local count: 315357974]:
  _26 = (unsigned long) _9;
  _16 = (unsigned long) _4;
  _13 = _26 - _16; ****************
  _23 = _13 + 18446744073709551608;
  _11 = _23 /[ex] 8;
  _3 = _11 & 2305843009213693948;
  _38 = _3 != 0;
  _39 = _4 + 15;
  _40 = _39 - _24; ****************
  _41 = (sizetype) _40;
  _42 = _41 > 30;
  _43 = _38 & _42;
  if (_43 != 0)
    goto <bb 16>; [80.00%]
  else
    goto <bb 17>; [20.00%]

  <bb 16> [local count: 252286381]:
  _55 = (unsigned long) _9;
  _56 = (unsigned long) _4;
  _57 = _55 - _56; ****************
  _58 = _57 + 18446744073709551608;
  _59 = _58 /[ex] 8;
  _60 = _59 & 2305843009213693951;
  niters.75_54 = _60 + 1;
  bnd.76_71 = niters.75_54 >> 1;

Note the lines marked with stars. To compute the size of the memory region, it
casts the pointers to unsigned long and subtracts those, whereas it could
perfectly well use POINTER_DIFF_EXPR. On the other hand, (for the aliasing
check?) it subtracts _39 and _24 which are completely independent pointers (one
was freshly returned by malloc) using POINTER_DIFF_EXPR, while IIRC this is
only supposed to be used for subtraction of pointers into the same
object/region.


More information about the Gcc-bugs mailing list