https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96522
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Slightly adjusted testcase that aborts if miscompiled: /* { dg-do run } */ /* { dg-options "-O -fno-tree-pta" } */ __attribute__((noipa)) void bar (void) { volatile int v = 1; if (v) __builtin_abort (); } __attribute__((noipa)) void baz (void) { } __attribute__((noipa)) void foo (int n, double *p, double *x) { if (n < 10 && p != 0) for (int i = 0; i < 10; i++) if (x[0] < p[i]) x[i] = 0; if (p != 0) bar (); else baz (); } int main () { double arr[10]; foo (1000, 0, arr); return 0; } Note, with -O1 neither evrp nor vrp{1,2} are done, but this happens during dom3. What I see happening is that we have _7 = p_16(D) + _6; in the IL and as it is used in a block guarded with p != 0, we determine (but don't store for the p_16(D) SSA_NAME that p_16(D) at that point must be non-NULL and so (IMO correctly) set _7 to be non-NULL in the vr info as well as SSA_NAME_PTR_INFO. The problem is that during ivopts rewrite_use_address calls copy_ref_info when copying ref info from *_7 to a TARGET_MEM_REF MEM[base: p_16(D), index: ivtmp.17_24, offset: 0B] and that in turn will do: 1018 /* We can transfer points-to information from an old pointer 1019 or decl base to the new one. */ 1020 if (new_ptr_base 1021 && TREE_CODE (new_ptr_base) == SSA_NAME 1022 && !SSA_NAME_PTR_INFO (new_ptr_base)) I bet the intent is that if new_ptr_base has been a newly created SSA_NAME, then it is ok to copy the info (maybe), and for other cases without the -fno-tree-pta the existing SSA_NAMEs will likely have SSA_NAME_PTR_INFO non-NULL. Anyway, even if it would be ok to copy the points-to info that way, I think it isn't ok to copy whether the pointer can be NULL or not. So, either the condition should include && flag_tree_pta, or at least do reset_flow_sensitive_info (new_ptr_info). Or maybe callers of copy_ref_info should pass in a flag whether the new_ptr_info is a freshly created SSA_NAME (in that case like e.g. in slsr it is probably ok to do what it does ATM), or not (and then either not do it at all, or do the reset_flow_sensitive_info on it afterwards, thus forget alignment and non-NULL info that could be only in a particular region and not valid elsewhere.