]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rs6000: Disable optimizing multiple xxsetaccz instructions into one xxsetaccz
authorPeter Bergner <bergner@linux.ibm.com>
Tue, 14 Sep 2021 15:47:18 +0000 (10:47 -0500)
committerPeter Bergner <bergner@linux.ibm.com>
Sat, 15 Jan 2022 04:54:39 +0000 (22:54 -0600)
Fwprop will happily optimize two xxsetaccz instructions into one xxsetaccz
by propagating the results of the first to the uses of the second.
We really don't want that to happen given the late priming/depriming of
accumulators.  I fixed this by making the xxsetaccz source operand an
unspec volatile.  I also removed the mma_xxsetaccz define_expand and
define_insn_and_split and replaced it with a simple define_insn.

Rather than a new test case, I was able to just modify the current test case
to add another __builtin_mma_xxsetaccz call which shows the bad code gen
with unpatched compilers.

2021-09-14  Peter Bergner  <bergner@linux.ibm.com>

gcc/
* config/rs6000/mma.md (unspecv): Add UNSPECV_MMA_XXSETACCZ.
(*movpxi): Remove 'O' alternative.
(mma_xxsetaccz): Change to define_insn.  Use UNSPECV_MMA_XXSETACCZ.
Add comment.
* config/rs6000/rs6000.c (rs6000_rtx_costs): Handle UNSPEC_VOLATILE.

gcc/testsuite/
* gcc.target/powerpc/mma-builtin-6.c: Add second call to xxsetacc
built-in.  Update instruction counts.

(cherry picked from commit f80b9be083e0e7d49e7744b7e531b9aa52acd563)

gcc/config/rs6000/mma.md
gcc/config/rs6000/rs6000.c
gcc/testsuite/gcc.target/powerpc/mma-builtin-6.c

index d97571608458e44a3b4629b42de6e750fa5423c1..f39a5c8ba99c9770484c2eae308bf76ece53e140 100644 (file)
    UNSPEC_MMA_XXMTACC
   ])
 
+(define_c_enum "unspecv"
+  [UNSPECV_MMA_XXSETACCZ
+  ])
+
 ;; MMA instructions with 1 accumulator argument
 (define_int_iterator MMA_ACC           [UNSPEC_MMA_XXMFACC
                                         UNSPEC_MMA_XXMTACC])
 })
 
 (define_insn_and_split "*movpxi"
-  [(set (match_operand:PXI 0 "nonimmediate_operand" "=d,m,d,d")
-       (match_operand:PXI 1 "input_operand" "m,d,d,O"))]
+  [(set (match_operand:PXI 0 "nonimmediate_operand" "=d,m,d")
+       (match_operand:PXI 1 "input_operand" "m,d,d"))]
   "TARGET_MMA
    && (gpc_reg_operand (operands[0], PXImode)
        || gpc_reg_operand (operands[1], PXImode))"
   "@
    #
    #
-   #
-   xxsetaccz %A0"
-  "&& reload_completed
-   && !(fpr_reg_operand (operands[0], PXImode) && operands[1] == const0_rtx)"
+   #"
+  "&& reload_completed"
   [(const_int 0)]
 {
   rs6000_split_multireg_move (operands[0], operands[1]);
   DONE;
 }
-  [(set_attr "type" "vecload,vecstore,veclogical,mma")
-   (set_attr "length" "8,8,16,*")
-   (set_attr "max_prefixed_insns" "2,2,*,*")])
+  [(set_attr "type" "vecload,vecstore,veclogical")
+   (set_attr "length" "8,8,16")
+   (set_attr "max_prefixed_insns" "2,2,*")])
 
 (define_expand "vsx_assemble_pair"
   [(match_operand:POI 0 "vsx_register_operand")
   "<acc> %A0"
   [(set_attr "type" "mma")])
 
-(define_expand "mma_xxsetaccz"
-  [(set (match_operand:PXI 0 "fpr_reg_operand")
-       (const_int 0))]
+;; We can't have integer constants in PXImode so we wrap this in an
+;; UNSPEC_VOLATILE.
+
+(define_insn "mma_xxsetaccz"
+  [(set (match_operand:PXI 0 "fpr_reg_operand" "=d")
+       (unspec_volatile:PXI [(const_int 0)]
+                            UNSPECV_MMA_XXSETACCZ))]
   "TARGET_MMA"
-{
-  emit_insn (gen_movpxi (operands[0], const0_rtx));
-  DONE;
-})
+  "xxsetaccz %A0"
+  [(set_attr "type" "mma")])
 
 (define_insn "mma_<vv>"
   [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
index 8ca7f2fe543aff1b0b4e9185002ce71fc89e1254..a9d1769350ed5d710c713003aa7fb6bf411eb7e3 100644 (file)
@@ -21353,6 +21353,14 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
        }
       break;
 
+    case UNSPEC_VOLATILE:
+      if (XINT (x, 1) == UNSPECV_MMA_XXSETACCZ)
+        {
+          *total = 0;
+          return true;
+        }
+      break;
+
     default:
       break;
     }
index 0c6517211e3b32702258e6b8e743ba79891cc90d..715b28138e9eff4cc491f01a813e1c2614466e32 100644 (file)
@@ -5,14 +5,16 @@
 void
 foo (__vector_quad *dst)
 {
-  __vector_quad acc;
-  __builtin_mma_xxsetaccz (&acc);
-  *dst = acc;
+  __vector_quad acc0, acc1;
+  __builtin_mma_xxsetaccz (&acc0);
+  __builtin_mma_xxsetaccz (&acc1);
+  dst[0] = acc0;
+  dst[1] = acc1;
 }
 
 /* { dg-final { scan-assembler-not {\mlxv\M} } } */
 /* { dg-final { scan-assembler-not {\mlxvp\M} } } */
 /* { dg-final { scan-assembler-not {\mxxmtacc\M} } } */
-/* { dg-final { scan-assembler-times {\mxxsetaccz\M} 1 } } */
-/* { dg-final { scan-assembler-times {\mxxmfacc\M} 1 } } */
-/* { dg-final { scan-assembler-times {\mstxvp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxxsetaccz\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxxmfacc\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mstxvp\M} 4 } } */