diff mbox

[1/4] vldN_lane error message enhancements (Q registers)

Message ID 1418138874-13285-2-git-send-email-charles.baylis@linaro.org
State New
Headers show

Commit Message

Charles Baylis Dec. 9, 2014, 3:27 p.m. UTC
From: Charles Baylis <charles.baylis@linaro.org>

gcc/ChangeLog:

<DATE>  Charles Baylis  <charles.baylis@linaro.org>

	PR target/63870
        * config/aarch64/aarch64-builtins.c (enum aarch64_type_qualifiers):
	Add qualifier_struct_load_store_lane_index.
	(aarch64_types_loadstruct_lane_qualifiers): Use
	qualifier_struct_load_store_lane_index for lane index argument for
	last argument.
	(builtin_simd_arg): Add SIMD_ARG_STRUCT_LOAD_STORE_LANE_INDEX.
        (aarch64_simd_expand_args): Add new argument describing mode of
	builtin. Check lane bounds for arguments with
	SIMD_ARG_STRUCT_LOAD_STORE_LANE_INDEX.
        (aarch64_simd_expand_builtin): Emit error for incorrect lane indices
	if marked with SIMD_ARG_STRUCT_LOAD_STORE_LANE_INDEX.
	(aarch64_simd_expand_builtin): Pass machine mode of builtin to
	aarch64_simd_expand_args.
        * config/aarch64/aarch64-simd.md: (aarch64_ld2_lane<mode>): Remove
	lane bounds check. Adjust lane numbers for big-endian.
	(aarch64_ld3_lane<mode>): Likewise.
	(aarch64_ld4_lane<mode>): Likewise.

gcc/testsuite/ChangeLog:

<DATE>  Charles Baylis  <charles.baylis@linaro.org>

        * gcc.target/aarch64/simd/vld4q_lane.c: New test.

Change-Id: Ib17adaf64e631cf8d00a1a1a6c12409d2d7f4239
---
 gcc/config/aarch64/aarch64-builtins.c              | 30 +++++++++++++++++++---
 gcc/config/aarch64/aarch64-simd.md                 | 12 ++++-----
 gcc/testsuite/gcc.target/aarch64/simd/vld4q_lane.c | 16 ++++++++++++
 3 files changed, 48 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/simd/vld4q_lane.c

Comments

Charles Baylis April 14, 2015, 4:30 p.m. UTC | #1
On 14 April 2015 at 14:45, Alan Lawrence <alan.lawrence@arm.com> wrote:

> Assuming/hoping that this patch is proposed for new stage 1 ;),

IIRC the approach of using __builtin_aarch64_im_lane_boundsi doesn't
work (results in double error messages), and so the patch needs to be
rewritten to avoid it. However, thanks for your comments, I'll reflect
those in the next version of the patch.

Thanks
Charles
Alan Lawrence April 14, 2015, 5:20 p.m. UTC | #2
That happens in your patch 2/3/4, which use __builtin_aarch64_im_lane_boundsi, 
indeed. Hence I think the SIMD_ARG_STRUCT_LOAD_STORE_LANE_INDEX approach of the 
first patch could well be the right way - initially I thought SIMD_ARG... too 
heavyweight, but I think I take that back now.

Really I think we should clean up and stop using q-reg intrinsics to handle 
d-regs here. I'm working on a few patches (i.e. targetting the v{st,ld}{2,3,4}* 
intrinsics) with that aim now, I think I can make some efficiency improvements 
in the process, too....

--Alan

Charles Baylis wrote:
> On 14 April 2015 at 14:45, Alan Lawrence <alan.lawrence@arm.com> wrote:
> 
>> Assuming/hoping that this patch is proposed for new stage 1 ;),
> 
> IIRC the approach of using __builtin_aarch64_im_lane_boundsi doesn't
> work (results in double error messages), and so the patch needs to be
> rewritten to avoid it. However, thanks for your comments, I'll reflect
> those in the next version of the patch.
> 
> Thanks
> Charles
>
diff mbox

Patch

diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c
index aac7269..27046e2 100644
--- a/gcc/config/aarch64/aarch64-builtins.c
+++ b/gcc/config/aarch64/aarch64-builtins.c
@@ -116,7 +116,9 @@  enum aarch64_type_qualifiers
   /* Polynomial types.  */
   qualifier_poly = 0x100,
   /* Lane indices - must be in range, and flipped for bigendian.  */
-  qualifier_lane_index = 0x200
+  qualifier_lane_index = 0x200,
+  /* Lane indices for single lane structure loads and stores */
+  qualifier_struct_load_store_lane_index = 0x400
 };
 
 typedef struct
@@ -224,7 +226,7 @@  aarch64_types_load1_qualifiers[SIMD_MAX_BUILTIN_ARGS]
 static enum aarch64_type_qualifiers
 aarch64_types_loadstruct_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
   = { qualifier_none, qualifier_const_pointer_map_mode,
-      qualifier_none, qualifier_none };
+      qualifier_none, qualifier_struct_load_store_lane_index };
 #define TYPES_LOADSTRUCT_LANE (aarch64_types_loadstruct_lane_qualifiers)
 
 static enum aarch64_type_qualifiers
