diff options
Diffstat (limited to 'gcc/config/aarch64/aarch64.c')
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index f878721..994fafc 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -17925,10 +17925,22 @@ aarch64_legitimate_constant_p (machine_mode mode, rtx x) { /* Support CSE and rematerialization of common constants. */ if (CONST_INT_P (x) - || (CONST_DOUBLE_P (x) && GET_MODE_CLASS (mode) == MODE_FLOAT) - || GET_CODE (x) == CONST_VECTOR) + || (CONST_DOUBLE_P (x) && GET_MODE_CLASS (mode) == MODE_FLOAT)) return true; + /* Only accept variable-length vector constants if they can be + handled directly. + + ??? It would be possible (but complex) to handle rematerialization + of other constants via secondary reloads. */ + if (!GET_MODE_SIZE (mode).is_constant ()) + return aarch64_simd_valid_immediate (x, NULL); + + /* Otherwise, accept any CONST_VECTOR that, if all else fails, can at + least be forced to memory and loaded from there. */ + if (GET_CODE (x) == CONST_VECTOR) + return !targetm.cannot_force_const_mem (mode, x); + /* Do not allow vector struct mode constants for Advanced SIMD. We could support 0 and -1 easily, but they need support in aarch64-simd.md. */ @@ -17936,14 +17948,6 @@ aarch64_legitimate_constant_p (machine_mode mode, rtx x) if (vec_flags == (VEC_ADVSIMD | VEC_STRUCT)) return false; - /* Only accept variable-length vector constants if they can be - handled directly. - - ??? It would be possible to handle rematerialization of other - constants via secondary reloads. */ - if (vec_flags & VEC_ANY_SVE) - return aarch64_simd_valid_immediate (x, NULL); - if (GET_CODE (x) == HIGH) x = XEXP (x, 0); |