[gcc r10-10399] rs6000: MMA test case emits wrong code when building a vector pair [PR102976]
Peter Bergner
bergner@gcc.gnu.org
Sat Jan 15 06:00:44 GMT 2022
https://gcc.gnu.org/g:7729d2c96d5eac9537c78d368bbc037bea13f988
commit r10-10399-g7729d2c96d5eac9537c78d368bbc037bea13f988
Author: Peter Bergner <bergner@linux.ibm.com>
Date: Tue Nov 16 12:14:22 2021 -0600
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.
(cherry picked from commit 4cdf7db9a39d18bd536d816a5751d4d3cf23808b)
Diff:
---
gcc/config/rs6000/mma.md | 10 ++++++++--
gcc/testsuite/gcc.target/powerpc/pr102976.c | 14 ++++++++++++++
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md
index c267a4c82e2..27f64d2cb7c 100644
--- a/gcc/config/rs6000/mma.md
+++ b/gcc/config/rs6000/mma.md
@@ -362,8 +362,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:POI 0 "vsx_register_operand" "=wa")
+ [(set (match_operand:POI 0 "vsx_register_operand" "=&wa")
(unspec:POI [(match_operand:V16QI 1 "mma_assemble_input_operand" "mwa")
(match_operand:V16QI 2 "mma_assemble_input_operand" "mwa")]
UNSPEC_VSX_ASSEMBLE))]
@@ -395,8 +398,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:PXI 0 "fpr_reg_operand" "=d")
+ [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
(unspec:PXI [(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 00000000000..5a4320f8e0a
--- /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 } } */
More information about the Gcc-cvs
mailing list