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

Reply via email to