This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 1/4] vldN_lane error message enhancements (Q registers)
- From: charles dot baylis at linaro dot org
- To: rearnsha at arm dot com, gcc-patches at gcc dot gnu dot org, marcus dot shawcroft at arm dot com, tejas dot belagod at arm dot com, alan dot lawrence at arm dot com
- Date: Tue, 9 Dec 2014 15:27:51 +0000
- Subject: [PATCH 1/4] vldN_lane error message enhancements (Q registers)
- Authentication-results: sourceware.org; auth=none
- References: <1418138874-13285-1-git-send-email-charles dot baylis at linaro dot org>
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
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;
+}
+
+
--
1.9.1