diff mbox

[1/3,ARM] PR63870 NEON error messages

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

Commit Message

Charles Baylis July 2, 2015, 3:39 p.m. UTC
gcc/ChangeLog:

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

        * config/arm/arm-builtins.c (enum arm_type_qualifiers): New enumerators
	qualifier_lane_index, qualifier_struct_load_store_lane_index.
        (arm_expand_neon_args): New parameter. Remove ellipsis. Handle NEON
	argument qualifiers.
        (arm_expand_neon_builtin): Handle NEON argument qualifiers.
        * config/arm/arm-protos.h: (arm_neon_lane_bounds) New prototype.
        * config/arm/arm.c (arm_neon_lane_bounds): New function.
        * config/arm/arm.h (ENDIAN_LANE_N): New macro.

Change-Id: Iaa14d8736879fa53776319977eda2089f0a26647
---
 gcc/config/arm/arm-builtins.c | 65 ++++++++++++++++++++++++++++++++-----------
 gcc/config/arm/arm-protos.h   |  4 +++
 gcc/config/arm/arm.c          | 20 +++++++++++++
 gcc/config/arm/arm.h          |  3 ++
 4 files changed, 75 insertions(+), 17 deletions(-)

Comments

Alan Lawrence July 6, 2015, 10:18 a.m. UTC | #1
I note some parts of this duplicate my 
https://gcc.gnu.org/ml/gcc-patches/2015-01/msg01422.html , which has been pinged 
a couple of times. Both Charles' patch, and my two, contain parts the other does 
not...

Cheers, Alan

