Hi! The conditions split groups if some operand is loaded in first stmt and the second load is incompatible with it, or if it is loaded and second stmt has constant in there instead of load. But as this testcase shows, I didn't handle properly the case when some operand is a constant first and in second stmt changes into a load. We need to split group between those too.
Bootstrapped/regtested on {x86_64,i686,powerpc64{,le}}-linux, ok for trunk? 2017-11-12 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/82954 * gimple-ssa-store-merging.c (imm_store_chain_info::coalesce_immediate_stores): If !infof->ops[N].base_addr, split group if info->ops[N].base_addr. * gcc.c-torture/execute/pr82954.c: New test. --- gcc/gimple-ssa-store-merging.c.jj 2017-11-10 15:42:39.000000000 +0100 +++ gcc/gimple-ssa-store-merging.c 2017-11-12 15:18:16.614785829 +0100 @@ -1198,10 +1198,12 @@ imm_store_chain_info::coalesce_immediate std::swap (info->ops[0], info->ops[1]); info->ops_swapped_p = true; } - if ((!infof->ops[0].base_addr - || compatible_load_p (merged_store, info, base_addr, 0)) - && (!infof->ops[1].base_addr - || compatible_load_p (merged_store, info, base_addr, 1))) + if ((infof->ops[0].base_addr + ? compatible_load_p (merged_store, info, base_addr, 0) + : !info->ops[0].base_addr) + && (infof->ops[1].base_addr + ? compatible_load_p (merged_store, info, base_addr, 1) + : !info->ops[1].base_addr)) { merged_store->merge_into (info); continue; --- gcc/testsuite/gcc.c-torture/execute/pr82954.c.jj 2017-11-12 15:27:44.478188823 +0100 +++ gcc/testsuite/gcc.c-torture/execute/pr82954.c 2017-11-12 15:27:27.000000000 +0100 @@ -0,0 +1,22 @@ +/* PR tree-optimization/82954 */ + +__attribute__((noipa)) void +foo (int *__restrict p, int *__restrict q) +{ + p[0] = p[0] ^ 1; + p[1] = p[1] ^ 2; + p[2] = p[2] ^ q[2]; + p[3] = p[3] ^ q[3]; +} + +int +main () +{ + int p[4] = { 16, 32, 64, 128 }; + int q[4] = { 8, 4, 2, 1 }; + asm volatile ("" : : "g" (p), "g" (q) : "memory"); + foo (p, q); + if (p[0] != 17 || p[1] != 34 || p[2] != 66 || p[3] != 129) + __builtin_abort (); + return 0; +} Jakub