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.