https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128213
--- Comment #1 from liu zhenyu <lzy20000419 at outlook dot com> --- Created attachment 65982 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65982&action=edit testcase I think this comes from r16 commit 952e145796da ("phiprop: Allow non-trapping loads to be proped back into the loop", PR60183). Before it, phiprop only replaced loads in blocks that post-dominate the PHI. Now it skips that check when no PHI argument could trap. gcc/tree-ssa-phiprop.cc (trunk), propagate_with_phi: 418 if (TREE_CODE (arg) == ADDR_EXPR) 419 { 420 tree decl = TREE_OPERAND (arg, 0); 421 if (!canpossible_trap) 422 canpossible_trap = tree_could_trap_p (decl); 423 } ... 499 if ((canpossible_trap || aggregate) 500 && !dominated_by_p (CDI_POST_DOMINATORS, 501 bb, gimple_bb (use_stmt))) 502 delay = true; tree_could_trap_p (decl) only asks whether the decl itself can be missing, for example a weak symbol. It does not look at the load that will be inserted on the edge, MEM_REF <int> (&ch, 0), which is 4 bytes from a 1-byte object. The same happens with an in-bounds ARRAY_REF argument like &buf[3] and a 4-byte load: char buf[4] = { 1, 2, 3, 4 }; int iv = 7; __attribute__((noipa)) int f (int c, int d) { char *p = c ? &buf[3] : (char *) &iv; if (d) { int v; __builtin_memcpy (&v, p, sizeof v); return v; } return 0; } int main (void) { volatile int c = 1, d = 0; return f (c, d); } (14.2 doesn't have this code. It always requires post-dominance.) Suggested fix: do the trap check per use, on the reference that will actually be inserted. For example, use tree_could_trap_p (build2 (MEM_REF, TREE_TYPE (rhs), arg, TREE_OPERAND (rhs, 1))), which compares the access extent with DECL_SIZE. I haven't built or tested this fix.
