rs6000: MMA built-in dies with incorrect sharing of tree nodes error
authorPeter Bergner <bergner@linux.ibm.com>
Tue, 1 Sep 2020 18:47:44 +0000 (13:47 -0500)
committerPeter Bergner <bergner@linux.ibm.com>
Tue, 1 Sep 2020 18:49:40 +0000 (13:49 -0500)
When we expand our MMA built-ins into gimple, we erroneously reused the
accumulator memory reference for both the source input value as well as
the destination output value.  This led to a tree sharing error.
The solution is to create separate memory references for the input
and output values.

2020-09-01  Peter Bergner  <bergner@linux.ibm.com>

gcc/
PR target/96808
* config/rs6000/rs6000-call.c (rs6000_gimple_fold_mma_builtin): Do not
reuse accumulator memory reference for source and destination accesses.

gcc/testsuite/
PR target/96808
* gcc.target/powerpc/pr96808.c: New test.

gcc/config/rs6000/rs6000-call.c
gcc/testsuite/gcc.target/powerpc/pr96808.c [new file with mode: 0644]

index 26388762c5fd91f7191d018b122a242e6abe93ff..b6b45687aaeb319489d828c4f4c0f1bcdf9b3535 100644 (file)
@@ -11471,12 +11471,8 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi)
   /* Convert this built-in into an internal version that uses pass-by-value
      arguments.  The internal built-in follows immediately after this one.  */
   new_decl = rs6000_builtin_decls[fncode + 1];
-  tree lhs, mem, op[MAX_MMA_OPERANDS];
+  tree lhs, op[MAX_MMA_OPERANDS];
   tree acc = gimple_call_arg (stmt, 0);
-  if (TREE_CODE (acc) == PARM_DECL)
-    mem = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (acc)), acc);
-  else
-    mem = build_simple_mem_ref (acc);
   push_gimplify_context (true);
 
   if ((attr & RS6000_BTC_QUAD) != 0)
@@ -11486,7 +11482,7 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi)
       op[0] = make_ssa_name (vector_quad_type_node);
       for (unsigned i = 1; i < nopnds; i++)
        op[i] = gimple_call_arg (stmt, i);
-      gimplify_assign (op[0], mem, &new_seq);
+      gimplify_assign (op[0], build_simple_mem_ref (acc), &new_seq);
     }
   else
     {
@@ -11536,7 +11532,7 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi)
     lhs = make_ssa_name (vector_quad_type_node);
   gimple_call_set_lhs (new_call, lhs);
   gimple_seq_add_stmt (&new_seq, new_call);
-  gimplify_assign (mem, lhs, &new_seq);
+  gimplify_assign (build_simple_mem_ref (acc), lhs, &new_seq);
   pop_gimplify_context (NULL);
   gsi_replace_with_seq (gsi, new_seq, true);
 
diff --git a/gcc/testsuite/gcc.target/powerpc/pr96808.c b/gcc/testsuite/gcc.target/powerpc/pr96808.c
new file mode 100644 (file)
index 0000000..2d44bd5
--- /dev/null
@@ -0,0 +1,59 @@
+/* PR target/96808 */
+/* { dg-do compile } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10" } */
+
+/* Verify we do not ICE on the tests below.  */
+
+void
+old_ok (__vector_quad *dst, vector unsigned char vc)
+{
+  __vector_quad vq;
+  __builtin_mma_xxsetaccz(&vq);
+  __builtin_mma_xvf32gerpp(&vq, vc, vc);
+  *dst = vq;
+}
+
+void
+test0 (__vector_quad *dst, vector unsigned char vc)
+{
+  __vector_quad vq[2];
+  __builtin_mma_xxsetaccz(&vq[1]);
+  __builtin_mma_xvf32gerpp(&vq[1], vc, vc);
+  *dst = vq[1];
+}
+
+void
+test1 (__vector_quad *dst, vector unsigned char vc)
+{
+  __vector_quad vq[2][2];
+  __builtin_mma_xxsetaccz(&vq[1][1]);
+  __builtin_mma_xvf32gerpp(&vq[1][1], vc, vc);
+  *dst = vq[1][1];
+}
+
+void
+test2 (__vector_quad *dst, vector unsigned char vc)
+{
+  struct {
+    __vector_quad dummy;
+    __vector_quad acc;
+  } vq;
+  __builtin_mma_xxsetaccz(&vq.acc);
+  __builtin_mma_xvf32gerpp(&vq.acc, vc, vc);
+  *dst = vq.acc;
+}
+
+void
+test3 (__vector_quad *dst, vector unsigned char vc)
+{
+  __builtin_mma_xxsetaccz(&dst[1]);
+  __builtin_mma_xvf32gerpp(&dst[1], vc, vc);
+}
+
+void
+test4 (__vector_quad *dst[], vector unsigned char vc)
+{
+  __builtin_mma_xxsetaccz(&dst[1][2]);
+  __builtin_mma_xvf32gerpp(&dst[1][2], vc, vc);
+}