Charles Baylis wrote:
> gcc/ChangeLog:
> 
> <DATE>  Charles Baylis  <charles.baylis@linaro.org>
> 
>         * config/arm/arm-builtins.c (enum arm_type_qualifiers): New enumerators
>         qualifier_lane_index, qualifier_struct_load_store_lane_index.
>         (arm_expand_neon_args): New parameter. Remove ellipsis. Handle NEON
>         argument qualifiers.
>         (arm_expand_neon_builtin): Handle NEON argument qualifiers.
>         * config/arm/arm-protos.h: (arm_neon_lane_bounds) New prototype.
>         * config/arm/arm.c (arm_neon_lane_bounds): New function.
>         * config/arm/arm.h (ENDIAN_LANE_N): New macro.
> 
> Change-Id: Iaa14d8736879fa53776319977eda2089f0a26647
> ---
>  gcc/config/arm/arm-builtins.c | 65 ++++++++++++++++++++++++++++++++-----------
>  gcc/config/arm/arm-protos.h   |  4 +++
>  gcc/config/arm/arm.c          | 20 +++++++++++++
>  gcc/config/arm/arm.h          |  3 ++
>  4 files changed, 75 insertions(+), 17 deletions(-)
> 
> diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
> index f960e0a..8f1253e 100644
> --- a/gcc/config/arm/arm-builtins.c
> +++ b/gcc/config/arm/arm-builtins.c
> @@ -77,7 +77,11 @@ enum arm_type_qualifiers
>    /* qualifier_const_pointer | qualifier_map_mode  */
>    qualifier_const_pointer_map_mode = 0x86,
>    /* Polynomial types.  */
> -  qualifier_poly = 0x100
> +  qualifier_poly = 0x100,
> +  /* Lane indices - must be in range, and flipped for bigendian.  */
> +  qualifier_lane_index = 0x200,
> +  /* Lane indices for single lane structure loads and stores.  */
> +  qualifier_struct_load_store_lane_index = 0x400
>  };
> 
>  /*  The qualifier_internal allows generation of a unary builtin from
> @@ -1927,6 +1931,8 @@ arm_expand_unop_builtin (enum insn_code icode,
>  typedef enum {
>    NEON_ARG_COPY_TO_REG,
>    NEON_ARG_CONSTANT,
> +  NEON_ARG_LANE_INDEX,
> +  NEON_ARG_STRUCT_LOAD_STORE_LANE_INDEX,
>    NEON_ARG_MEMORY,
>    NEON_ARG_STOP
>  } builtin_arg;
> @@ -1984,9 +1990,9 @@ neon_dereference_pointer (tree exp, tree type, machine_mode mem_mode,
>  /* Expand a Neon builtin.  */
>  static rtx
>  arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
> -                     int icode, int have_retval, tree exp, ...)
> +                     int icode, int have_retval, tree exp,
> +                     builtin_arg *args)
>  {
> -  va_list ap;
>    rtx pat;
>    tree arg[SIMD_MAX_BUILTIN_ARGS];
>    rtx op[SIMD_MAX_BUILTIN_ARGS];
> @@ -2001,13 +2007,11 @@ arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
>           || !(*insn_data[icode].operand[0].predicate) (target, tmode)))
>      target = gen_reg_rtx (tmode);
> 
> -  va_start (ap, exp);
> -
>    formals = TYPE_ARG_TYPES (TREE_TYPE (arm_builtin_decls[fcode]));
> 
>    for (;;)
>      {
> -      builtin_arg thisarg = (builtin_arg) va_arg (ap, int);
> +      builtin_arg thisarg = args[argc];
> 
>        if (thisarg == NEON_ARG_STOP)
>         break;
> @@ -2043,17 +2047,46 @@ arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
>                 op[argc] = copy_to_mode_reg (mode[argc], op[argc]);
>               break;
> 
> +            case NEON_ARG_STRUCT_LOAD_STORE_LANE_INDEX:
> +             gcc_assert (argc > 1);
> +             if (CONST_INT_P (op[argc]))
> +               {
> +                 arm_neon_lane_bounds (op[argc], 0,
> +                                       GET_MODE_NUNITS (map_mode), exp);
> +                 /* Keep to GCC-vector-extension lane indices in the RTL.  */
> +                 op[argc] =
> +                   GEN_INT (ENDIAN_LANE_N (map_mode, INTVAL (op[argc])));
> +               }
> +             goto constant_arg;
> +
> +            case NEON_ARG_LANE_INDEX:
> +             /* Must be a previous operand into which this is an index.  */
> +             gcc_assert (argc > 0);
> +             if (CONST_INT_P (op[argc]))
> +               {
> +                 machine_mode vmode = insn_data[icode].operand[argc - 1].mode;
> +                 arm_neon_lane_bounds (op[argc],
> +                                       0, GET_MODE_NUNITS (vmode), exp);
> +                 /* Keep to GCC-vector-extension lane indices in the RTL.  */
> +                 op[argc] = GEN_INT (ENDIAN_LANE_N (vmode, INTVAL (op[argc])));
> +               }
> +             /* Fall through - if the lane index isn't a constant then
> +                the next case will error.  */
>             case NEON_ARG_CONSTANT:
> +constant_arg:
>               if (!(*insn_data[icode].operand[opno].predicate)
>                   (op[argc], mode[argc]))
> -               error_at (EXPR_LOCATION (exp), "incompatible type for argument %d, "
> -                      "expected %<const int%>", argc + 1);
> +               {
> +                 error ("%Kargument %d must be a constant immediate",
> +                        exp, argc + 1);
> +                 return const0_rtx;
> +               }
>               break;
> +
>              case NEON_ARG_MEMORY:
>               /* Check if expand failed.  */
>               if (op[argc] == const0_rtx)
>               {
> -               va_end (ap);
>                 return 0;
>               }
>               gcc_assert (MEM_P (op[argc]));
> @@ -2076,8 +2109,6 @@ arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
>         }
>      }
> 
> -  va_end (ap);
> -
>    if (have_retval)
>      switch (argc)
>        {
> @@ -2170,7 +2201,11 @@ arm_expand_neon_builtin (int fcode, tree exp, rtx target)
>        int operands_k = k - is_void;
>        int expr_args_k = k - 1;
> 
> -      if (d->qualifiers[qualifiers_k] & qualifier_immediate)
> +      if (d->qualifiers[qualifiers_k] & qualifier_lane_index)
> +        args[k] = NEON_ARG_LANE_INDEX;
> +      else if (d->qualifiers[qualifiers_k] & qualifier_struct_load_store_lane_index)
> +        args[k] = NEON_ARG_STRUCT_LOAD_STORE_LANE_INDEX;
> +      else if (d->qualifiers[qualifiers_k] & qualifier_immediate)
>         args[k] = NEON_ARG_CONSTANT;
>        else if (d->qualifiers[qualifiers_k] & qualifier_maybe_immediate)
>         {
> @@ -2195,11 +2230,7 @@ arm_expand_neon_builtin (int fcode, tree exp, rtx target)
>       the function is void, and a 1 if it is not.  */
>    return arm_expand_neon_args
>           (target, d->mode, fcode, icode, !is_void, exp,
> -          args[1],
> -          args[2],
> -          args[3],
> -          args[4],
> -          NEON_ARG_STOP);
> +          &args[1]);
>  }
> 
>  /* Expand an expression EXP that calls a built-in function,
> diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
> index 62f91ef..0b4bef5 100644
> --- a/gcc/config/arm/arm-protos.h
> +++ b/gcc/config/arm/arm-protos.h
> @@ -343,6 +343,10 @@ extern void arm_cpu_builtins (struct cpp_reader *, int);
> 
>  extern bool arm_is_constant_pool_ref (rtx);
> 
> +void arm_neon_lane_bounds (rtx operand, HOST_WIDE_INT low, HOST_WIDE_INT high,
> +                          const_tree exp);
> +
> +
>  /* Flags used to identify the presence of processor capabilities.  */
> 
>  /* Bit values used to identify processor capabilities.  */
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index d794fc0..2cbfd64 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -29652,4 +29652,24 @@ arm_sched_fusion_priority (rtx_insn *insn, int max_pri,
>    *pri = tmp;
>    return;
>  }
> +
> +/* Bounds-check lanes.  Ensure OPERAND lies between LOW (inclusive) and
> +   HIGH (exclusive).  */
> +void
> +arm_neon_lane_bounds (rtx operand, HOST_WIDE_INT low, HOST_WIDE_INT high,
> +                     const_tree exp)
> +{
> +  HOST_WIDE_INT lane;
> +  gcc_assert (CONST_INT_P (operand));
> +  lane = INTVAL (operand);
> +
> +  if (lane < low || lane >= high)
> +  {
> +    if (exp)
> +      error ("%Klane %ld out of range %ld - %ld", exp, lane, low, high - 1);
> +    else
> +      error ("lane %ld out of range %ld - %ld", lane, low, high - 1);
> +  }
> +}
> +
>  #include "gt-arm.h"
> diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
> index 373dc85..1a55ac8 100644
> --- a/gcc/config/arm/arm.h
> +++ b/gcc/config/arm/arm.h
> @@ -298,6 +298,9 @@ extern void (*arm_lang_output_object_attributes_hook)(void);
>  #define TARGET_BPABI false
>  #endif
> 
> +#define ENDIAN_LANE_N(mode, n)  \
> +  (BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 - n : n)
> +
>  /* Support for a compile-time default CPU, et cetera.  The rules are:
>     --with-arch is ignored if -march or -mcpu are specified.
>     --with-cpu is ignored if -march or -mcpu are specified, and is overridden
> --
> 1.9.1
> 
>
Alan Lawrence July 7, 2015, 12:30 p.m. UTC | #2
Alan Lawrence wrote:
> I note some parts of this duplicate my
> https://gcc.gnu.org/ml/gcc-patches/2015-01/msg01422.html , which has been pinged
> a couple of times. Both Charles' patch, and my two, contain parts the other does
> not...
> 
> Cheers, Alan
> 
> Charles Baylis wrote:
>> gcc/ChangeLog:
>>
>> <DATE>  Charles Baylis  <charles.baylis@linaro.org>
>>
>>         * config/arm/arm-builtins.c (enum arm_type_qualifiers): New enumerators
>>         qualifier_lane_index, qualifier_struct_load_store_lane_index.
>>         (arm_expand_neon_args): New parameter. Remove ellipsis. Handle NEON
>>         argument qualifiers.
>>         (arm_expand_neon_builtin): Handle NEON argument qualifiers.
>>         * config/arm/arm-protos.h: (arm_neon_lane_bounds) New prototype.
>>         * config/arm/arm.c (arm_neon_lane_bounds): New function.

Further to that - the main difference/conflict between Charles' patch and mine 
looks to be that I added the const_tree parameter to the existing 
neon_lane_bounds method, whereas Charles' patch adds a new method 
arm_neon_lane_bounds.

--Alan
Charles Baylis July 7, 2015, 7:03 p.m. UTC | #3
On 6 July 2015 at 11:18, Alan Lawrence <alan.lawrence@arm.com> wrote:
> I note some parts of this duplicate my
> https://gcc.gnu.org/ml/gcc-patches/2015-01/msg01422.html , which has been
> pinged a couple of times. Both Charles' patch, and my two, contain parts the
> other does not...

To resolve the conflicts, I suggest that Alan's patches should be
applied as-is first, and I'll rebase mine afterwards.

...and...

> Further to that - the main difference/conflict between Charles' patch and mine
> looks to be that I added the const_tree parameter to the existing
> neon_lane_bounds method, whereas Charles' patch adds a new method
> arm_neon_lane_bounds.

... I'll clean up this duplication when I do.
diff mbox

Patch

diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index f960e0a..8f1253e 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -77,7 +77,11 @@  enum arm_type_qualifiers
   /* qualifier_const_pointer | qualifier_map_mode  */
   qualifier_const_pointer_map_mode = 0x86,
   /* Polynomial types.  */
