From: Stefan Schulze Frielinghaus <[email protected]>
The splitter could fire before register allocation for which the
attached test ICEs. There we end up for operands[1] with (subreg:HI
(reg:HF 70) 0) for which simplify_gen_subreg tries to fold two subregs
into (subreg:SI (reg:HF 70) 0) which is not valid. The returned
NULL_RTX is then propagated and later on dereferenced.
The splitter is supposed to fire only after register allocation once we
decided to go for the GPR alternative in bswaphi2. This also solves the
initial problem since after RA we should only deal with hard registers
and simplify_gen_subreg folds subregs of GPRs (this would also solve the
problem of using a paradoxical subreg over pseudos as a left-hand side
operand). As a safety net, still test for NULL_RTX which would lead to
more descriptive ICEs.
PR 127692
gcc/ChangeLog:
* config/s390/s390.md: Fix bswap:HI reg-reg splitter.
gcc/testsuite/ChangeLog:
* gcc.target/s390/pr127692-1.c: New test.
Co-authored-by: Jakub Jelinek <[email protected]>
---
Bootstrap and regtest still running. Will push if they are successful.
I will also come up with backports since the last fix is from
r6-6202-g9060e33505b.
gcc/config/s390/s390.md | 4 +++-
gcc/testsuite/gcc.target/s390/pr127692-1.c | 17 +++++++++++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.target/s390/pr127692-1.c
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index aa9b011278d..9ca5ad06cfb 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -11317,12 +11317,14 @@
(define_split
[(set (match_operand:HI 0 "register_operand" "")
(bswap:HI (match_operand:HI 1 "register_operand" "")))]
- ""
+ "reload_completed"
[(set (match_dup 2) (bswap:SI (match_dup 3)))
(set (match_dup 2) (lshiftrt:SI (match_dup 2) (const_int 16)))]
{
operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
+ if (operands[2] == NULL_RTX || operands[3] == NULL_RTX)
+ FAIL;
})
diff --git a/gcc/testsuite/gcc.target/s390/pr127692-1.c
b/gcc/testsuite/gcc.target/s390/pr127692-1.c
new file mode 100644
index 00000000000..d68b6bef82a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/pr127692-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=z13" } */
+
+void
+foo (double x, char *y, int z)
+{
+ _Float16 a = (_Float16) x;
+ if (!z)
+ {
+ unsigned short b;
+ __builtin_memcpy (&b, &a, 2);
+ b = __builtin_bswap16(b);
+ __builtin_memcpy (y, &b, 2);
+ }
+ else
+ __builtin_memcpy (y, &a, sizeof (_Float16));
+}
--
2.55.0