]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rs6000: MMA test case emits wrong code when building a vector pair [PR102976]
authorPeter Bergner <bergner@linux.ibm.com>
Tue, 16 Nov 2021 18:14:22 +0000 (12:14 -0600)
committerPeter Bergner <bergner@linux.ibm.com>
Tue, 16 Nov 2021 18:14:22 +0000 (12:14 -0600)
PR102976 shows a test case where we generate wrong code when building
a vector pair from 2 vector registers.  The bug here is that with unlucky
register assignments, we can clobber one of the input operands before
we write both registers of the output operand.  The solution is to use
early-clobbers in the assemble pair and accumulator patterns.

2021-11-16  Peter Bergner  <bergner@linux.ibm.com>

gcc/
PR target/102976
* config/rs6000/mma.md (*vsx_assemble_pair): Add early-clobber for
output operand.
(*mma_assemble_acc): Likewise.

gcc/testsuite/
PR target/102976
* gcc.target/powerpc/pr102976.c: New test.

gcc/config/rs6000/mma.md
gcc/testsuite/gcc.target/powerpc/pr102976.c [new file with mode: 0644]

index 1990a2183f6c96f8f1dac95bc50c8cf64c31aee8..fa081608c4c87aa3eb2d85186ebebcf487cef012 100644 (file)
   DONE;
 })
 
+;; We cannot update the two output registers atomically, so mark the output
+;; as an early clobber so we don't accidentally clobber the input operands.  */
+
 (define_insn_and_split "*vsx_assemble_pair"
-  [(set (match_operand:OO 0 "vsx_register_operand" "=wa")
+  [(set (match_operand:OO 0 "vsx_register_operand" "=&wa")
        (unspec:OO [(match_operand:V16QI 1 "mma_assemble_input_operand" "mwa")
                    (match_operand:V16QI 2 "mma_assemble_input_operand" "mwa")]
                    UNSPEC_MMA_ASSEMBLE))]
   DONE;
 })
 
+;; We cannot update the four output registers atomically, so mark the output
+;; as an early clobber so we don't accidentally clobber the input operands.  */
+
 (define_insn_and_split "*mma_assemble_acc"
-  [(set (match_operand:XO 0 "fpr_reg_operand" "=d")
+  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
        (unspec:XO [(match_operand:V16QI 1 "mma_assemble_input_operand" "mwa")
                    (match_operand:V16QI 2 "mma_assemble_input_operand" "mwa")
                    (match_operand:V16QI 3 "mma_assemble_input_operand" "mwa")
diff --git a/gcc/testsuite/gcc.target/powerpc/pr102976.c b/gcc/testsuite/gcc.target/powerpc/pr102976.c
new file mode 100644 (file)
index 0000000..5a4320f
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10" } */
+
+#include <altivec.h>
+void
+bug (__vector_pair *dst)
+{
+  register vector unsigned char vec0 asm ("vs44");
+  register vector unsigned char vec1 asm ("vs32");
+  __builtin_vsx_build_pair (dst, vec0, vec1);
+}
+
+/* { dg-final { scan-assembler-times {(?p)\mxxlor \d+,44,44\M} 1 } } */
+/* { dg-final { scan-assembler-times {(?p)\mxxlor \d+,32,32\M} 1 } } */