-  qualifier_poly = 0x100
+  qualifier_poly = 0x100,
+  /* Lane indices - must be in range, and flipped for bigendian.  */
+  qualifier_lane_index = 0x200,
+  /* Lane indices for single lane structure loads and stores.  */
+  qualifier_struct_load_store_lane_index = 0x400
 };
 
 /*  The qualifier_internal allows generation of a unary builtin from
@@ -1927,6 +1931,8 @@  arm_expand_unop_builtin (enum insn_code icode,
 typedef enum {
   NEON_ARG_COPY_TO_REG,
   NEON_ARG_CONSTANT,
+  NEON_ARG_LANE_INDEX,
+  NEON_ARG_STRUCT_LOAD_STORE_LANE_INDEX,
   NEON_ARG_MEMORY,
   NEON_ARG_STOP
 } builtin_arg;
@@ -1984,9 +1990,9 @@  neon_dereference_pointer (tree exp, tree type, machine_mode mem_mode,
 /* Expand a Neon builtin.  */
 static rtx
 arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
-		      int icode, int have_retval, tree exp, ...)
+		      int icode, int have_retval, tree exp,
+		      builtin_arg *args)
 {
-  va_list ap;
   rtx pat;
   tree arg[SIMD_MAX_BUILTIN_ARGS];
   rtx op[SIMD_MAX_BUILTIN_ARGS];
@@ -2001,13 +2007,11 @@  arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
 	  || !(*insn_data[icode].operand[0].predicate) (target, tmode)))
     target = gen_reg_rtx (tmode);
 
