aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPeter Bergner <bergner@linux.ibm.com>2021-11-16 12:14:22 -0600
committerPeter Bergner <bergner@linux.ibm.com>2021-11-16 12:14:22 -0600
commit4cdf7db9a39d18bd536d816a5751d4d3cf23808b (patch)
tree6b23eb7b51feb857c3207e4d8331375337cede24 /gcc
parent48a8c5be5b98240d664672a2b7b7d26f3c36cf84 (diff)
downloadgcc-4cdf7db9a39d18bd536d816a5751d4d3cf23808b.zip
gcc-4cdf7db9a39d18bd536d816a5751d4d3cf23808b.tar.gz
gcc-4cdf7db9a39d18bd536d816a5751d4d3cf23808b.tar.bz2
rs6000: MMA test case emits wrong code when building a vector pair [PR102976]
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/rs6000/mma.md10
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr102976.c14
2 files changed, 22 insertions, 2 deletions
diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md
index 1990a21..fa08160 100644
--- a/gcc/config/rs6000/mma.md
+++ b/gcc/config/rs6000/mma.md
@@ -338,8 +338,11 @@
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))]
@@ -404,8 +407,11 @@
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
index 0000000..5a4320f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr102976.c
@@ -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 } } */