[AArch64] Make aarch64_classify_vector_mode use a switch statement

Richard Sandiford richard.sandiford@arm.com
Wed Aug 7 18:35:00 GMT 2019


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.

Tested on aarch64-linux-gnu (with and without SVE) and aarch64_be-elf.
OK to install?

Richard


2019-08-07  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* config/aarch64/aarch64.c (aarch64_classify_vector_mode): Switch
	based on the mode instead of testing properties of it.

Index: gcc/config/aarch64/aarch64.c
===================================================================
--- gcc/config/aarch64/aarch64.c	2019-08-07 19:17:05.931537111 +0100
+++ gcc/config/aarch64/aarch64.c	2019-08-07 19:19:52.018305243 +0100
@@ -1474,34 +1474,68 @@ aarch64_classify_vector_mode (machine_mo
   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))
+  /* 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)
     {
-      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;
-	}
+    /* 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;
 
-      /* 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;
-    }
+    /* 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;
 
-  return 0;
+    default:
+      return 0;
+    }
 }
 
 /* Return true if MODE is any of the data vector modes, including



More information about the Gcc-patches mailing list