There's a path I added where get_alias_set () != 0 was meant to cover -fno-strict-aliasing but it doesn't since quite some time (oops). Fixed as follows - preprartory for PR91091 where we'd otherwise break the testcase below.
Bootstrap / regtest running on x86_64-unknown-linux-gnu. I'll also backport this to the GCC 8/9 branches where the issue is latent. Richard. 2019-07-05 Richard Biener <rguent...@suse.de> PR tree-optimization/91091 * tree-ssa-sccvn.c (vn_reference_lookup_3): Overlap of accesses can happen with -fno-strict-aliasing. * gcc.dg/tree-ssa/pr91091-1.c: New testcase. Index: gcc/tree-ssa-sccvn.c =================================================================== --- gcc/tree-ssa-sccvn.c (revision 273133) +++ gcc/tree-ssa-sccvn.c (working copy) @@ -1996,7 +1996,8 @@ vn_reference_lookup_3 (ao_ref *ref, tree activation of a union member via a store makes the values of untouched bytes unspecified. */ && (known_eq (ref->size, BITS_PER_UNIT) - || (get_alias_set (lhs) != 0 + || (flag_strict_aliasing + && get_alias_set (lhs) != 0 && ao_ref_alias_set (ref) != 0))) { tree *saved_last_vuse_ptr = data->last_vuse_ptr; Index: gcc/testsuite/gcc.dg/tree-ssa/pr91091-1.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/pr91091-1.c (nonexistent) +++ gcc/testsuite/gcc.dg/tree-ssa/pr91091-1.c (working copy) @@ -0,0 +1,23 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-strict-aliasing" } */ + +struct s { int x; } __attribute__((packed)); +struct t { int x; }; + +void __attribute__((noinline,noipa)) +swap(struct s* p, struct t* q) +{ + p->x = q->x; + q->x = p->x; +} + +int main() +{ + struct t a[2]; + a[0].x = 0x12345678; + a[1].x = 0x98765432; + swap ((struct s *)((char *)a + 1), a); + if (a[0].x != 0x12345678) + __builtin_abort (); + return 0; +}