aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/aarch64/aarch64.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/aarch64/aarch64.c')
-rw-r--r--gcc/config/aarch64/aarch64.c24
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);