https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101993
--- Comment #2 from Hongyu Wang <wwwhhhyyy333 at gmail dot com> --- (In reply to Richard Biener from comment #1) > We can vectorize this with masked moves when using AVX2. clang seems to > simply remove the test completely - C seems to guarantee that a + i is a > valid pointer > if any of a + i is accessed and thus a + i is never NULL. > > But then - just don't write such stupid checks? What real-world code was > this testcase created from? It came from 538.imagick_r --- #define GetPixelIndex(indexes) \ ((indexes == (const unsigned short *) NULL) ? 0 : (*(indexes))) for (v=0; v < (ssize_t) kernel->height; v++) { for (u=0; u < (ssize_t) kernel->width; u++, k--) { if ( IsNaN(*k) ) continue; result.red += (*k)*k_pixels[u].red; result.green += (*k)*k_pixels[u].green; result.blue += (*k)*k_pixels[u].blue; result.opacity += (*k)*k_pixels[u].opacity; if ( image->colorspace == CMYKColorspace) result.index += (*k)*GetPixelIndex(k_indexes+u); } k_pixels += virt_width; k_indexes += virt_width; } --- I extracted it to a small test in https://godbolt.org/z/G5h6nWvb5 which can be vectorized by clang but not gcc due to such pattern. > > There is currently no optimization phase that would use loop info to elide > NULL pointer checks and I'm not sure where I'd put such. Note the argument > for > GCC would be that the access *(a + i) infers that a + i does not "overflow" > to another object (including NULL). That's sth the points-to solver would > assume here (but the points-to solver is bad at tracking NULL).