[PATCH] Fix store-merging of cst followed by load (PR tree-optimization/82954)

Jakub Jelinek jakub@redhat.com
Sun Nov 12 23:03:00 GMT 2017


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  <jakub@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



More information about the Gcc-patches mailing list