diff options
author | Ilya Leoshkevich <iii@linux.ibm.com> | 2020-12-10 15:43:59 +0100 |
---|---|---|
committer | Ilya Leoshkevich <iii@linux.ibm.com> | 2021-03-16 13:57:34 +0100 |
commit | 4073a09e23944b17cd1afce77025b1ea19b28ced (patch) | |
tree | 5d9bb0a528e524c62e227edc69c9995b0c002832 | |
parent | 995a740cb01a0671a2082cb1ae13d0c356d4b568 (diff) | |
download | gcc-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.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/s390/vector/long-double-asm-fprvrmem.c | 11 |
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; +} |