-  va_start (ap, exp);
-
   formals = TYPE_ARG_TYPES (TREE_TYPE (arm_builtin_decls[fcode]));
 
   for (;;)
     {
-      builtin_arg thisarg = (builtin_arg) va_arg (ap, int);
+      builtin_arg thisarg = args[argc];
 
       if (thisarg == NEON_ARG_STOP)
 	break;
@@ -2043,17 +2047,46 @@  arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
 		op[argc] = copy_to_mode_reg (mode[argc], op[argc]);
 	      break;
 
+            case NEON_ARG_STRUCT_LOAD_STORE_LANE_INDEX:
+	      gcc_assert (argc > 1);
+	      if (CONST_INT_P (op[argc]))
+		{
+		  arm_neon_lane_bounds (op[argc], 0,
+					GET_MODE_NUNITS (map_mode), exp);
+		  /* Keep to GCC-vector-extension lane indices in the RTL.  */
+		  op[argc] =
+		    GEN_INT (ENDIAN_LANE_N (map_mode, INTVAL (op[argc])));
+		}
+	      goto constant_arg;
+
+            case NEON_ARG_LANE_INDEX:
+	      /* Must be a previous operand into which this is an index.  */
+	      gcc_assert (argc > 0);
+	      if (CONST_INT_P (op[argc]))
+		{
+		  machine_mode vmode = insn_data[icode].operand[argc - 1].mode;
+		  arm_neon_lane_bounds (op[argc],
+					0, GET_MODE_NUNITS (vmode), exp);
+		  /* Keep to GCC-vector-extension lane indices in the RTL.  */
+		  op[argc] = GEN_INT (ENDIAN_LANE_N (vmode, INTVAL (op[argc])));
+		}
+	      /* Fall through - if the lane index isn't a constant then
+	         the next case will error.  */
 	    case NEON_ARG_CONSTANT:
+constant_arg:
 	      if (!(*insn_data[icode].operand[opno].predicate)
 		  (op[argc], mode[argc]))
-		error_at (EXPR_LOCATION (exp), "incompatible type for argument %d, "
-		       "expected %<const int%>", argc + 1);
+		{
+		  error ("%Kargument %d must be a constant immediate",
+			 exp, argc + 1);
+		  return const0_rtx;
+		}
 	      break;
+
             case NEON_ARG_MEMORY:
 	      /* Check if expand failed.  */
 	      if (op[argc] == const0_rtx)
 	      {
-		va_end (ap);
 		return 0;
 	      }
 	      gcc_assert (MEM_P (op[argc]));
@@ -2076,8 +2109,6 @@  arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
 	}
     }
 
