From 806f69cd68c18399e8e54b1a0913ae57beabbe69 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 13 Aug 2019 09:50:35 +0000 Subject: [PATCH] [AArch64] Make aarch64_classify_vector_mode use a switch statement aarch64_classify_vector_mode used properties of a mode to test whether the mode was a single Advanced SIMD vector, a single SVE vector, or a tuple of SVE vectors. That works well for current trunk and is simpler than checking for modes by name. However, for the ACLE and for planned autovec improvements, we also need partial SVE vector modes that hold: - half of the available 32-bit elements - a half or quarter of the available 16-bit elements - a half, quarter, or eighth of the available 8-bit elements These should be packed in memory and unpacked in registers. E.g. VNx2SI has half the number of elements of VNx4SI, and so is half the size in memory. When stored in registers, each VNx2SI element occupies the low 32 bits of a VNx2DI element, with the upper bits being undefined. The upshot is that: GET_MODE_SIZE (VNx4SImode) == 2 * GET_MODE_SIZE (VNx2SImode) since GET_MODE_SIZE must always be the memory size. This in turn means that for fixed-length SVE, some partial modes can have the same size as Advanced SIMD modes. We then need to be specific about which mode we're dealing with. This patch prepares for that by switching based on the mode instead of querying properties. A later patch makes sure that Advanced SIMD modes always win over partial SVE vector modes in normal queries. 2019-08-13 Richard Sandiford gcc/ * config/aarch64/aarch64.c (aarch64_classify_vector_mode): Switch based on the mode instead of testing properties of it. From-SVN: r274368 --- gcc/ChangeLog | 5 +++ gcc/config/aarch64/aarch64.c | 86 ++++++++++++++++++++++++++++++-------------- 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b3a69bc79c2..c77cba1858a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2019-08-13 Richard Sandiford + * config/aarch64/aarch64.c (aarch64_classify_vector_mode): Switch + based on the mode instead of testing properties of it. + +2019-08-13 Richard Sandiford + * doc/md.texi: Document the x and y constraints for AArch64. * config/aarch64/aarch64.h (FP_LO8_REGNUM_P): New macro. (FP_LO8_REGS): New reg_class. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 6a674a3ff09..487e987f9b6 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -1474,34 +1474,68 @@ aarch64_classify_vector_mode (machine_mode mode) if (aarch64_sve_pred_mode_p (mode)) return VEC_SVE_PRED; - scalar_mode inner = GET_MODE_INNER (mode); - if (VECTOR_MODE_P (mode) - && (inner == QImode - || inner == HImode - || inner == HFmode - || inner == SImode - || inner == SFmode - || inner == DImode - || inner == DFmode)) - { - if (TARGET_SVE) - { - if (known_eq (GET_MODE_BITSIZE (mode), BITS_PER_SVE_VECTOR)) - return VEC_SVE_DATA; - if (known_eq (GET_MODE_BITSIZE (mode), BITS_PER_SVE_VECTOR * 2) - || known_eq (GET_MODE_BITSIZE (mode), BITS_PER_SVE_VECTOR * 3) - || known_eq (GET_MODE_BITSIZE (mode), BITS_PER_SVE_VECTOR * 4)) - return VEC_SVE_DATA | VEC_STRUCT; - } + /* Make the decision based on the mode's enum value rather than its + properties, so that we keep the correct classification regardless + of -msve-vector-bits. */ + switch (mode) + { + /* Single SVE vectors. */ + case E_VNx16QImode: + case E_VNx8HImode: + case E_VNx4SImode: + case E_VNx2DImode: + case E_VNx8HFmode: + case E_VNx4SFmode: + case E_VNx2DFmode: + return TARGET_SVE ? VEC_SVE_DATA : 0; + + /* x2 SVE vectors. */ + case E_VNx32QImode: + case E_VNx16HImode: + case E_VNx8SImode: + case E_VNx4DImode: + case E_VNx16HFmode: + case E_VNx8SFmode: + case E_VNx4DFmode: + /* x3 SVE vectors. */ + case E_VNx48QImode: + case E_VNx24HImode: + case E_VNx12SImode: + case E_VNx6DImode: + case E_VNx24HFmode: + case E_VNx12SFmode: + case E_VNx6DFmode: + /* x4 SVE vectors. */ + case E_VNx64QImode: + case E_VNx32HImode: + case E_VNx16SImode: + case E_VNx8DImode: + case E_VNx32HFmode: + case E_VNx16SFmode: + case E_VNx8DFmode: + return TARGET_SVE ? VEC_SVE_DATA | VEC_STRUCT : 0; + + /* 64-bit Advanced SIMD vectors. */ + case E_V8QImode: + case E_V4HImode: + case E_V2SImode: + /* ...E_V1DImode doesn't exist. */ + case E_V4HFmode: + case E_V2SFmode: + case E_V1DFmode: + /* 128-bit Advanced SIMD vectors. */ + case E_V16QImode: + case E_V8HImode: + case E_V4SImode: + case E_V2DImode: + case E_V8HFmode: + case E_V4SFmode: + case E_V2DFmode: + return TARGET_SIMD ? VEC_ADVSIMD : 0; - /* This includes V1DF but not V1DI (which doesn't exist). */ - if (TARGET_SIMD - && (known_eq (GET_MODE_BITSIZE (mode), 64) - || known_eq (GET_MODE_BITSIZE (mode), 128))) - return VEC_ADVSIMD; + default: + return 0; } - - return 0; } /* Return true if MODE is any of the data vector modes, including -- 2.11.4.GIT