aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Leoshkevich <iii@linux.ibm.com>2020-12-10 15:43:59 +0100
committerIlya Leoshkevich <iii@linux.ibm.com>2021-03-16 13:57:34 +0100
commit4073a09e23944b17cd1afce77025b1ea19b28ced (patch)
tree5d9bb0a528e524c62e227edc69c9995b0c002832
parent995a740cb01a0671a2082cb1ae13d0c356d4b568 (diff)
downloadgcc-4073a09e23944b17cd1afce77025b1ea19b28ced.zip
gcc-4073a09e23944b17cd1afce77025b1ea19b28ced.tar.gz
gcc-4073a09e23944b17cd1afce77025b1ea19b28ced.tar.bz2
IBM Z: Fix "+fvm" constraint with long doubles
When a long double is passed to an asm statement with a "+fvm" constraint, a LRA loop occurs. This happens, because LRA chooses the widest register class in this case (VEC_REGS), but the code generated by s390_md_asm_adjust() always wants FP_REGS. Mismatching register classes cause infinite reloading. Fix by treating "fv" constraints as "v" in s390_md_asm_adjust(). gcc/ChangeLog: * config/s390/s390.c (f_constraint_p): Treat "fv" constraints as "v". gcc/testsuite/ChangeLog: * gcc.target/s390/vector/long-double-asm-fprvrmem.c: New test.
-rw-r--r--gcc/config/s390/s390.c12
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-asm-fprvrmem.c11
2 files changed, 21 insertions, 2 deletions
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 151136b..f7b1c03 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -16714,13 +16714,21 @@ s390_shift_truncation_mask (machine_mode mode)
static bool
f_constraint_p (const char *constraint)
{
+ bool seen_f_p = false;
+ bool seen_v_p = false;
+
for (size_t i = 0, c_len = strlen (constraint); i < c_len;
i += CONSTRAINT_LEN (constraint[i], constraint + i))
{
if (constraint[i] == 'f')
- return true;
+ seen_f_p = true;
+ if (constraint[i] == 'v')
+ seen_v_p = true;
}
- return false;
+
+ /* Treat "fv" constraints as "v", because LRA will choose the widest register
+ * class. */
+ return seen_f_p && !seen_v_p;
}
/* Implement TARGET_MD_ASM_ADJUST hook in order to fix up "f"
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-asm-fprvrmem.c b/gcc/testsuite/gcc.target/s390/vector/long-double-asm-fprvrmem.c
new file mode 100644
index 0000000..f95656c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-asm-fprvrmem.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=z14 -mzarch" } */
+
+long double
+foo (long double x)
+{
+ x = x * x;
+ asm("# %0" : "+fvm"(x));
+ x = x + x;
+ return x;
+}