@@ -859,12 +861,14 @@  typedef enum
   SIMD_ARG_COPY_TO_REG,
   SIMD_ARG_CONSTANT,
   SIMD_ARG_LANE_INDEX,
+  SIMD_ARG_STRUCT_LOAD_STORE_LANE_INDEX,
   SIMD_ARG_STOP
 } builtin_simd_arg;
 
 static rtx
 aarch64_simd_expand_args (rtx target, int icode, int have_retval,
-			  tree exp, builtin_simd_arg *args)
+			  tree exp, builtin_simd_arg *args,
+			  enum machine_mode builtin_mode)
 {
   rtx pat;
   rtx op[SIMD_MAX_BUILTIN_ARGS + 1]; /* First element for result operand.  */
@@ -903,6 +907,21 @@  aarch64_simd_expand_args (rtx target, int icode, int have_retval,
 		op[opc] = copy_to_mode_reg (mode, op[opc]);
 	      break;
 
+	    case SIMD_ARG_STRUCT_LOAD_STORE_LANE_INDEX:
+	      /* we expect arguments in order (ptr, array_of_vector, lane), and
+		 we have to grub around in the ptr to find the lane size */
+	      gcc_assert (opc > 1);
+	      if (CONST_INT_P (op[opc]))
+		{
+		  aarch64_simd_lane_bounds (op[opc], 0,
+					    GET_MODE_NUNITS (builtin_mode),
+					    exp);
+		  /* Keep to GCC-vector-extension lane indices in the RTL.  */
+		  op[opc] =
+		    GEN_INT (ENDIAN_LANE_N (builtin_mode, INTVAL (op[opc])));
+		}
+	      goto constant_arg;
+
 	    case SIMD_ARG_LANE_INDEX:
 	      /* Must be a previous operand into which this is an index.  */
 	      gcc_assert (opc > 0);
@@ -917,6 +936,7 @@  aarch64_simd_expand_args (rtx target, int icode, int have_retval,
 	      /* Fall through - if the lane index isn't a constant then
 		 the next case will error.  */
 	    case SIMD_ARG_CONSTANT:
+constant_arg:
 	      if (!(*insn_data[icode].operand[opc].predicate)
 		  (op[opc], mode))
 	      {
@@ -1003,6 +1023,8 @@  aarch64_simd_expand_builtin (int fcode, tree exp, rtx target)
 
       if (d->qualifiers[qualifiers_k] & qualifier_lane_index)
 	args[k] = SIMD_ARG_LANE_INDEX;
+      else if (d->qualifiers[qualifiers_k] & qualifier_struct_load_store_lane_index)
+	args[k] = SIMD_ARG_STRUCT_LOAD_STORE_LANE_INDEX;
       else if (d->qualifiers[qualifiers_k] & qualifier_immediate)
 	args[k] = SIMD_ARG_CONSTANT;
       else if (d->qualifiers[qualifiers_k] & qualifier_maybe_immediate)
@@ -1026,7 +1048,7 @@  aarch64_simd_expand_builtin (int fcode, tree exp, rtx target)
   /* The interface to aarch64_simd_expand_args expects a 0 if
      the function is void, and a 1 if it is not.  */
   return aarch64_simd_expand_args
-	  (target, icode, !is_void, exp, &args[1]);
+	  (target, icode, !is_void, exp, &args[1], d->mode);
 }
 
 rtx
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 0ec1323..beac497 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -4397,8 +4397,8 @@ 
   machine_mode mode = <V_TWO_ELEM>mode;
   rtx mem = gen_rtx_MEM (mode, operands[1]);
 
-  aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode),
-			    NULL);
+  operands[3] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[3])));
+
   emit_insn (gen_aarch64_vec_load_lanesoi_lane<mode> (operands[0],
 						      mem,
 						      operands[2],
@@ -4417,8 +4417,8 @@ 
   machine_mode mode = <V_THREE_ELEM>mode;
   rtx mem = gen_rtx_MEM (mode, operands[1]);
 
-  aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode),
-			    NULL);
+  operands[3] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[3])));
+
   emit_insn (gen_aarch64_vec_load_lanesci_lane<mode> (operands[0],
 						      mem,
 						      operands[2],
@@ -4437,8 +4437,8 @@ 
   machine_mode mode = <V_FOUR_ELEM>mode;
   rtx mem = gen_rtx_MEM (mode, operands[1]);
 
-  aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode),
-			    NULL);
+  operands[3] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[3])));
+
   emit_insn (gen_aarch64_vec_load_lanesxi_lane<mode> (operands[0],
 						      mem,
 						      operands[2],
diff --git a/gcc/testsuite/gcc.target/aarch64/simd/vld4q_lane.c b/gcc/testsuite/gcc.target/aarch64/simd/vld4q_lane.c
new file mode 100644
index 0000000..c673ded
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/simd/vld4q_lane.c
@@ -0,0 +1,16 @@ 
+/* Test error message when passing an invalid value as a lane index.  */
+
+/* { dg-do compile } */
+
+#include <arm_neon.h>
+
+/* { dg-error "lane 8 out of range 0 - 7" "" { target *-*-* } 0 } */
+int16x8x4_t
+f_vld4_lane (int16_t * p, int16x8x4_t v)
+{
+  int16x8x4_t res;
+  res = vld4q_lane_s16 (p, v, 8);
+  return res;
+}
+
+