-  va_end (ap);
-
   if (have_retval)
     switch (argc)
       {
@@ -2170,7 +2201,11 @@  arm_expand_neon_builtin (int fcode, tree exp, rtx target)
       int operands_k = k - is_void;
       int expr_args_k = k - 1;
 
-      if (d->qualifiers[qualifiers_k] & qualifier_immediate)
+      if (d->qualifiers[qualifiers_k] & qualifier_lane_index)
+        args[k] = NEON_ARG_LANE_INDEX;
+      else if (d->qualifiers[qualifiers_k] & qualifier_struct_load_store_lane_index)
+        args[k] = NEON_ARG_STRUCT_LOAD_STORE_LANE_INDEX;
+      else if (d->qualifiers[qualifiers_k] & qualifier_immediate)
 	args[k] = NEON_ARG_CONSTANT;
       else if (d->qualifiers[qualifiers_k] & qualifier_maybe_immediate)
 	{
@@ -2195,11 +2230,7 @@  arm_expand_neon_builtin (int fcode, tree exp, rtx target)
      the function is void, and a 1 if it is not.  */
   return arm_expand_neon_args
 	  (target, d->mode, fcode, icode, !is_void, exp,
-	   args[1],
-	   args[2],
-	   args[3],
-	   args[4],
-	   NEON_ARG_STOP);
+	   &args[1]);
 }
 
 /* Expand an expression EXP that calls a built-in function,
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 62f91ef..0b4bef5 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -343,6 +343,10 @@  extern void arm_cpu_builtins (struct cpp_reader *, int);
 
 extern bool arm_is_constant_pool_ref (rtx);
 
+void arm_neon_lane_bounds (rtx operand, HOST_WIDE_INT low, HOST_WIDE_INT high,
+			   const_tree exp);
+
+
 /* Flags used to identify the presence of processor capabilities.  */
 
 /* Bit values used to identify processor capabilities.  */
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index d794fc0..2cbfd64 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -29652,4 +29652,24 @@  arm_sched_fusion_priority (rtx_insn *insn, int max_pri,
   *pri = tmp;
   return;
 }
+
+/* Bounds-check lanes.  Ensure OPERAND lies between LOW (inclusive) and
+   HIGH (exclusive).  */
+void
+arm_neon_lane_bounds (rtx operand, HOST_WIDE_INT low, HOST_WIDE_INT high,
+		      const_tree exp)
+{
+  HOST_WIDE_INT lane;
+  gcc_assert (CONST_INT_P (operand));
+  lane = INTVAL (operand);
+
+  if (lane < low || lane >= high)
+  {
+    if (exp)
+      error ("%Klane %ld out of range %ld - %ld", exp, lane, low, high - 1);
+    else
+      error ("lane %ld out of range %ld - %ld", lane, low, high - 1);
+  }
+}
+
 #include "gt-arm.h"
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 373dc85..1a55ac8 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -298,6 +298,9 @@  extern void (*arm_lang_output_object_attributes_hook)(void);
 #define TARGET_BPABI false
 #endif
 
+#define ENDIAN_LANE_N(mode, n)  \
+  (BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 - n : n)
+
 /* Support for a compile-time default CPU, et cetera.  The rules are:
    --with-arch is ignored if -march or -mcpu are specified.
    --with-cpu is ignored if -march or -mcpu are specified, and is overridden