I am testing the following patch to restrict MEM canonicalization in LIM further.
Bootstrap and regtest running on x86_64-unkown-linux-gnu. Richard. 2019-01-30 Richard Biener <rguent...@suse.de> PR tree-optimization/89111 * tree-ssa-loop-im.c (gather_mem_refs_stmt): Restrict canonicalization to appropriately sized access types. * gcc.dg/torture/pr89111.c: New testcase. Index: gcc/tree-ssa-loop-im.c =================================================================== --- gcc/tree-ssa-loop-im.c (revision 268383) +++ gcc/tree-ssa-loop-im.c (working copy) @@ -1472,6 +1472,11 @@ gather_mem_refs_stmt (struct loop *loop, && aor.max_size.is_constant (&max_size) && size == max_size && (size % BITS_PER_UNIT) == 0 + /* We're canonicalizing to a MEM where TYPE_SIZE specifies the + size. Make sure this is consistent with the extraction. */ + && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (*mem))) + && known_eq (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (*mem))), + aor.size) && (mem_base = get_addr_base_and_unit_offset (aor.ref, &mem_off))) { hash = iterative_hash_expr (ao_ref_base (&aor), 0); Index: gcc/testsuite/gcc.dg/torture/pr89111.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr89111.c (nonexistent) +++ gcc/testsuite/gcc.dg/torture/pr89111.c (working copy) @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-require-effective-target int32plus } */ + +struct __attribute__((packed)) A { int b : 24; } c[243], f; + +int d, e, g, j; + +__attribute__((noipa)) int +foo (int x) +{ + if (x != 0) + __builtin_abort (); + return 2; +} + +int +main () +{ + struct A h = f; + h.b = 0; + while (e++ < 3) + { + while (d++ < 3) + c[46].b ^= 9890739; + f = c[46] = h; + } + while (g++ < 9) + j = foo (c[g * 9 + j].b); + return 0; +}