In LazyValueInfoImpl::isNonNullAtEndOfBlock we populate a set of
pointers, known to be non-null at the end of a block (e.g. because we
did a load through them). We then infer that any pointer, based on an
element of this set is non-null as well ("based" here meaning a
non-null pointer is the underlying object). This is incorrect, even if
the base pointer was non-null, the value of a GEP, that lacks the
inbounds` attribute, may be null.
This issue appeared as miscompilation of the following test case:
int puts(const char *); typedef struct iter { int *val; } iter_t; static long distance(iter_t first, iter_t last) { long r = 0; for (; first.val != last.val; first.val++) ++r; return r; } int main() { int arr[2] = {0}; iter_t i, j; i.val = arr; j.val = arr + 1; if (distance(i, j) >= 2) puts("failed"); else puts("passed"); }
This fixes PR49662.
This test should be in llvm/test/Transform/JumpThreading.