diff mbox series

[2/4,Aarch64] v2: Implement Aarch64 SIMD ABI

Message ID d5734fee1fd3b6065ca9d8842f9de4cb7ad4fc0a.camel@marvell.com
State New
Headers show
Series None | expand

Commit Message

Steve Ellcey Dec. 11, 2018, 11:10 p.m. UTC
This is the modified version of the second of my Aarch64 SIMD ABI patches.
While implementing this functionality I found I wanted
targetm.simd_clone.adjust to be called when creating SIMD clone definitions
and also when creating SIMD clone declarations.  The current
implementation (used only by x86) only called this target function when
creating clone definitions.  I added a second argument to the target
function to say if it was creating a definition or a declaration and
modified the i386 code to do nothing on declarations, thus maintaining
its current behavour.

This allowed my to add the aarch64_vector_pcs attribute to SIMD clone
declarations and definitions on Aarch64. 

I considered comparing node->decl and cfun->decl to differentiate
between definitions and declarations instead of using a new argument
but having an argument seemed cleaner and clearer.

Tested on x86 and aarch64.

Steve Ellcey
sellcey@marvell.com


2018-12-11  Steve Ellcey  <sellcey@cavium.com>

	* config/aarch64/aarch64.c (cgraph.h): New include.
	(aarch64_simd_clone_compute_vecsize_and_simdlen): New function.
	(aarch64_simd_clone_adjust): Ditto.
	(aarch64_simd_clone_usable): Ditto.
	(TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN): New macro.
	(TARGET_SIMD_CLONE_ADJUST): Ditto.
	(TARGET_SIMD_CLONE_USABLE): Ditto.
	* config/i386/i386.c (ix86_simd_clone_adjust): Add new argument.
	* omp-simd-clone.c (simd_clone_adjust): Add new argument
	to targetm.simd_clone.adjust call.
	(expand_simd_clones): Add new targetm.simd_clone.adjust call.
	* target.def (simd_clone_adjust): Add new argument.

Comments

Richard Sandiford Dec. 12, 2018, 12:34 p.m. UTC | #1
Steve Ellcey <sellcey@marvell.com> writes:
> This is the modified version of the second of my Aarch64 SIMD ABI patches.
> While implementing this functionality I found I wanted
> targetm.simd_clone.adjust to be called when creating SIMD clone definitions
> and also when creating SIMD clone declarations.  The current
> implementation (used only by x86) only called this target function when
> creating clone definitions.  I added a second argument to the target
> function to say if it was creating a definition or a declaration and
> modified the i386 code to do nothing on declarations, thus maintaining
> its current behavour.
>
> This allowed my to add the aarch64_vector_pcs attribute to SIMD clone
> declarations and definitions on Aarch64. 
>
> I considered comparing node->decl and cfun->decl to differentiate
> between definitions and declarations instead of using a new argument
> but having an argument seemed cleaner and clearer.

Yeah, agreed.

> +  tree ret_type = TREE_TYPE (TREE_TYPE (node->decl));
> +  if (TREE_CODE (ret_type) != VOID_TYPE)
> +    switch (TYPE_MODE (ret_type))
> +      {
> +      case E_QImode:
> +      case E_HImode:
> +      case E_SImode:
> +      case E_DImode:
> +      case E_SFmode:
> +      case E_DFmode:
> +      /* case E_SCmode: */
> +      /* case E_DCmode: */
> +	break;
> +      default:
> +	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
> +		    "unsupported return type %qT for simd\n", ret_type);
> +	return 0;
> +      }

I think this should be using the tree-level properties of the type
rather than the mode.  E.g.:

    struct S { int i[1]; };

has SImode (I think) but the vector ABI's "PBV" property is false for that.

I think we then need to separate cases in which the code is warning
about things that are invalid according to the vector ABI vs. those
that GCC simply doesn't support yet.  At the moment I think there's
an implicit requirement in the vector ABI that PBV has to be true for
non-void return types, so warning about the struct above would be a
correctness test.

But as the commented-out lines say, complex types are also valid,
so if we don't support those yet, I think the warning should say
something like "GCC does not yet support ...".  ("sorry (...)" is
too strong, since it's error-class.)

We should handle 16-bit floats as well.

> +  tree t;
> +  for (t = DECL_ARGUMENTS (node->decl); t; t = DECL_CHAIN (t))
> +    /* FIXME: Shouldn't we allow such arguments if they are uniform?  */

Yeah.

> +    switch (TYPE_MODE (TREE_TYPE (t)))
> +      {
> +      case E_QImode:
> +      case E_HImode:
> +      case E_SImode:
> +      case E_DImode:
> +      case E_SFmode:
> +      case E_DFmode:
> +      /* case E_SCmode: */
> +      /* case E_DCmode: */
> +	break;
> +      default:
> +	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
> +		    "unsupported argument type %qT for simd\n", TREE_TYPE (t));
> +	return 0;
> +      }

Same comments here.  The vector ABI doesn't place this restriction on
parameters: if PBV is false, the elements are passed by pointer instead.

> +
> +  if (TARGET_SIMD)
> +    {
> +    clonei->vecsize_mangle = 'n';
> +    clonei->mask_mode = VOIDmode;
> +    clonei->vecsize_int = 128;
> +    clonei->vecsize_float = 128;
> +
> +    if (clonei->simdlen == 0)
> +      {
> +      if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
> +	clonei->simdlen = clonei->vecsize_int;
> +      else
> +	clonei->simdlen = clonei->vecsize_float;
> +      clonei->simdlen /= GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type));

Are we sure base_type is correct for the AArch64 vector ABI?
I think at the moment it's specific to the Intel ABI.

> +      }
> +    else if (clonei->simdlen > 16)
> +      {
> +      /* If it is possible for given SIMDLEN to pass CTYPE value in
> +	 registers (v0-v7) accept that SIMDLEN, otherwise warn and don't
> +	 emit corresponding clone.  */

This too would be a GCC restriction rather than an ABI one.  Could you
add a comment explaning why we need it?

> +/* If SIMD clone NODE can't be used in a vectorized loop
> +   in current function, return -1, otherwise return a badness of using it
> +   (0 if it is most desirable from vecsize_mangle point of view, 1
> +   slightly less desirable, etc.).  */
> +
> +static int
> +aarch64_simd_clone_usable (struct cgraph_node *node)

Think this should just say:

/* Implement TARGET_SIMD_CLONE_USABLE.  */

instead of duplicating the hook definition.  Maybe there's something
AArch64-specific we can add, but doesn't matter if not.

> diff --git a/gcc/target.def b/gcc/target.def
> index 96f37e0..ffc3787 100644
> --- a/gcc/target.def
> +++ b/gcc/target.def
> @@ -1632,8 +1632,10 @@ int, (struct cgraph_node *, struct cgraph_simd_clone *, tree, int), NULL)
>  DEFHOOK
>  (adjust,
>  "This hook should add implicit @code{attribute(target(\"...\"))} attribute\n\
> -to SIMD clone @var{node} if needed.",
> -void, (struct cgraph_node *), NULL)
> +to SIMD clone @var{node} if needed.  If the @var{defn} bool argument is true\n\
> +then this function is being called for a function definition, if false it is\n\
> +a function declaration.",
> +void, (struct cgraph_node *, bool), NULL)

Maybe "this hook is being called", to avoid confusion with the function
argument.  It's a pre-existing bug, but the prototype should have names
if the comment refers to them:

 void, (struct cgraph_node *node, bool defn), NULL)

Thanks,
Richard
Jakub Jelinek Dec. 12, 2018, 12:41 p.m. UTC | #2
On Wed, Dec 12, 2018 at 12:34:46PM +0000, Richard Sandiford wrote:
> > I considered comparing node->decl and cfun->decl to differentiate
> > between definitions and declarations instead of using a new argument
> > but having an argument seemed cleaner and clearer.
> 
> Yeah, agreed.

I actually disagree, there is no point in passing another argument.
You should be able to just check node->definition whether it is a definition
or declaration.

	Jakub
Steve Ellcey Dec. 12, 2018, 6:19 p.m. UTC | #3
On Wed, 2018-12-12 at 13:41 +0100, Jakub Jelinek wrote:
> External Email
> 
> -------------------------------------------------------------------
> ---
> On Wed, Dec 12, 2018 at 12:34:46PM +0000, Richard Sandiford wrote:
> > > I considered comparing node->decl and cfun->decl to differentiate
> > > between definitions and declarations instead of using a new
> > > argument
> > > but having an argument seemed cleaner and clearer.
> > 
> > Yeah, agreed.
> 
> I actually disagree, there is no point in passing another argument.
> You should be able to just check node->definition whether it is a
> definition
> or declaration.
> 
> 	Jakub

You are right, I can just use node->definition and not add the new
argument.  I will make that change.

Steve Ellcey
sellcey@cavium.com
Steve Ellcey Dec. 19, 2018, 10:10 p.m. UTC | #4
Here is an updated version of the GCC patch to enable SIMD functions on
Aarch64.  There are a number of changes from the last patch.

I reduced the shared code changes, there is still one change in shared code
(omp-simd-clone.c) to call targetm.simd_clone.adjust from expand_simd_clones
but it now uses the same argument as the existing call.  This new call allows
Aarch64 to add the aarch64_vector_pcs attribute to SIMD clone definitions
which in turn ensures they use the correct ABI.  Previously this target
function was only called on declarations, not definitions.  This change affects
the x86 target so I modified ix86_simd_clone_adjust to return and do nothing
when called with a definition.  This means there is no change in behaviour
on x86.  I did a build and GCC testsuite run on x86 to verify this.

Most of the changes from the previous patch are in the
aarch64_simd_clone_compute_vecsize_and_simdlen function.

The previous version was heavily based on the x86 function, this one has
changes to address the issues that were raised in the earlier patch
and so it no longer looks like the x86 version.  I use types instead of modes
to check for what we can/cannot vectorize and I (try to) differentiate
between vectors that we are not currently handling (but could later) and
those that won't ever be handled.

I have also added a testsuite patch to fix regressions in the gcc.dg/gomp
and g++.dg/gomp tests.  There are no regressions with this patch applied.

Steve Ellcey
sellcey@marvell.com


2018-12-19  Steve Ellcey  <sellcey@cavium.com>

	* config/aarch64/aarch64.c (cgraph.h): New include.
	(supported_simd_type): New function.
	(currently_supported_simd_type): Ditto.
	(aarch64_simd_clone_compute_vecsize_and_simdlen): Ditto.
	(aarch64_simd_clone_adjust): Ditto.
	(aarch64_simd_clone_usable): Ditto.
	(TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN): New macro.
	(TARGET_SIMD_CLONE_ADJUST): Ditto.
	(TARGET_SIMD_CLONE_USABLE): Ditto.
	* config/i386/i386.c (ix86_simd_clone_adjust): Add definition check.
	* omp-simd-clone.c (expand_simd_clones): Add targetm.simd_clone.adjust
	call.

2018-12-19  Steve Ellcey  <sellcey@cavium.com>

	* g++.dg/gomp/declare-simd-1.C: Add aarch64 specific
	warning checks and assembler scans.
	* g++.dg/gomp/declare-simd-3.C: Ditto.
	* g++.dg/gomp/declare-simd-4.C: Ditto.
	* g++.dg/gomp/declare-simd-7.C: Ditto.
	* gcc.dg/gomp/declare-simd-1.c: Ditto.
	* gcc.dg/gomp/declare-simd-3.c: Ditto.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 6038494..e61f6e1 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -40,6 +40,7 @@
 #include "regs.h"
 #include "emit-rtl.h"
 #include "recog.h"
+#include "cgraph.h"
 #include "diagnostic.h"
 #include "insn-attr.h"
 #include "alias.h"
@@ -71,6 +72,7 @@
 #include "selftest.h"
 #include "selftest-rtl.h"
 #include "rtx-vector-builder.h"
+#include "intl.h"
 
 /* This file should be included last.  */
 #include "target-def.h"
@@ -18064,6 +18066,138 @@ aarch64_estimated_poly_value (poly_int64 val)
   return val.coeffs[0] + val.coeffs[1] * over_128 / 128;
 }
 
+
+/* Return true for types that could be supported as SIMD return or
+   argument types.  */
+
+static bool supported_simd_type (tree t)
+{
+  return (FLOAT_TYPE_P (t) || INTEGRAL_TYPE_P (t));
+}
+
+/* Return true for types that currently are supported as SIMD return
+   or argument types.  */
+
+static bool currently_supported_simd_type (tree t)
+{
+  if (COMPLEX_FLOAT_TYPE_P (t))
+    return false;
+
+  return supported_simd_type (t);
+}
+
+/* Implement TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN.  */
+
+static int
+aarch64_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
+					struct cgraph_simd_clone *clonei,
+					tree base_type,
+					int num ATTRIBUTE_UNUSED)
+{
+  const char *wmsg;
+  int vsize;
+  tree t, ret_type, arg_type;
+
+  if (!TARGET_SIMD)
+    return 0;
+
+  if (clonei->simdlen
+      && (clonei->simdlen < 2
+	  || clonei->simdlen > 1024
+	  || (clonei->simdlen & (clonei->simdlen - 1)) != 0))
+    {
+      warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		  "unsupported simdlen %d", clonei->simdlen);
+      return 0;
+    }
+
+  ret_type = TREE_TYPE (TREE_TYPE (node->decl));
+  if (TREE_CODE (ret_type) != VOID_TYPE
+      && !currently_supported_simd_type (ret_type))
+    {
+      if (supported_simd_type (ret_type))
+	wmsg = G_("GCC does not currently support return type %qT for simd");
+      else
+	wmsg = G_("unsupported return type return type %qT for simd");
+      warning_at (DECL_SOURCE_LOCATION (node->decl), 0, wmsg, ret_type);
+      return 0;
+    }
+
+  for (t = DECL_ARGUMENTS (node->decl); t; t = DECL_CHAIN (t))
+    {
+      arg_type = TREE_TYPE (t);
+      if (POINTER_TYPE_P (arg_type))
+	arg_type = TREE_TYPE (arg_type);
+      if (!currently_supported_simd_type (arg_type))
+	{
+	  if (supported_simd_type (arg_type))
+	    wmsg = G_("GCC does not currently support argument type %qT "
+		      "for simd");
+	  else
+	    wmsg = G_("unsupported argument type %qT for simd");
+	  warning_at (DECL_SOURCE_LOCATION (node->decl), 0, wmsg, arg_type);
+	  return 0;
+	}
+    }
+
+  clonei->vecsize_mangle = 'n';
+  clonei->mask_mode = VOIDmode;
+  clonei->vecsize_int = 128;
+  clonei->vecsize_float = 128;
+
+  if (clonei->simdlen == 0)
+    {
+      if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
+	clonei->simdlen = clonei->vecsize_int;
+      else
+	clonei->simdlen = clonei->vecsize_float;
+      clonei->simdlen /= GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type));
+      return 1;
+    }
+
+  /* Restrict ourselves to vectors that fit in a single register  */
+
+  gcc_assert (tree_fits_shwi_p (TYPE_SIZE (base_type)));
+  vsize = clonei->simdlen * tree_to_shwi (TYPE_SIZE (base_type));
+  if (vsize > 128)
+    {
+	  warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		      "GCC does not currently support simdlen %d for type %qT",
+		      clonei->simdlen, base_type);
+	  return 0;
+    }
+  return 0;
+}
+
+/* Implement TARGET_SIMD_CLONE_ADJUST.  */
+
+static void
+aarch64_simd_clone_adjust (struct cgraph_node *node)
+{
+  /* Add aarch64_vector_pcs target attribute to SIMD clones so they
+     use the correct ABI.  */
+
+  tree t = TREE_TYPE (node->decl);
+  TYPE_ATTRIBUTES (t) =
+    make_attribute ("aarch64_vector_pcs", "default", TYPE_ATTRIBUTES (t));
+}
+
+/* Implement TARGET_SIMD_CLONE_USABLE.  */
+
+static int
+aarch64_simd_clone_usable (struct cgraph_node *node)
+{
+  switch (node->simdclone->vecsize_mangle)
+    {
+    case 'n':
+      if (!TARGET_SIMD)
+	return -1;
+      return 0;
+    default:
+      gcc_unreachable ();
+    }
+}
+
 /* Target-specific selftests.  */
 
 #if CHECKING_P
@@ -18549,6 +18683,16 @@ aarch64_libgcc_floating_mode_supported_p
 #undef TARGET_ATTRIBUTE_TABLE
 #define TARGET_ATTRIBUTE_TABLE aarch64_attribute_table
 
+#undef TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN
+#define TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN \
+  aarch64_simd_clone_compute_vecsize_and_simdlen
+
+#undef TARGET_SIMD_CLONE_ADJUST
+#define TARGET_SIMD_CLONE_ADJUST aarch64_simd_clone_adjust
+
+#undef TARGET_SIMD_CLONE_USABLE
+#define TARGET_SIMD_CLONE_USABLE aarch64_simd_clone_usable
+
 #if CHECKING_P
 #undef TARGET_RUN_TARGET_SELFTESTS
 #define TARGET_RUN_TARGET_SELFTESTS selftest::aarch64_run_selftests
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b9c4591..57b9e32 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -50150,6 +50150,11 @@ static void
 ix86_simd_clone_adjust (struct cgraph_node *node)
 {
   const char *str = NULL;
+
+  /* Attributes need to be adjusted for definitions, not declarations.  */
+  if (!node->definition)
+    return;
+
   gcc_assert (node->decl == cfun->decl);
   switch (node->simdclone->vecsize_mangle)
     {
diff --git a/gcc/omp-simd-clone.c b/gcc/omp-simd-clone.c
index ba03bd5..0837b82 100644
--- a/gcc/omp-simd-clone.c
+++ b/gcc/omp-simd-clone.c
@@ -1685,6 +1685,7 @@ expand_simd_clones (struct cgraph_node *node)
 	    simd_clone_adjust (n);
 	  else
 	    {
+	      targetm.simd_clone.adjust (n);
 	      simd_clone_adjust_return_type (n);
 	      simd_clone_adjust_argument_types (n);
 	    }
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-1.C b/gcc/testsuite/g++.dg/gomp/declare-simd-1.C
index d2659e1..8db5d5c 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-1.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-1.C
@@ -22,6 +22,7 @@ int f2 (int a, int *b, int c)
 // { dg-final { scan-assembler-times "_ZGVdN8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } 12 }
 
 #pragma omp declare simd uniform (c) aligned (b : 4 * sizeof (int)) linear (a : 4) simdlen (4)
 template <typename T>
@@ -89,6 +90,7 @@ namespace N1
 // { dg-final { scan-assembler-times "_ZGVdN2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZN2N12N23f10EPx:" 1 { target { aarch64-*-* } } } }
 
 struct A
 {
@@ -199,6 +201,7 @@ int B<int>::f25<7> (int a, int *b, int c)
 // { dg-final { scan-assembler-times "_ZGVdN8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-warning "unsupported argument type 'B<int>' for simd" "" { target aarch64-*-* } 191 }
 
 #pragma omp declare simd simdlen (4) aligned (b : 8 * sizeof (int)) linear (a, c : 2)
 template <>
@@ -216,6 +219,7 @@ int B<int>::f26<-1> (int a, int *b, int c)
 // { dg-final { scan-assembler-times "_ZGVdN4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { aarch64-*-* } } } }
 
 int
 f27 (int x)
@@ -247,6 +251,7 @@ f30 (int x)
 // { dg-final { scan-assembler-times "_ZGVdN16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-warning "GCC does not currently support simdlen 16 for type 'int'" "" { target aarch64-*-* } 239 }
 
 template <int N>
 struct C
@@ -281,6 +286,7 @@ struct D
   int f37 (int a);
   int e;
 };
+// { dg-warning "GCC does not currently support simdlen 16 for type 'int'" "" { target aarch64-*-* } 286 }
 
 void
 f38 (D &d)
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-3.C b/gcc/testsuite/g++.dg/gomp/declare-simd-3.C
index 32cdc58..5679075 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-3.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-3.C
@@ -21,6 +21,8 @@ int f1 (int a, int b, int c, int &d, int &e, int &f)
 // { dg-final { scan-assembler-times "_ZGVdN8vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM16vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN16vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnN4vulLUR4__Z2f1iiiRiS_S_:" 1 { target { aarch64-*-* } } } }
+                                      
 
 #pragma omp declare simd uniform(b) linear(c, d) linear(uval(e)) linear(ref(f))
 int f2 (int a, int b, int c, int &d, int &e, int &f)
@@ -48,6 +50,7 @@ int f2 (int a, int b, int c, int &d, int &e, int &f)
 // { dg-final { scan-assembler-times "_ZGVdN8vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM16vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN16vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnN4vulLUR4__Z2f2iiiRiS_S_:" 1 { target { aarch64-*-* } } } }
 
 #pragma omp declare simd uniform(b) linear(c, d) linear(uval(e)) linear(ref(f))
 int f3 (const int a, const int b, const int c, const int &d, const int &e, const int &f)
@@ -62,7 +65,7 @@ int f3 (const int a, const int b, const int c, const int &d, const int &e, const
 // { dg-final { scan-assembler-times "_ZGVdM8vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVdN8vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM16vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
-// { dg-final { scan-assembler-times "_ZGVeN16vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVeN4vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 
 #pragma omp declare simd uniform(b) linear(c, d) linear(uval(e)) linear(ref(f))
 int f4 (const int a, const int b, const int c, const int &d, const int &e, const int &f)
@@ -83,4 +86,4 @@ int f4 (const int a, const int b, const int c, const int &d, const int &e, const
 // { dg-final { scan-assembler-times "_ZGVdM8vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVdN8vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM16vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
-// { dg-final { scan-assembler-times "_ZGVeN16vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVeN4vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-4.C b/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
index acf03d9..fa5ac65d 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
@@ -13,6 +13,8 @@ f1 (int *p, int *q, short *s)
 // { dg-final { scan-assembler-times "_ZGVdN8l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM16l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN16l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnM4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnN4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
 
 #pragma omp declare simd linear(p:s) linear(q:t) uniform (s) linear(r:s) notinbranch simdlen(8) uniform(t)
 int
@@ -25,6 +27,7 @@ f2 (int *p, short *q, int s, int r, int &t)
 // { dg-final { scan-assembler-times "_ZGVcN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVdN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } 21 }
 
 #pragma omp declare simd linear(ref(p):s) linear(val(q):t) uniform (s) linear(uval(r):s) notinbranch simdlen(8) uniform(t)
 int
@@ -37,3 +40,4 @@ f3 (int &p, short &q, int s, int &r, int &t)
 // { dg-final { scan-assembler-times "_ZGVcN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVdN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } 34 }
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-7.C b/gcc/testsuite/g++.dg/gomp/declare-simd-7.C
index 52e9f18..9436656 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-7.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-7.C
@@ -18,6 +18,7 @@ foo1 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j,
 {
   return bar1 (a, b, c, d, e, f, g, h, i, j, k);
 }
+// { dg-warning "unsupported argument type 'S' for simd" "" { target aarch64-*-* } 17 }
 
 #pragma omp declare simd inbranch uniform (b, c, d, e) aligned (e : 16) \
 		    linear (f : 2) linear (ref (g) : 1) \
@@ -28,6 +29,7 @@ foo2 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j,
 {
   return bar2 (a, b, c, d, e, f, g, h, i, j, k);
 }
+// { dg-warning "unsupported argument type 'S' for simd" "" { target aarch64-*-* } 28 }
 
 #pragma omp declare simd notinbranch uniform (b, c, d, e) aligned (e : 16) \
 		    linear (f : 2) linear (ref (g) : 1) \
@@ -38,6 +40,7 @@ foo3 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j,
 {
   return bar3 (a, b, c, d, e, f, g, h, i, j, k);
 }
+// { dg-warning "unsupported argument type 'S' for simd" "" { target aarch64-*-* } 39 }
 
 #pragma omp declare simd inbranch uniform (b, c, d, e) aligned (e : 16) \
 		    linear (f : 2) linear (ref (g) : 1) \
@@ -48,3 +51,4 @@ foo4 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j,
 {
   return bar4 (a, b, c, d, e, f, g, h, i, j, k);
 }
+// { dg-warning "unsupported argument type 'S' for simd" "" { target aarch64-*-* } 50 }
diff --git a/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c b/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c
index b8bba1f..8dabc1e 100644
--- a/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c
+++ b/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c
@@ -21,6 +21,7 @@ int f2 (int a, int *b, int c)
 /* { dg-final { scan-assembler-times "_ZGVdN8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeM8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeN8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
+/* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } 11 } */
 
 #pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (long long)) linear (c : 4) simdlen (8)
 __extension__
@@ -57,6 +58,7 @@ f7 (int x)
 /* { dg-final { scan-assembler-times "_ZGVdN16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeM16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeN16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */
+/* { dg-warning "GCC does not currently support simdlen 16 for type 'int'" "" { target aarch64-*-* } 46 } */
 
 #pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8)
 int f12 (int c; int *b; int a; int a, int *b, int c);
@@ -76,6 +78,7 @@ f13 (int c; int *b; int a; int a, int *b, int c)
 /* { dg-final { scan-assembler-times "_ZGVdN8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeM8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeN8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */
+/* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } 68 } */
 
 #pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8)
 int
@@ -94,6 +97,7 @@ f14 (a, b, c)
 /* { dg-final { scan-assembler-times "_ZGVdN8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeM8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeN8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */
+/* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } 85 } */
 
 #pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8)
 int
@@ -110,6 +114,7 @@ f15 (int a, int *b, int c)
 /* { dg-final { scan-assembler-times "_ZGVdN8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeM8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeN8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */
+/* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } 104 } */
 
 #pragma omp declare simd uniform (d) aligned (e : 8 * sizeof (int)) linear (f : 4) simdlen (8)
 int f15 (int d, int *e, int f);
@@ -139,6 +144,7 @@ int f17 (int g, long *h)
 /* { dg-final { scan-assembler-times "_ZGVdN4l12va4_f17:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeM4l12va4_f17:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeN4l12va4_f17:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
+/* { dg-final { scan-assembler-times "f17:" 1 { target { aarch64-*-* } } } } */
 
 #pragma omp declare simd aligned (i : sizeof (*i)) linear (j : 2 * sizeof (i[0]) + sizeof (j)) simdlen (4)
 int
@@ -165,3 +171,4 @@ f18 (j, i)
 /* { dg-final { scan-assembler-times "_ZGVdN4l12va4_f18:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeM4l12va4_f18:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeN4l12va4_f18:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
+/* { dg-final { scan-assembler-times "f18:" 1 { target { aarch64-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c b/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c
index 9b8546d..e868516 100644
--- a/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c
+++ b/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c
@@ -13,6 +13,8 @@ f1 (int *p, int *q, short *s)
 /* { dg-final { scan-assembler-times "_ZGVdN8l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeM16l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeN16l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */
+/* { dg-final { scan-assembler-times "_ZGVnM4l4ln4ln6_f1:" 1 { target { aarch64-*-* } } } } */
+/* { dg-final { scan-assembler-times "_ZGVnN4l4ln4ln6_f1:" 1 { target { aarch64-*-* } } } } */
 
 #pragma omp declare simd linear(p:s) linear(q:t) uniform (s) linear(r:s) notinbranch simdlen(8) uniform(t)
 int
@@ -25,3 +27,4 @@ f2 (int *p, short *q, int s, int r, int t)
 /* { dg-final { scan-assembler-times "_ZGVcN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVdN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
+/* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } 21 } */
Jakub Jelinek Dec. 19, 2018, 10:57 p.m. UTC | #5
On Wed, Dec 19, 2018 at 10:10:19PM +0000, Steve Ellcey wrote:
> @@ -199,6 +201,7 @@ int B<int>::f25<7> (int a, int *b, int c)
>  // { dg-final { scan-assembler-times "_ZGVdN8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
>  // { dg-final { scan-assembler-times "_ZGVeM8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
>  // { dg-final { scan-assembler-times "_ZGVeN8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
> +// { dg-warning "unsupported argument type 'B<int>' for simd" "" { target aarch64-*-* } 191 }

Can you use relative line number instead, like .-10 or so?

> @@ -62,7 +65,7 @@ int f3 (const int a, const int b, const int c, const int &d, const int &e, const
>  // { dg-final { scan-assembler-times "_ZGVdM8vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
>  // { dg-final { scan-assembler-times "_ZGVdN8vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
>  // { dg-final { scan-assembler-times "_ZGVeM16vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
> -// { dg-final { scan-assembler-times "_ZGVeN16vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
> +// { dg-final { scan-assembler-times "_ZGVeN4vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }

Can you explain this change?  Are you changing the x86 ABI?

>  #pragma omp declare simd uniform(b) linear(c, d) linear(uval(e)) linear(ref(f))
>  int f4 (const int a, const int b, const int c, const int &d, const int &e, const int &f)
> @@ -83,4 +86,4 @@ int f4 (const int a, const int b, const int c, const int &d, const int &e, const
>  // { dg-final { scan-assembler-times "_ZGVdM8vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
>  // { dg-final { scan-assembler-times "_ZGVdN8vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
>  // { dg-final { scan-assembler-times "_ZGVeM16vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
> -// { dg-final { scan-assembler-times "_ZGVeN16vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
> +// { dg-final { scan-assembler-times "_ZGVeN4vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }

Likewise.

> --- a/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
> +++ b/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
> @@ -13,6 +13,8 @@ f1 (int *p, int *q, short *s)
>  // { dg-final { scan-assembler-times "_ZGVdN8l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
>  // { dg-final { scan-assembler-times "_ZGVeM16l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
>  // { dg-final { scan-assembler-times "_ZGVeN16l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
> +// { dg-final { scan-assembler-times "_ZGVnM4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
> +// { dg-final { scan-assembler-times "_ZGVnN4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }

This will also surely fail on x86.

> @@ -21,6 +21,7 @@ int f2 (int a, int *b, int c)
>  /* { dg-final { scan-assembler-times "_ZGVdN8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
>  /* { dg-final { scan-assembler-times "_ZGVeM8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
>  /* { dg-final { scan-assembler-times "_ZGVeN8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
> +/* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } 11 } */

.-x here too.

	Jakub
Steve Ellcey Dec. 19, 2018, 11:05 p.m. UTC | #6
On Wed, 2018-12-19 at 23:57 +0100, Jakub Jelinek wrote:
> On Wed, Dec 19, 2018 at 10:10:19PM +0000, Steve Ellcey wrote:
> > @@ -199,6 +201,7 @@ int B<int>::f25<7> (int a, int *b, int c)
> >  // { dg-final { scan-assembler-times
> > "_ZGVdN8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-*
> > x86_64-*-* } } } }
> >  // { dg-final { scan-assembler-times
> > "_ZGVeM8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-*
> > x86_64-*-* } } } }
> >  // { dg-final { scan-assembler-times
> > "_ZGVeN8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-*
> > x86_64-*-* } } } }
> > +// { dg-warning "unsupported argument type 'B<int>' for simd" "" {
> > target aarch64-*-* } 191 }
> 
> Can you use relative line number instead, like .-10 or so?

That sounds like a good idea.

> 
> > @@ -62,7 +65,7 @@ int f3 (const int a, const int b, const int c,
> > const int &d, const int &e, const
> >  // { dg-final { scan-assembler-times
> > "_ZGVdM8vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-
> > * } } } }
> >  // { dg-final { scan-assembler-times
> > "_ZGVdN8vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-
> > * } } } }
> >  // { dg-final { scan-assembler-times
> > "_ZGVeM16vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-
> > *-* } } } }
> > -// { dg-final { scan-assembler-times
> > "_ZGVeN16vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-
> > *-* } } } }
> > +// { dg-final { scan-assembler-times
> > "_ZGVeN4vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-
> > * } } } }
> 
> Can you explain this change?  Are you changing the x86 ABI?

No, that is a mistake that snuck in.  None of the x86 lines should
change.  Same for the other x86 changes.  I was changing the aarch64
manglings and obviously messed up some of the x86 ones.  Unfortunately
I did those changes after I did my x86 testing to verify the x86
code change I made so I didn't notice them.  I will fix those so that
no x86 lines are different.

Steve Ellcey
sellcey@marvell.com
Steve Ellcey Dec. 21, 2018, 6:01 p.m. UTC | #7
Here is an update to the test part of this patch.  I did not change the
actual source code part of this, just the tests, so that is all I am
including here.  I removed the x86 changes that had gotten in there by
accident and used relative line numbers in the warning checks instead
of absolute line numbers.  I also moved the warning checks to be closer
to the lines where the warnings are generated.

Retested on x86 and aarch64 with no regressions.

Steve Ellcey
sellcey@cavium.com


2018-12-21  Steve Ellcey  <sellcey@cavium.com>

	* g++.dg/gomp/declare-simd-1.C: Add aarch64 specific
	warning checks and assembler scans.
	* g++.dg/gomp/declare-simd-3.C: Ditto.
	* g++.dg/gomp/declare-simd-4.C: Ditto.
	* g++.dg/gomp/declare-simd-7.C: Ditto.
	* gcc.dg/gomp/declare-simd-1.c: Ditto.
	* gcc.dg/gomp/declare-simd-3.c: Ditto.
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-1.C b/gcc/testsuite/g++.dg/gomp/declare-simd-1.C
index d2659e1..f44efd5 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-1.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-1.C
@@ -14,6 +14,7 @@ int f2 (int a, int *b, int c)
   return a + *b + c;
 }
 
+// { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbM8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -89,6 +90,7 @@ namespace N1
 // { dg-final { scan-assembler-times "_ZGVdN2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZN2N12N23f10EPx:" 1 { target { aarch64-*-* } } } }
 
 struct A
 {
@@ -191,6 +193,7 @@ int B<int>::f25<7> (int a, int *b, int c)
   return a + *b + c;
 }
 
+// { dg-warning "unsupported argument type 'B<int>' for simd" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbM8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -216,6 +219,7 @@ int B<int>::f26<-1> (int a, int *b, int c)
 // { dg-final { scan-assembler-times "_ZGVdN4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { aarch64-*-* } } } }
 
 int
 f27 (int x)
@@ -239,6 +243,7 @@ f30 (int x)
   return x;
 }
 
+// { dg-warning "GCC does not currently support simdlen 16 for type 'int'" "" { target aarch64-*-* } .-7 }
 // { dg-final { scan-assembler-times "_ZGVbM16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -281,6 +286,7 @@ struct D
   int f37 (int a);
   int e;
 };
+// { dg-warning "GCC does not currently support simdlen 16 for type 'int'" "" { target aarch64-*-* } .-3 }
 
 void
 f38 (D &d)
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-3.C b/gcc/testsuite/g++.dg/gomp/declare-simd-3.C
index 32cdc58..3d668ff 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-3.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-3.C
@@ -21,6 +21,8 @@ int f1 (int a, int b, int c, int &d, int &e, int &f)
 // { dg-final { scan-assembler-times "_ZGVdN8vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM16vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN16vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnN4vulLUR4__Z2f1iiiRiS_S_:" 1 { target { aarch64-*-* } } } }
+                                      
 
 #pragma omp declare simd uniform(b) linear(c, d) linear(uval(e)) linear(ref(f))
 int f2 (int a, int b, int c, int &d, int &e, int &f)
@@ -48,6 +50,7 @@ int f2 (int a, int b, int c, int &d, int &e, int &f)
 // { dg-final { scan-assembler-times "_ZGVdN8vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM16vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN16vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnN4vulLUR4__Z2f2iiiRiS_S_:" 1 { target { aarch64-*-* } } } }
 
 #pragma omp declare simd uniform(b) linear(c, d) linear(uval(e)) linear(ref(f))
 int f3 (const int a, const int b, const int c, const int &d, const int &e, const int &f)
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-4.C b/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
index acf03d9..6d7e046 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
@@ -13,6 +13,8 @@ f1 (int *p, int *q, short *s)
 // { dg-final { scan-assembler-times "_ZGVdN8l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM16l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN16l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnM4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { aarch64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnN4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { aarch64-*-* } } } }
 
 #pragma omp declare simd linear(p:s) linear(q:t) uniform (s) linear(r:s) notinbranch simdlen(8) uniform(t)
 int
@@ -21,6 +23,7 @@ f2 (int *p, short *q, int s, int r, int &t)
   return *p + *q + r;
 }
 
+// { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVdN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -33,6 +36,7 @@ f3 (int &p, short &q, int s, int &r, int &t)
   return p + q + r;
 }
 
+// { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVdN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-7.C b/gcc/testsuite/g++.dg/gomp/declare-simd-7.C
index 52e9f18..c541720 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-7.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-7.C
@@ -18,6 +18,7 @@ foo1 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j,
 {
   return bar1 (a, b, c, d, e, f, g, h, i, j, k);
 }
+// { dg-warning "unsupported argument type 'S' for simd" "" { target aarch64-*-* } .-4 }
 
 #pragma omp declare simd inbranch uniform (b, c, d, e) aligned (e : 16) \
 		    linear (f : 2) linear (ref (g) : 1) \
@@ -28,6 +29,7 @@ foo2 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j,
 {
   return bar2 (a, b, c, d, e, f, g, h, i, j, k);
 }
+// { dg-warning "unsupported argument type 'S' for simd" "" { target aarch64-*-* } .-4 }
 
 #pragma omp declare simd notinbranch uniform (b, c, d, e) aligned (e : 16) \
 		    linear (f : 2) linear (ref (g) : 1) \
@@ -38,13 +40,14 @@ foo3 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j,
 {
   return bar3 (a, b, c, d, e, f, g, h, i, j, k);
 }
+// { dg-warning "unsupported argument type 'S' for simd" "" { target aarch64-*-* } .-4 }
 
 #pragma omp declare simd inbranch uniform (b, c, d, e) aligned (e : 16) \
 		    linear (f : 2) linear (ref (g) : 1) \
 		    linear (val (h) : 1) linear (uval (i) : 1) \
 		    linear (k : 4)
 int
-foo4 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j, int k)
-{
+foo4 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j, int k) {
   return bar4 (a, b, c, d, e, f, g, h, i, j, k);
 }
+// { dg-warning "unsupported argument type 'S' for simd" "" { target aarch64-*-* } .-3 }
diff --git a/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c b/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c
index b8bba1f..48e79fd 100644
--- a/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c
+++ b/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c
@@ -13,6 +13,7 @@ int f2 (int a, int *b, int c)
   return a + *b + c;
 }
 
+/* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -49,6 +50,7 @@ f7 (int x)
   return x;
 }
 
+/* { dg-warning "GCC does not currently support simdlen 16 for type 'int'" "" { target aarch64-*-* } .-7 } */
 /* { dg-final { scan-assembler-times "_ZGVbM16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -68,6 +70,7 @@ f13 (int c; int *b; int a; int a, int *b, int c)
   return a + *b + c;
 }
 
+/* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -86,6 +89,7 @@ f14 (a, b, c)
   return a + *b + c;
 }
 
+/* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-7 } */
 /* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -102,6 +106,7 @@ f15 (int a, int *b, int c)
   return a + *b + c;
 }
 
+/* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -139,6 +144,7 @@ int f17 (int g, long *h)
 /* { dg-final { scan-assembler-times "_ZGVdN4l12va4_f17:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeM4l12va4_f17:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeN4l12va4_f17:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
+/* { dg-final { scan-assembler-times "f17:" 1 { target { aarch64-*-* } } } } */
 
 #pragma omp declare simd aligned (i : sizeof (*i)) linear (j : 2 * sizeof (i[0]) + sizeof (j)) simdlen (4)
 int
@@ -165,3 +171,4 @@ f18 (j, i)
 /* { dg-final { scan-assembler-times "_ZGVdN4l12va4_f18:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeM4l12va4_f18:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeN4l12va4_f18:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
+/* { dg-final { scan-assembler-times "f18:" 1 { target { aarch64-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c b/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c
index 9b8546d..e4dd074 100644
--- a/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c
+++ b/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c
@@ -13,6 +13,8 @@ f1 (int *p, int *q, short *s)
 /* { dg-final { scan-assembler-times "_ZGVdN8l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeM16l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeN16l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */
+/* { dg-final { scan-assembler-times "_ZGVnM4l4ln4ln6_f1:" 1 { target { aarch64-*-* } } } } */
+/* { dg-final { scan-assembler-times "_ZGVnN4l4ln4ln6_f1:" 1 { target { aarch64-*-* } } } } */
 
 #pragma omp declare simd linear(p:s) linear(q:t) uniform (s) linear(r:s) notinbranch simdlen(8) uniform(t)
 int
@@ -21,6 +23,7 @@ f2 (int *p, short *q, int s, int r, int t)
   return *p + *q + r;
 }
 
+/* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVdN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
Jakub Jelinek Dec. 21, 2018, 7:13 p.m. UTC | #8
On Fri, Dec 21, 2018 at 06:01:56PM +0000, Steve Ellcey wrote:
> Here is an update to the test part of this patch.  I did not change the
> actual source code part of this, just the tests, so that is all I am
> including here.  I removed the x86 changes that had gotten in there by
> accident and used relative line numbers in the warning checks instead
> of absolute line numbers.  I also moved the warning checks to be closer
> to the lines where the warnings are generated.
> 
> Retested on x86 and aarch64 with no regressions.
> 
> Steve Ellcey
> sellcey@cavium.com
> 
> 
> 2018-12-21  Steve Ellcey  <sellcey@cavium.com>
> 
> 	* g++.dg/gomp/declare-simd-1.C: Add aarch64 specific
> 	warning checks and assembler scans.
> 	* g++.dg/gomp/declare-simd-3.C: Ditto.
> 	* g++.dg/gomp/declare-simd-4.C: Ditto.
> 	* g++.dg/gomp/declare-simd-7.C: Ditto.
> 	* gcc.dg/gomp/declare-simd-1.c: Ditto.
> 	* gcc.dg/gomp/declare-simd-3.c: Ditto.

LGTM.

	Jakub
Richard Sandiford Jan. 11, 2019, 2:45 p.m. UTC | #9
Steve Ellcey <sellcey@marvell.com> writes:
> Here is an updated version of the GCC patch to enable SIMD functions on
> Aarch64.  There are a number of changes from the last patch.
>
> I reduced the shared code changes, there is still one change in shared code
> (omp-simd-clone.c) to call targetm.simd_clone.adjust from expand_simd_clones
> but it now uses the same argument as the existing call.  This new call allows
> Aarch64 to add the aarch64_vector_pcs attribute to SIMD clone definitions
> which in turn ensures they use the correct ABI.  Previously this target
> function was only called on declarations, not definitions.  This change affects
> the x86 target so I modified ix86_simd_clone_adjust to return and do nothing
> when called with a definition.  This means there is no change in behaviour
> on x86.  I did a build and GCC testsuite run on x86 to verify this.
>
> Most of the changes from the previous patch are in the
> aarch64_simd_clone_compute_vecsize_and_simdlen function.
>
> The previous version was heavily based on the x86 function, this one has
> changes to address the issues that were raised in the earlier patch
> and so it no longer looks like the x86 version.  I use types instead of modes
> to check for what we can/cannot vectorize and I (try to) differentiate
> between vectors that we are not currently handling (but could later) and
> those that won't ever be handled.
>
> I have also added a testsuite patch to fix regressions in the gcc.dg/gomp
> and g++.dg/gomp tests.  There are no regressions with this patch applied.
>
> Steve Ellcey
> sellcey@marvell.com
>
> 2018-12-19  Steve Ellcey  <sellcey@cavium.com>
>
> 	* config/aarch64/aarch64.c (cgraph.h): New include.
> 	(supported_simd_type): New function.
> 	(currently_supported_simd_type): Ditto.
> 	(aarch64_simd_clone_compute_vecsize_and_simdlen): Ditto.
> 	(aarch64_simd_clone_adjust): Ditto.
> 	(aarch64_simd_clone_usable): Ditto.
> 	(TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN): New macro.
> 	(TARGET_SIMD_CLONE_ADJUST): Ditto.
> 	(TARGET_SIMD_CLONE_USABLE): Ditto.
> 	* config/i386/i386.c (ix86_simd_clone_adjust): Add definition check.
> 	* omp-simd-clone.c (expand_simd_clones): Add targetm.simd_clone.adjust
> 	call.
>
> 2018-12-19  Steve Ellcey  <sellcey@cavium.com>
>
> 	* g++.dg/gomp/declare-simd-1.C: Add aarch64 specific
> 	warning checks and assembler scans.
> 	* g++.dg/gomp/declare-simd-3.C: Ditto.
> 	* g++.dg/gomp/declare-simd-4.C: Ditto.
> 	* g++.dg/gomp/declare-simd-7.C: Ditto.
> 	* gcc.dg/gomp/declare-simd-1.c: Ditto.
> 	* gcc.dg/gomp/declare-simd-3.c: Ditto.

Sorry, hadn't realised this was still unreviewed.

> @@ -18064,6 +18066,138 @@ aarch64_estimated_poly_value (poly_int64 val)
>    return val.coeffs[0] + val.coeffs[1] * over_128 / 128;
>  }
>  
> +
> +/* Return true for types that could be supported as SIMD return or
> +   argument types.  */
> +
> +static bool supported_simd_type (tree t)
> +{
> +  return (FLOAT_TYPE_P (t) || INTEGRAL_TYPE_P (t));

We should also check that the size is 1, 2, 4 or 8 bytes.

> +}
> +
> +/* Return true for types that currently are supported as SIMD return
> +   or argument types.  */
> +
> +static bool currently_supported_simd_type (tree t)
> +{
> +  if (COMPLEX_FLOAT_TYPE_P (t))
> +    return false;
> +
> +  return supported_simd_type (t);
> +}
> +
> +/* Implement TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN.  */
> +
> +static int
> +aarch64_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
> +					struct cgraph_simd_clone *clonei,
> +					tree base_type,
> +					int num ATTRIBUTE_UNUSED)
> +{
> +  const char *wmsg;
> +  int vsize;
> +  tree t, ret_type, arg_type;
> +
> +  if (!TARGET_SIMD)
> +    return 0;
> +
> +  if (clonei->simdlen
> +      && (clonei->simdlen < 2
> +	  || clonei->simdlen > 1024
> +	  || (clonei->simdlen & (clonei->simdlen - 1)) != 0))
> +    {
> +      warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
> +		  "unsupported simdlen %d", clonei->simdlen);
> +      return 0;
> +    }
> +
> +  ret_type = TREE_TYPE (TREE_TYPE (node->decl));
> +  if (TREE_CODE (ret_type) != VOID_TYPE
> +      && !currently_supported_simd_type (ret_type))
> +    {
> +      if (supported_simd_type (ret_type))
> +	wmsg = G_("GCC does not currently support return type %qT for simd");
> +      else
> +	wmsg = G_("unsupported return type return type %qT for simd");

Typo: doubled "return type".

Maybe s/for simd/for %<simd%> functions/ in both messages.
Since that will blow the line limit...

> +      warning_at (DECL_SOURCE_LOCATION (node->decl), 0, wmsg, ret_type);
> +      return 0;
> +    }

...it's probably worth just calling warning_at in each arm of the "if".
We'll then get proper format checking in bootstraps.

> +  for (t = DECL_ARGUMENTS (node->decl); t; t = DECL_CHAIN (t))
> +    {
> +      arg_type = TREE_TYPE (t);
> +      if (POINTER_TYPE_P (arg_type))
> +	arg_type = TREE_TYPE (arg_type);
> +      if (!currently_supported_simd_type (arg_type))
> +	{
> +	  if (supported_simd_type (arg_type))
> +	    wmsg = G_("GCC does not currently support argument type %qT "
> +		      "for simd");
> +	  else
> +	    wmsg = G_("unsupported argument type %qT for simd");
> +	  warning_at (DECL_SOURCE_LOCATION (node->decl), 0, wmsg, arg_type);
> +	  return 0;
> +	}
> +    }

The ABI supports all argument types, so this should only check
current_supported_simd_type and should always use the "GCC does not..."
message.

Could you explain why the POINTER_TYPE_P handling is correct?
Think it's worth a comment.  Dropping it is also fine if that's easier.

(Just in case: the point about PBV in my previous reply was that if
an argument isn't a natural vector element, the ABI says that you
should implicitly convert it to a vector of pointers instead, which is
how it can handle any argument type.  I didn't mean that we should add
a pointer check here.)

> +  if (clonei->simdlen == 0)
> +    {
> +      if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
> +	clonei->simdlen = clonei->vecsize_int;
> +      else
> +	clonei->simdlen = clonei->vecsize_float;
> +      clonei->simdlen /= GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type));
> +      return 1;
> +    }

I should have noticed this last time, but base_type is the CDT in the
Intel ABI.  That isn't always right for the AArch64 ABI.

I think for now currently_supported_simd_type should take base_type
as a second parameter and check that the given type has the same size.

> +  /* Restrict ourselves to vectors that fit in a single register  */
> +
> +  gcc_assert (tree_fits_shwi_p (TYPE_SIZE (base_type)));
> +  vsize = clonei->simdlen * tree_to_shwi (TYPE_SIZE (base_type));
> +  if (vsize > 128)
> +    {
> +	  warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
> +		      "GCC does not currently support simdlen %d for type %qT",
> +		      clonei->simdlen, base_type);
> +	  return 0;
> +    }

nit: block contents indented too far.

> +  return 0;
> +}

Doesn't this mean that we always silently fail for an explicit and
correct simdlen?  If so, that suggests we might not have enough
testsuite coverage :-)

Thanks,
Richard
Steve Ellcey Jan. 11, 2019, 10:26 p.m. UTC | #10
On Fri, 2019-01-11 at 14:45 +0000, Richard Sandiford wrote:
> 
> > +
> > +/* Return true for types that could be supported as SIMD return or
> > +   argument types.  */
> > +
> > +static bool supported_simd_type (tree t)
> > +{
> > +  return (FLOAT_TYPE_P (t) || INTEGRAL_TYPE_P (t));
> 
> We should also check that the size is 1, 2, 4 or 8 bytes.

I fixed this, I also allow for POINTER_P types which allowed me
to not do the POINTER_P check below which you asked about and
which I now think was a mistake (more comments below).

> > 
> > +	wmsg = G_("unsupported return type return type %qT for simd");
> 
> Typo: doubled "return type".

Fixed.
> 
> Maybe s/for simd/for %<simd%> functions/ in both messages.
> Since that will blow the line limit...
> 
> > +      warning_at (DECL_SOURCE_LOCATION (node->decl), 0, wmsg,
> > ret_type);
> > +      return 0;
> > +    }
> 
> ...it's probably worth just calling warning_at in each arm of the
> "if".
> We'll then get proper format checking in bootstraps.

I made this change.

> > +  for (t = DECL_ARGUMENTS (node->decl); t; t = DECL_CHAIN (t))
> > +    {
> > +      arg_type = TREE_TYPE (t);
> > +      if (POINTER_TYPE_P (arg_type))
> > +	arg_type = TREE_TYPE (arg_type);
> > +      if (!currently_supported_simd_type (arg_type))
> > +	{
> > +	  if (supported_simd_type (arg_type))
> > +	    wmsg = G_("GCC does not currently support argument type %qT
> > "
> > +		      "for simd");
> > +	  else
> > +	    wmsg = G_("unsupported argument type %qT for simd");
> > +	  warning_at (DECL_SOURCE_LOCATION (node->decl), 0, wmsg,
> > arg_type);
> > +	  return 0;
> > +	}
> > +    }
> 
> The ABI supports all argument types, so this should only check
> current_supported_simd_type and should always use the "GCC does
> not..."
> message.

Done.

> Could you explain why the POINTER_TYPE_P handling is correct?
> Think it's worth a comment.  Dropping it is also fine if that's
> easier.

I now think this was a mistake but after removing it I had to allow
for POINTER_P type in supported_simd_type to get the regression
tests to pass.  I think the current code is the correct behavour
and more closely matches x86 in terms of what is and is not vectorized.


> > +  if (clonei->simdlen == 0)
> > +    {
> > +      if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
> > +	clonei->simdlen = clonei->vecsize_int;
> > +      else
> > +	clonei->simdlen = clonei->vecsize_float;
> > +      clonei->simdlen /= GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type));
> > +      return 1;
> > +    }
> 
> I should have noticed this last time, but base_type is the CDT in the
> Intel ABI.  That isn't always right for the AArch64 ABI.
> 
> I think for now currently_supported_simd_type should take base_type
> as a second parameter and check that the given type has the same
> size.

I have not changed this, I am not quite sure what you mean.  What is
CDT?  Clone data type?  Are you saying I should use node->decl->type
instead of base_type?

> 
> > +  /* Restrict ourselves to vectors that fit in a single
> > register  */
> > +
> > +  gcc_assert (tree_fits_shwi_p (TYPE_SIZE (base_type)));
> > +  vsize = clonei->simdlen * tree_to_shwi (TYPE_SIZE (base_type));
> > +  if (vsize > 128)
> > +    {
> > +	  warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
> > +		      "GCC does not currently support simdlen %d for
> > type %qT",
> > +		      clonei->simdlen, base_type);
> > +	  return 0;
> > +    }
> 
> nit: block contents indented too far.

Fixed.

> > +  return 0;
> > +}
> 
> Doesn't this mean that we always silently fail for an explicit and
> correct simdlen?  If so, that suggests we might not have enough
> testsuite coverage :-)

Well, we were failing here and some tests were failing but then I
'fixed' the tests in my last patch to pass instead of fixing this
bug.  I have now changed it to 'return 1' and re-fixed the tests
that I incorrectly fixed last time.  So at least it wasn't a silent
fail (until I silenced it).

Here is the latest patch, any help you can give me on the base_type
issue would be appreciated.


2018-01-11  Steve Ellcey  <sellcey@cavium.com>

	* config/aarch64/aarch64.c (cgraph.h): New include.
	(intl.h): New include.
	(supported_simd_type): New function.
	(currently_supported_simd_type): Ditto.
	(aarch64_simd_clone_compute_vecsize_and_simdlen): Ditto.
	(aarch64_simd_clone_adjust): Ditto.
	(aarch64_simd_clone_usable): Ditto.
	(TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN): New macro.
	(TARGET_SIMD_CLONE_ADJUST): Ditto.
	(TARGET_SIMD_CLONE_USABLE): Ditto.
	* config/i386/i386.c (ix86_simd_clone_adjust): Add definition check.
	* omp-simd-clone.c (expand_simd_clones): Add targetm.simd_clone.adjust
	call.


2018-01-11  Steve Ellcey  <sellcey@cavium.com>

	* g++.dg/gomp/declare-simd-1.C: Add aarch64 specific
	warning checks and assembler scans.
	* g++.dg/gomp/declare-simd-3.C: Ditto.
	* g++.dg/gomp/declare-simd-4.C: Ditto.
	* gcc.dg/gomp/declare-simd-1.c: Ditto.
	* gcc.dg/gomp/declare-simd-3.c: Ditto.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index fd60bdd..360adea 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -40,6 +40,7 @@
 #include "regs.h"
 #include "emit-rtl.h"
 #include "recog.h"
+#include "cgraph.h"
 #include "diagnostic.h"
 #include "insn-attr.h"
 #include "alias.h"
@@ -71,6 +72,7 @@
 #include "selftest.h"
 #include "selftest-rtl.h"
 #include "rtx-vector-builder.h"
+#include "intl.h"
 
 /* This file should be included last.  */
 #include "target-def.h"
@@ -18420,6 +18422,140 @@ aarch64_estimated_poly_value (poly_int64 val)
   return val.coeffs[0] + val.coeffs[1] * over_128 / 128;
 }
 
+
+/* Return true for types that could be supported as SIMD return or
+   argument types.  */
+
+static bool supported_simd_type (tree t)
+{
+  HOST_WIDE_INT s;
+  gcc_assert (tree_fits_shwi_p (TYPE_SIZE_UNIT (t)));
+  s = tree_to_shwi (TYPE_SIZE_UNIT (t));
+  return ((FLOAT_TYPE_P (t) || INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
+	  && (s == 1 || s == 2 || s == 4 || s == 8));
+}
+
+/* Return true for types that currently are supported as SIMD return
+   or argument types.  */
+
+static bool currently_supported_simd_type (tree t)
+{
+  if (COMPLEX_FLOAT_TYPE_P (t))
+    return false;
+
+  return supported_simd_type (t);
+}
+
+/* Implement TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN.  */
+
+static int
+aarch64_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
+					struct cgraph_simd_clone *clonei,
+					tree base_type,
+					int num ATTRIBUTE_UNUSED)
+{
+  int vsize;
+  tree t, ret_type, arg_type;
+
+  if (!TARGET_SIMD)
+    return 0;
+
+  if (clonei->simdlen
+      && (clonei->simdlen < 2
+	  || clonei->simdlen > 1024
+	  || (clonei->simdlen & (clonei->simdlen - 1)) != 0))
+    {
+      warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		  "unsupported simdlen %d", clonei->simdlen);
+      return 0;
+    }
+
+  ret_type = TREE_TYPE (TREE_TYPE (node->decl));
+  if (TREE_CODE (ret_type) != VOID_TYPE
+      && !currently_supported_simd_type (ret_type))
+    {
+      if (supported_simd_type (ret_type))
+	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		    "GCC does not currently support return type %qT "
+		    "for %<simd%> functions", ret_type);
+      else
+	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		    "unsupported return type %qT for %<simd%> functions",
+		    ret_type);
+      return 0;
+    }
+
+  for (t = DECL_ARGUMENTS (node->decl); t; t = DECL_CHAIN (t))
+    {
+      arg_type = TREE_TYPE (t);
+
+      if (!currently_supported_simd_type (arg_type))
+	{
+	  warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		      "GCC does not currently support argument type %qT "
+		      "for %<simd%> functions", arg_type);
+	  return 0;
+	}
+    }
+
+  clonei->vecsize_mangle = 'n';
+  clonei->mask_mode = VOIDmode;
+  clonei->vecsize_int = 128;
+  clonei->vecsize_float = 128;
+
+  if (clonei->simdlen == 0)
+    {
+      if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
+	clonei->simdlen = clonei->vecsize_int;
+      else
+	clonei->simdlen = clonei->vecsize_float;
+      clonei->simdlen /= GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type));
+      return 1;
+    }
+
+  /* Restrict ourselves to vectors that fit in a single register  */
+
+  gcc_assert (tree_fits_shwi_p (TYPE_SIZE (base_type)));
+  vsize = clonei->simdlen * tree_to_shwi (TYPE_SIZE (base_type));
+  if (vsize > 128)
+    {
+      warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		  "GCC does not currently support simdlen %d for type %qT",
+		  clonei->simdlen, base_type);
+      return 0;
+    }
+  return 1;
+}
+
+/* Implement TARGET_SIMD_CLONE_ADJUST.  */
+
+static void
+aarch64_simd_clone_adjust (struct cgraph_node *node)
+{
+  /* Add aarch64_vector_pcs target attribute to SIMD clones so they
+     use the correct ABI.  */
+
+  tree t = TREE_TYPE (node->decl);
+  TYPE_ATTRIBUTES (t) =
+    make_attribute ("aarch64_vector_pcs", "default", TYPE_ATTRIBUTES (t));
+}
+
+/* Implement TARGET_SIMD_CLONE_USABLE.  */
+
+static int
+aarch64_simd_clone_usable (struct cgraph_node *node)
+{
+  switch (node->simdclone->vecsize_mangle)
+    {
+    case 'n':
+      if (!TARGET_SIMD)
+	return -1;
+      return 0;
+    default:
+      gcc_unreachable ();
+    }
+}
+
 /* Target-specific selftests.  */
 
 #if CHECKING_P
@@ -18913,6 +19049,16 @@ aarch64_libgcc_floating_mode_supported_p
 #undef TARGET_ATTRIBUTE_TABLE
 #define TARGET_ATTRIBUTE_TABLE aarch64_attribute_table
 
+#undef TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN
+#define TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN \
+  aarch64_simd_clone_compute_vecsize_and_simdlen
+
+#undef TARGET_SIMD_CLONE_ADJUST
+#define TARGET_SIMD_CLONE_ADJUST aarch64_simd_clone_adjust
+
+#undef TARGET_SIMD_CLONE_USABLE
+#define TARGET_SIMD_CLONE_USABLE aarch64_simd_clone_usable
+
 #if CHECKING_P
 #undef TARGET_RUN_TARGET_SELFTESTS
 #define TARGET_RUN_TARGET_SELFTESTS selftest::aarch64_run_selftests
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 1bb535a..82e0f90 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -50648,6 +50648,11 @@ static void
 ix86_simd_clone_adjust (struct cgraph_node *node)
 {
   const char *str = NULL;
+
+  /* Attributes need to be adjusted for definitions, not declarations.  */
+  if (!node->definition)
+    return;
+
   gcc_assert (node->decl == cfun->decl);
   switch (node->simdclone->vecsize_mangle)
     {
diff --git a/gcc/omp-simd-clone.c b/gcc/omp-simd-clone.c
index 783118f..9b8111c 100644
--- a/gcc/omp-simd-clone.c
+++ b/gcc/omp-simd-clone.c
@@ -1685,6 +1685,7 @@ expand_simd_clones (struct cgraph_node *node)
 	    simd_clone_adjust (n);
 	  else
 	    {
+	      targetm.simd_clone.adjust (n);
 	      simd_clone_adjust_return_type (n);
 	      simd_clone_adjust_argument_types (n);
 	    }
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-1.C b/gcc/testsuite/g++.dg/gomp/declare-simd-1.C
index d2659e1..c147978 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-1.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-1.C
@@ -14,6 +14,7 @@ int f2 (int a, int *b, int c)
   return a + *b + c;
 }
 
+// { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbM8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -89,6 +90,8 @@ namespace N1
 // { dg-final { scan-assembler-times "_ZGVdN2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnM2va16__ZN2N12N23f10EPx:" 1 { target { aarch64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnN2va16__ZN2N12N23f10EPx:" 1 { target { aarch64-*-* } } } }
 
 struct A
 {
@@ -191,6 +194,7 @@ int B<int>::f25<7> (int a, int *b, int c)
   return a + *b + c;
 }
 
+// { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbM8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -216,6 +220,8 @@ int B<int>::f26<-1> (int a, int *b, int c)
 // { dg-final { scan-assembler-times "_ZGVdN4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnM4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { aarch64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnN4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { aarch64-*-* } } } }
 
 int
 f27 (int x)
@@ -239,6 +245,7 @@ f30 (int x)
   return x;
 }
 
+// { dg-warning "GCC does not currently support simdlen 16 for type 'int'" "" { target aarch64-*-* } .-7 }
 // { dg-final { scan-assembler-times "_ZGVbM16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -281,6 +288,7 @@ struct D
   int f37 (int a);
   int e;
 };
+// { dg-warning "GCC does not currently support simdlen 16 for type 'int'" "" { target aarch64-*-* } .-3 }
 
 void
 f38 (D &d)
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-3.C b/gcc/testsuite/g++.dg/gomp/declare-simd-3.C
index 32cdc58..3d668ff 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-3.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-3.C
@@ -21,6 +21,8 @@ int f1 (int a, int b, int c, int &d, int &e, int &f)
 // { dg-final { scan-assembler-times "_ZGVdN8vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM16vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN16vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnN4vulLUR4__Z2f1iiiRiS_S_:" 1 { target { aarch64-*-* } } } }
+                                      
 
 #pragma omp declare simd uniform(b) linear(c, d) linear(uval(e)) linear(ref(f))
 int f2 (int a, int b, int c, int &d, int &e, int &f)
@@ -48,6 +50,7 @@ int f2 (int a, int b, int c, int &d, int &e, int &f)
 // { dg-final { scan-assembler-times "_ZGVdN8vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM16vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN16vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnN4vulLUR4__Z2f2iiiRiS_S_:" 1 { target { aarch64-*-* } } } }
 
 #pragma omp declare simd uniform(b) linear(c, d) linear(uval(e)) linear(ref(f))
 int f3 (const int a, const int b, const int c, const int &d, const int &e, const int &f)
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-4.C b/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
index acf03d9..6d7e046 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
@@ -13,6 +13,8 @@ f1 (int *p, int *q, short *s)
 // { dg-final { scan-assembler-times "_ZGVdN8l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM16l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN16l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnM4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { aarch64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnN4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { aarch64-*-* } } } }
 
 #pragma omp declare simd linear(p:s) linear(q:t) uniform (s) linear(r:s) notinbranch simdlen(8) uniform(t)
 int
@@ -21,6 +23,7 @@ f2 (int *p, short *q, int s, int r, int &t)
   return *p + *q + r;
 }
 
+// { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVdN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -33,6 +36,7 @@ f3 (int &p, short &q, int s, int &r, int &t)
   return p + q + r;
 }
 
+// { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVdN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
diff --git a/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c b/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c
index b8bba1f..ec53ebe 100644
--- a/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c
+++ b/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c
@@ -13,6 +13,7 @@ int f2 (int a, int *b, int c)
   return a + *b + c;
 }
 
+/* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -49,6 +50,7 @@ f7 (int x)
   return x;
 }
 
+/* { dg-warning "GCC does not currently support simdlen 16 for type 'int'" "" { target aarch64-*-* } .-7 } */
 /* { dg-final { scan-assembler-times "_ZGVbM16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -68,6 +70,7 @@ f13 (int c; int *b; int a; int a, int *b, int c)
   return a + *b + c;
 }
 
+/* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -86,6 +89,7 @@ f14 (a, b, c)
   return a + *b + c;
 }
 
+/* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-7 } */
 /* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -102,6 +106,7 @@ f15 (int a, int *b, int c)
   return a + *b + c;
 }
 
+/* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -139,6 +144,8 @@ int f17 (int g, long *h)
 /* { dg-final { scan-assembler-times "_ZGVdN4l12va4_f17:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeM4l12va4_f17:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeN4l12va4_f17:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
+/* { dg-final { scan-assembler-times "_ZGVnM4l20va8_f17:" 1 { target { aarch64-*-* } } } } */
+/* { dg-final { scan-assembler-times "_ZGVnN4l20va8_f17:" 1 { target { aarch64-*-* } } } } */
 
 #pragma omp declare simd aligned (i : sizeof (*i)) linear (j : 2 * sizeof (i[0]) + sizeof (j)) simdlen (4)
 int
@@ -165,3 +172,5 @@ f18 (j, i)
 /* { dg-final { scan-assembler-times "_ZGVdN4l12va4_f18:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeM4l12va4_f18:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeN4l12va4_f18:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */
+/* { dg-final { scan-assembler-times "_ZGVnM4l20va8_f18:" 1 { target { aarch64-*-* } } } } */
+/* { dg-final { scan-assembler-times "_ZGVnN4l20va8_f18:" 1 { target { aarch64-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c b/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c
index 9b8546d..e4dd074 100644
--- a/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c
+++ b/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c
@@ -13,6 +13,8 @@ f1 (int *p, int *q, short *s)
 /* { dg-final { scan-assembler-times "_ZGVdN8l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeM16l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVeN16l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */
+/* { dg-final { scan-assembler-times "_ZGVnM4l4ln4ln6_f1:" 1 { target { aarch64-*-* } } } } */
+/* { dg-final { scan-assembler-times "_ZGVnN4l4ln4ln6_f1:" 1 { target { aarch64-*-* } } } } */
 
 #pragma omp declare simd linear(p:s) linear(q:t) uniform (s) linear(r:s) notinbranch simdlen(8) uniform(t)
 int
@@ -21,6 +23,7 @@ f2 (int *p, short *q, int s, int r, int t)
   return *p + *q + r;
 }
 
+/* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVdN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
Richard Sandiford Jan. 14, 2019, 10:27 p.m. UTC | #11
Steve Ellcey <sellcey@marvell.com> writes:
> On Fri, 2019-01-11 at 14:45 +0000, Richard Sandiford wrote:
>> 
>> > +
>> > +/* Return true for types that could be supported as SIMD return or
>> > +   argument types.  */
>> > +
>> > +static bool supported_simd_type (tree t)
>> > +{
>> > +  return (FLOAT_TYPE_P (t) || INTEGRAL_TYPE_P (t));
>> 
>> We should also check that the size is 1, 2, 4 or 8 bytes.
>
> I fixed this, I also allow for POINTER_P types which allowed me
> to not do the POINTER_P check below which you asked about and
> which I now think was a mistake (more comments below).

Ah, yeah, agree that's the right thing to do.

>> > +  if (clonei->simdlen == 0)
>> > +    {
>> > +      if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
>> > +	clonei->simdlen = clonei->vecsize_int;
>> > +      else
>> > +	clonei->simdlen = clonei->vecsize_float;
>> > +      clonei->simdlen /= GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type));
>> > +      return 1;
>> > +    }
>> 
>> I should have noticed this last time, but base_type is the CDT in the
>> Intel ABI.  That isn't always right for the AArch64 ABI.
>> 
>> I think for now currently_supported_simd_type should take base_type
>> as a second parameter and check that the given type has the same
>> size.
>
> I have not changed this, I am not quite sure what you mean.  What is
> CDT?  Clone data type?  Are you saying I should use node->decl->type
> instead of base_type?

CDT is the Characteristic Data Type and is specific to the Intel ABI:

/* Given a SIMD clone in NODE, calculate the characteristic data
   type and return the coresponding type.  The characteristic data
   type is computed as described in the Intel Vector ABI.  */

static tree
simd_clone_compute_base_data_type (struct cgraph_node *node,
				   struct cgraph_simd_clone *clone_info)

This has consequences that we didn't want for AArch64, such as
assigning different implicit simdlens for "double f(float)" and
"float g(double)".  The rules also don't extend naturally to
SVE-like architectures, where mixed data sizes are best handled
using unpacked vectors.

But at this stage I think it would be better to leave cases in which
the Intel ABI gives a different mapping from the AArch64 ABI to GCC 10.
For GCC 9 it seems better to handle only the cases that are the same
under both ABIs.

And using the CDT is stil OK in the trivial case that the return type
and arguments are all supported vector element types and all have the
same size.  So I think for GCC 9 we should just handle that case.

We can do that by passing base_type as a second argument to
currently_supported_simd_type and checking that the first argument
has the same size.

> @@ -18420,6 +18422,140 @@ aarch64_estimated_poly_value (poly_int64 val)
>    return val.coeffs[0] + val.coeffs[1] * over_128 / 128;
>  }
>  
> +
> +/* Return true for types that could be supported as SIMD return or
> +   argument types.  */
> +
> +static bool supported_simd_type (tree t)
> +{
> +  HOST_WIDE_INT s;
> +  gcc_assert (tree_fits_shwi_p (TYPE_SIZE_UNIT (t)));
> +  s = tree_to_shwi (TYPE_SIZE_UNIT (t));
> +  return ((FLOAT_TYPE_P (t) || INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
> +	  && (s == 1 || s == 2 || s == 4 || s == 8));

We should only assert after checking FLOAT_TYPE_P etc.  And there's
no need to assert explicitly, since tree_to_shwi already asserts
where necessary.  So I think this should be:

  if (SCALAR_FLOAT_TYPE_P (t) || INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
    {
      HOST_WIDE_INT s = tree_to_shwi (TYPE_SIZE_UNIT (t));
      return s == 1 || s == 2 || s == 4 || s == 8;
    }
  return false;
  
(SCALAR_FLOAT_TYPE_P so that the tests are consistent about not handling
complex types, sorry for not thinking about that before.)

> +  clonei->vecsize_mangle = 'n';
> +  clonei->mask_mode = VOIDmode;
> +  clonei->vecsize_int = 128;
> +  clonei->vecsize_float = 128;
> +
> +  if (clonei->simdlen == 0)
> +    {
> +      if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
> +	clonei->simdlen = clonei->vecsize_int;
> +      else
> +	clonei->simdlen = clonei->vecsize_float;
> +      clonei->simdlen /= GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type));
> +      return 1;

The AArch64 vector ABI says that having no simdlen should imply both
64-bit and 128-bit implementations.  E.g.:

   #pragma omp declare simd
   int32_t foo(int32_t x);

should provide:

   int32x2_t _ZGVnN2v_foo(int32x2_t vx);
   int32x2_t _ZGVnM2v_foo(int32x2_t vx, uint32x2_t vmask);
   int32x4_t _ZGVnN4v_foo(int32x4_t vx);
   int32x4_t _ZGVnM4v_foo(int32x4_t vx, uint32x4_t vmask);

whereas here we're only providing the 128-bit versions.  I think we should:

- return 2
- set vecsize_int and vecsize_float to 64 when num==0
- set vecsize_int and vecsize_float to 128 when num==1

> +  /* Restrict ourselves to vectors that fit in a single register  */
> +
> +  gcc_assert (tree_fits_shwi_p (TYPE_SIZE (base_type)));
> +  vsize = clonei->simdlen * tree_to_shwi (TYPE_SIZE (base_type));
> +  if (vsize > 128)
> +    {
> +      warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
> +		  "GCC does not currently support simdlen %d for type %qT",
> +		  clonei->simdlen, base_type);
> +      return 0;
> +    }
> +  return 1;

This only really handles cases in which vsize is exactly 128,
because it doesn't update vecsize_int or vecsize_float.

I think we should allow only 64 and 128 (for now) and set vecsize_int
and vecsize_float to vsize.

> +}
> +
> +/* Implement TARGET_SIMD_CLONE_ADJUST.  */
> +
> +static void
> +aarch64_simd_clone_adjust (struct cgraph_node *node)
> +{
> +  /* Add aarch64_vector_pcs target attribute to SIMD clones so they
> +     use the correct ABI.  */
> +
> +  tree t = TREE_TYPE (node->decl);
> +  TYPE_ATTRIBUTES (t) =
> +    make_attribute ("aarch64_vector_pcs", "default", TYPE_ATTRIBUTES (t));

Formatting nit: "=" shouldn't be at the end of a line.  Maybe:

  TYPE_ATTRIBUTES (t) = make_attribute ("aarch64_vector_pcs", "default",
					TYPE_ATTRIBUTES (t));

Thanks,
Richard
Steve Ellcey Jan. 15, 2019, 9:57 p.m. UTC | #12
Richard,

Here is a new version of the patch but it is not passing the testsuite
right now.  I added the check for the size of the base type being the
same as the size of the return or argument type and modified the error
messages in some cases to make more sense.  This caused some things
to not get cloned which is fine but it also caused a couple of ICE
failures and I am not sure how to deal with those.  I also am having
trouble with a couple of tests that include other tests and how to
set dg-warning on them.

I will try to figure out what is going on but I wanted to send the
latest versions to you to see if you had any ideas on the problems
I am seeing.

Steve Ellcey
sellcey@marvell.com



Here are the failures I am getting with this patch:

c-c++-common/gomp/pr63328.c
gcc.dg/gomp/pr87895-2.c

These tests include another test (which passes) and the included tests
have a dg-warning check.  For some reason the dg-warning in the include
is ignored and when I tried adding one in the main file (that includes
the other test), that didn't work either.


gcc.dg/gomp/simd-clones-1.c
g++.dg/gomp/declare-simd-1.C

These two tests are generating an ICE and I am not sure why.

I cut declare-simd-1.C down to:

#pragma omp declare simd simdlen (2) aligned (b : sizeof (long long) * 2)
__extension__ long long
f10 (long long *b)
{
      return *b;
}

And it results in:

% install/usr/bin/g++ -fopenmp-simd -c b1.C
during RTL pass: expand
b1.C: In function ‘long long int f10(long long int*)’:
b1.C:5:15: internal compiler error: in expand_assignment, at expr.c:5101
    5 |       return *b;
      |               ^
0xaeee73 expand_assignment(tree_node*, tree_node*, bool)
	/home/sellcey/gcc-vect/src/gcc/gcc/expr.c:5101
0x9aeecf expand_gimple_stmt_1
	/home/sellcey/gcc-vect/src/gcc/gcc/cfgexpand.c:3746
0x9aeecf expand_gimple_stmt
	/home/sellcey/gcc-vect/src/gcc/gcc/cfgexpand.c:3844
0x9b682f expand_gimple_basic_block
	/home/sellcey/gcc-vect/src/gcc/gcc/cfgexpand.c:5880
0x9b90a7 execute
	/home/sellcey/gcc-vect/src/gcc/gcc/cfgexpand.c:6503
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.



gcc.dg/gomp/simd-clones-1.c is pretty small, when I run that
I get the same trace as above.

Here is the current version of my patch.

2018-01-15  Steve Ellcey  <sellcey@cavium.com>

	* config/aarch64/aarch64.c (cgraph.h): New include.
	(intl.h): New include.
	(supported_simd_type): New function.
	(currently_supported_simd_type): Ditto.
	(aarch64_simd_clone_compute_vecsize_and_simdlen): Ditto.
	(aarch64_simd_clone_adjust): Ditto.
	(aarch64_simd_clone_usable): Ditto.
	(TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN): New macro.
	(TARGET_SIMD_CLONE_ADJUST): Ditto.
	(TARGET_SIMD_CLONE_USABLE): Ditto.
	* config/i386/i386.c (ix86_simd_clone_adjust): Add definition check.
	* omp-simd-clone.c (expand_simd_clones): Add targetm.simd_clone.adjust
	call.


2018-01-15  Steve Ellcey  <sellcey@cavium.com>

	* c-c++-common/gomp/pr60823-1.c: Add aarch64 specific
	warning checks and assembler scans.
	* c-c++-common/gomp/pr60823-3.c: Ditto.
	* g++.dg/gomp/declare-simd-1.C: Ditto.
	* g++.dg/gomp/declare-simd-3.C: Ditto.
	* g++.dg/gomp/declare-simd-4.C: Ditto.
	* g++.dg/gomp/declare-simd-7.C: Ditto.
	* g++.dg/gomp/pr88182.C: Ditto.
	* gcc.dg/gomp/declare-simd-1.c: Ditto.
	* gcc.dg/gomp/declare-simd-3.c: Ditto.
	* gcc.dg/gomp/pr59669-2.c: Ditto.
	* gcc.dg/gomp/pr87895-1.c: Ditto.
	* gcc.dg/gomp/simd-clones-2.c: Ditto.
	* gfortran.dg/gomp/declare-simd-2.f90: Ditto.
	* gfortran.dg/gomp/pr79154-1.f90: Ditto.
	* gfortran.dg/gomp/pr83977.f90: Ditto.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index fd60bdd..5e5248f 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -40,6 +40,7 @@
 #include "regs.h"
 #include "emit-rtl.h"
 #include "recog.h"
+#include "cgraph.h"
 #include "diagnostic.h"
 #include "insn-attr.h"
 #include "alias.h"
@@ -71,6 +72,7 @@
 #include "selftest.h"
 #include "selftest-rtl.h"
 #include "rtx-vector-builder.h"
+#include "intl.h"
 
 /* This file should be included last.  */
 #include "target-def.h"
@@ -18420,6 +18422,151 @@ aarch64_estimated_poly_value (poly_int64 val)
   return val.coeffs[0] + val.coeffs[1] * over_128 / 128;
 }
 
+
+/* Return true for types that could be supported as SIMD return or
+   argument types.  */
+
+static bool supported_simd_type (tree t)
+{
+  if (SCALAR_FLOAT_TYPE_P (t) || INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
+    {
+      HOST_WIDE_INT s = tree_to_shwi (TYPE_SIZE_UNIT (t));
+      return s == 1 || s == 2 || s == 4 || s == 8;
+    }
+  return false;
+}
+
+/* Return true for types that currently are supported as SIMD return
+   or argument types.  */
+
+static bool currently_supported_simd_type (tree t, tree b)
+{
+  if (COMPLEX_FLOAT_TYPE_P (t))
+    return false;
+
+  if (TYPE_SIZE (t) != TYPE_SIZE (b))
+    return false;
+
+  return supported_simd_type (t);
+}
+
+/* Implement TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN.  */
+
+static int
+aarch64_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
+					struct cgraph_simd_clone *clonei,
+					tree base_type, int num)
+{
+  int vsize;
+  tree t, ret_type, arg_type;
+
+  if (!TARGET_SIMD)
+    return 0;
+
+  if (clonei->simdlen
+      && (clonei->simdlen < 2
+	  || clonei->simdlen > 1024
+	  || (clonei->simdlen & (clonei->simdlen - 1)) != 0))
+    {
+      warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		  "unsupported simdlen %d", clonei->simdlen);
+      return 0;
+    }
+
+  ret_type = TREE_TYPE (TREE_TYPE (node->decl));
+  if (TREE_CODE (ret_type) != VOID_TYPE
+      && !currently_supported_simd_type (ret_type, base_type))
+    {
+      if (TYPE_SIZE (ret_type) != TYPE_SIZE (base_type))
+	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		    "GCC does not currently support mixed size types "
+		    "for %<simd%> functions");
+      else if (supported_simd_type (ret_type))
+	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		    "GCC does not currently support return type %qT "
+		    "for %<simd%> functions", ret_type);
+      else
+	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		    "unsupported return type %qT for %<simd%> functions",
+		    ret_type);
+      return 0;
+    }
+
+  for (t = DECL_ARGUMENTS (node->decl); t; t = DECL_CHAIN (t))
+    {
+      arg_type = TREE_TYPE (t);
+
+      if (!currently_supported_simd_type (arg_type, base_type))
+	{
+	  if (TYPE_SIZE (arg_type) != TYPE_SIZE (base_type))
+	    warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+			"GCC does not currently support mixed size types "
+			"for %<simd%> functions");
+	  else
+	    warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+			"GCC does not currently support argument type %qT "
+			"for %<simd%> functions", arg_type);
+	  return 0;
+	}
+    }
+
+  clonei->vecsize_mangle = 'n';
+  clonei->mask_mode = VOIDmode;
+  clonei->vecsize_int = (num == 0) ? 64 :128;
+  clonei->vecsize_float = (num == 0) ? 64 :128;
+  if (clonei->simdlen == 0)
+    {
+      if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
+	clonei->simdlen = clonei->vecsize_int;
+      else
+	clonei->simdlen = clonei->vecsize_float;
+      clonei->simdlen /= GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type));
+      return 2;
+    }
+
+  /* Restrict ourselves to vectors that fit in a single register  */
+
+  gcc_assert (tree_fits_shwi_p (TYPE_SIZE (base_type)));
+  vsize = clonei->simdlen * tree_to_shwi (TYPE_SIZE (base_type));
+  if (vsize != 64 && vsize != 128)
+    {
+      warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		  "GCC does not currently support simdlen %d for type %qT",
+		  clonei->simdlen, base_type);
+      return 0;
+    }
+  return 2;
+}
+
+/* Implement TARGET_SIMD_CLONE_ADJUST.  */
+
+static void
+aarch64_simd_clone_adjust (struct cgraph_node *node)
+{
+  /* Add aarch64_vector_pcs target attribute to SIMD clones so they
+     use the correct ABI.  */
+
+  tree t = TREE_TYPE (node->decl);
+  TYPE_ATTRIBUTES (t) = make_attribute ("aarch64_vector_pcs", "default",
+					TYPE_ATTRIBUTES (t));
+}
+
+/* Implement TARGET_SIMD_CLONE_USABLE.  */
+
+static int
+aarch64_simd_clone_usable (struct cgraph_node *node)
+{
+  switch (node->simdclone->vecsize_mangle)
+    {
+    case 'n':
+      if (!TARGET_SIMD)
+	return -1;
+      return 0;
+    default:
+      gcc_unreachable ();
+    }
+}
+
 /* Target-specific selftests.  */
 
 #if CHECKING_P
@@ -18913,6 +19060,16 @@ aarch64_libgcc_floating_mode_supported_p
 #undef TARGET_ATTRIBUTE_TABLE
 #define TARGET_ATTRIBUTE_TABLE aarch64_attribute_table
 
+#undef TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN
+#define TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN \
+  aarch64_simd_clone_compute_vecsize_and_simdlen
+
+#undef TARGET_SIMD_CLONE_ADJUST
+#define TARGET_SIMD_CLONE_ADJUST aarch64_simd_clone_adjust
+
+#undef TARGET_SIMD_CLONE_USABLE
+#define TARGET_SIMD_CLONE_USABLE aarch64_simd_clone_usable
+
 #if CHECKING_P
 #undef TARGET_RUN_TARGET_SELFTESTS
 #define TARGET_RUN_TARGET_SELFTESTS selftest::aarch64_run_selftests
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b0b7580..2f6e786 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -50649,6 +50649,11 @@ static void
 ix86_simd_clone_adjust (struct cgraph_node *node)
 {
   const char *str = NULL;
+
+  /* Attributes need to be adjusted for definitions, not declarations.  */
+  if (!node->definition)
+    return;
+
   gcc_assert (node->decl == cfun->decl);
   switch (node->simdclone->vecsize_mangle)
     {
diff --git a/gcc/omp-simd-clone.c b/gcc/omp-simd-clone.c
index 783118f..9b8111c 100644
--- a/gcc/omp-simd-clone.c
+++ b/gcc/omp-simd-clone.c
@@ -1685,6 +1685,7 @@ expand_simd_clones (struct cgraph_node *node)
 	    simd_clone_adjust (n);
 	  else
 	    {
+	      targetm.simd_clone.adjust (n);
 	      simd_clone_adjust_return_type (n);
 	      simd_clone_adjust_argument_types (n);
 	    }
diff --git a/gcc/testsuite/c-c++-common/gomp/pr60823-1.c b/gcc/testsuite/c-c++-common/gomp/pr60823-1.c
index 5f98572..d0aeb2e 100644
--- a/gcc/testsuite/c-c++-common/gomp/pr60823-1.c
+++ b/gcc/testsuite/c-c++-common/gomp/pr60823-1.c
@@ -17,3 +17,4 @@ foo (const double c1, const double c2)
     }
   return res;
 }
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-13 } */
diff --git a/gcc/testsuite/c-c++-common/gomp/pr60823-3.c b/gcc/testsuite/c-c++-common/gomp/pr60823-3.c
index 93e9fbe..5c36286 100644
--- a/gcc/testsuite/c-c++-common/gomp/pr60823-3.c
+++ b/gcc/testsuite/c-c++-common/gomp/pr60823-3.c
@@ -28,5 +28,6 @@ foo (double c1, double c2)
   baz (*(struct S *)&c1, *(struct S *)&c2);
   return c1 + c2 + ((struct S *)&c1)->c[1];
 }
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-16 } */
 
 #endif
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-1.C b/gcc/testsuite/g++.dg/gomp/declare-simd-1.C
index d2659e1..c147978 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-1.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-1.C
@@ -14,6 +14,7 @@ int f2 (int a, int *b, int c)
   return a + *b + c;
 }
 
+// { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbM8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -89,6 +90,8 @@ namespace N1
 // { dg-final { scan-assembler-times "_ZGVdN2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnM2va16__ZN2N12N23f10EPx:" 1 { target { aarch64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnN2va16__ZN2N12N23f10EPx:" 1 { target { aarch64-*-* } } } }
 
 struct A
 {
@@ -191,6 +194,7 @@ int B<int>::f25<7> (int a, int *b, int c)
   return a + *b + c;
 }
 
+// { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbM8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -216,6 +220,8 @@ int B<int>::f26<-1> (int a, int *b, int c)
 // { dg-final { scan-assembler-times "_ZGVdN4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnM4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { aarch64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnN4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { aarch64-*-* } } } }
 
 int
 f27 (int x)
@@ -239,6 +245,7 @@ f30 (int x)
   return x;
 }
 
+// { dg-warning "GCC does not currently support simdlen 16 for type 'int'" "" { target aarch64-*-* } .-7 }
 // { dg-final { scan-assembler-times "_ZGVbM16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -281,6 +288,7 @@ struct D
   int f37 (int a);
   int e;
 };
+// { dg-warning "GCC does not currently support simdlen 16 for type 'int'" "" { target aarch64-*-* } .-3 }
 
 void
 f38 (D &d)
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-3.C b/gcc/testsuite/g++.dg/gomp/declare-simd-3.C
index 32cdc58..0706c79 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-3.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-3.C
@@ -13,6 +13,7 @@ int f1 (int a, int b, int c, int &d, int &e, int &f)
   return a + b + c + d + e + f;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-11 }
 // { dg-final { scan-assembler-times "_ZGVbM4vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN4vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM4vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -21,6 +22,7 @@ int f1 (int a, int b, int c, int &d, int &e, int &f)
 // { dg-final { scan-assembler-times "_ZGVdN8vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM16vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN16vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
+                                      
 
 #pragma omp declare simd uniform(b) linear(c, d) linear(uval(e)) linear(ref(f))
 int f2 (int a, int b, int c, int &d, int &e, int &f)
@@ -40,6 +42,7 @@ int f2 (int a, int b, int c, int &d, int &e, int &f)
   return a + b + c + d + e + f;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-17 }
 // { dg-final { scan-assembler-times "_ZGVbM4vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN4vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM4vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -55,6 +58,7 @@ int f3 (const int a, const int b, const int c, const int &d, const int &e, const
   return a + b + c + d + e + f;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbM4vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN4vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM4vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -76,6 +80,7 @@ int f4 (const int a, const int b, const int c, const int &d, const int &e, const
   return a + b + c + d + e + f;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-11 }
 // { dg-final { scan-assembler-times "_ZGVbM4vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN4vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM4vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-4.C b/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
index acf03d9..1289f48 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
@@ -5,6 +5,7 @@ f1 (int *p, int *q, short *s)
   return *p + *q + *s;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbM4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -21,6 +22,7 @@ f2 (int *p, short *q, int s, int r, int &t)
   return *p + *q + r;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVdN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -33,6 +35,7 @@ f3 (int &p, short &q, int s, int &r, int &t)
   return p + q + r;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVdN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-7.C b/gcc/testsuite/g++.dg/gomp/declare-simd-7.C
index 52e9f18..1614db5 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-7.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-7.C
@@ -18,6 +18,7 @@ foo1 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j,
 {
   return bar1 (a, b, c, d, e, f, g, h, i, j, k);
 }
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-4 }
 
 #pragma omp declare simd inbranch uniform (b, c, d, e) aligned (e : 16) \
 		    linear (f : 2) linear (ref (g) : 1) \
@@ -28,6 +29,7 @@ foo2 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j,
 {
   return bar2 (a, b, c, d, e, f, g, h, i, j, k);
 }
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-4 }
 
 #pragma omp declare simd notinbranch uniform (b, c, d, e) aligned (e : 16) \
 		    linear (f : 2) linear (ref (g) : 1) \
@@ -38,6 +40,7 @@ foo3 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j,
 {
   return bar3 (a, b, c, d, e, f, g, h, i, j, k);
 }
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-4 }
 
 #pragma omp declare simd inbranch uniform (b, c, d, e) aligned (e : 16) \
 		    linear (f : 2) linear (ref (g) : 1) \
@@ -48,3 +51,4 @@ foo4 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j,
 {
   return bar4 (a, b, c, d, e, f, g, h, i, j, k);
 }
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-4 }
diff --git a/gcc/testsuite/g++.dg/gomp/pr88182.C b/gcc/testsuite/g++.dg/gomp/pr88182.C
index 6eeeed9..c783edc 100644
--- a/gcc/testsuite/g++.dg/gomp/pr88182.C
+++ b/gcc/testsuite/g++.dg/gomp/pr88182.C
@@ -18,6 +18,7 @@ foo (double c1, double c2)
     }
   return res;
 }
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-15 }
 
 __attribute__((noinline, noclone)) void
 bar (double *x, double *y)
diff --git a/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c b/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c
index b8bba1f..003b054 100644
--- a/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c
+++ b/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c
@@ -13,6 +13,7 @@ int f2 (int a, int *b, int c)
   return a + *b + c;
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' function" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -49,6 +50,7 @@ f7 (int x)
   return x;
 }
 
+/* { dg-warning "GCC does not currently support simdlen 16 for type 'int'" "" { target aarch64-*-* } .-7 } */
 /* { dg-final { scan-assembler-times "_ZGVbM16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -68,6 +70,7 @@ f13 (int c; int *b; int a; int a, int *b, int c)
   return a + *b + c;
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' function" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -86,6 +89,7 @@ f14 (a, b, c)
   return a + *b + c;
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' function" "" { target aarch64-*-* } .-7 } */
 /* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -102,6 +106,7 @@ f15 (int a, int *b, int c)
   return a + *b + c;
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' function" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -123,6 +128,7 @@ int f17 (int g, long *h)
   return g + h[0];
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' function" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbM4l20va8_f17:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN4l20va8_f17:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM4l20va8_f17:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */
@@ -149,6 +155,7 @@ f18 (j, i)
   return j + i[0];
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' function" "" { target aarch64-*-* } .-7 } */
 /* { dg-final { scan-assembler-times "_ZGVbM4l20va8_f18:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN4l20va8_f18:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM4l20va8_f18:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c b/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c
index 9b8546d..66dc740 100644
--- a/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c
+++ b/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c
@@ -5,6 +5,7 @@ f1 (int *p, int *q, short *s)
   return *p + *q + *s;
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbM4l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN4l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM4l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -21,6 +22,7 @@ f2 (int *p, short *q, int s, int r, int t)
   return *p + *q + r;
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVdN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/pr59669-2.c b/gcc/testsuite/gcc.dg/gomp/pr59669-2.c
index f6aad89..46294db 100644
--- a/gcc/testsuite/gcc.dg/gomp/pr59669-2.c
+++ b/gcc/testsuite/gcc.dg/gomp/pr59669-2.c
@@ -7,3 +7,4 @@ void
 bar (int *a)
 {
 }
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-3 } */
diff --git a/gcc/testsuite/gcc.dg/gomp/pr87895-1.c b/gcc/testsuite/gcc.dg/gomp/pr87895-1.c
index 22f5c69..7f5397b 100644
--- a/gcc/testsuite/gcc.dg/gomp/pr87895-1.c
+++ b/gcc/testsuite/gcc.dg/gomp/pr87895-1.c
@@ -17,3 +17,4 @@ bar (int *x, int y)
   if ((y == 0) ? (*x = 0) : *x)
     return 0;
 }
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 } */
diff --git a/gcc/testsuite/gcc.dg/gomp/simd-clones-2.c b/gcc/testsuite/gcc.dg/gomp/simd-clones-2.c
index df7f631..3201c96 100644
--- a/gcc/testsuite/gcc.dg/gomp/simd-clones-2.c
+++ b/gcc/testsuite/gcc.dg/gomp/simd-clones-2.c
@@ -6,6 +6,7 @@ int addit(int a, int b, int *c)
 {
   return a + b;
 }
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-4 } */
 
 #pragma omp declare simd uniform(a) aligned(a:32) linear(k:1) notinbranch
 float setArray(float *a, float x, int k)
@@ -14,6 +15,7 @@ float setArray(float *a, float x, int k)
   return a[k];
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-6 } */
 /* { dg-final { scan-tree-dump "_ZGVbN4ua32vl_setArray" "optimized" { target i?86-*-* x86_64-*-* } } } */
 /* { dg-final { scan-tree-dump "_ZGVbN4vvva32_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */
 /* { dg-final { scan-tree-dump "_ZGVbM4vl66u_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */
diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-simd-2.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-simd-2.f90
index 8f76774..fd4e119 100644
--- a/gcc/testsuite/gfortran.dg/gomp/declare-simd-2.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/declare-simd-2.f90
@@ -1,6 +1,6 @@
 ! { dg-do compile }
 
-function f1 (a, b, c, d, e, f)
+function f1 (a, b, c, d, e, f) ! { dg-warning "GCC does not currently support mixed size types for 'simd' functions" }
   integer, value :: a, b, c
   integer :: d, e, f, f1
 !$omp declare simd (f1) uniform(b) linear(c, d) linear(uval(e)) linear(ref(f))
@@ -12,7 +12,7 @@ function f1 (a, b, c, d, e, f)
   f = f + 1
   f1 = a + b + c + d + e + f
 end function f1
-integer function f2 (a, b)
+integer function f2 (a, b) ! { dg-warning "GCC does not currently support mixed size types for 'simd' functions" }
   integer :: a, b
 !$omp declare simd uniform(b) linear(ref(a):b)
   a = a + 1
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr79154-1.f90 b/gcc/testsuite/gfortran.dg/gomp/pr79154-1.f90
index 6c86ded..953dcad 100644
--- a/gcc/testsuite/gfortran.dg/gomp/pr79154-1.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/pr79154-1.f90
@@ -1,7 +1,7 @@
 ! PR fortran/79154
 ! { dg-do compile }
 
-pure real function foo (a, b)
+pure real function foo (a, b)		! { dg-warning "GCC does not currently support mixed size types for 'simd' functions" }
 !$omp declare simd(foo)			! { dg-bogus "may not appear in PURE or ELEMENTAL" }
   real, intent(in) :: a, b
   foo = a + b
@@ -20,7 +20,7 @@ pure real function baz (a, b)
   real, intent(in) :: a, b
   baz = a + b
 end function baz
-elemental real function fooe (a, b)
+elemental real function fooe (a, b)	! { dg-warning "GCC does not currently support mixed size types for 'simd' functions" }
 !$omp declare simd(fooe)		! { dg-bogus "may not appear in PURE or ELEMENTAL" }
   real, intent(in) :: a, b
   fooe = a + b
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr83977.f90 b/gcc/testsuite/gfortran.dg/gomp/pr83977.f90
index b8ad1a7..6dfdbc3 100644
--- a/gcc/testsuite/gfortran.dg/gomp/pr83977.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/pr83977.f90
@@ -1,7 +1,7 @@
 ! PR middle-end/83977
 ! { dg-do compile }
 
-integer function foo (a, b)
+integer function foo (a, b) ! { dg-warning "GCC does not currently support mixed size types for 'simd' functions" }
    integer :: a, b
 !$omp declare simd uniform(b) linear(ref(a):b)
    a = a + 1
Richard Sandiford Jan. 16, 2019, 8:50 a.m. UTC | #13
Steve Ellcey <sellcey@marvell.com> writes:
> Here are the failures I am getting with this patch:
>
> c-c++-common/gomp/pr63328.c
> gcc.dg/gomp/pr87895-2.c
>
> These tests include another test (which passes) and the included tests
> have a dg-warning check.  For some reason the dg-warning in the include
> is ignored

Yeah, that's expected.  Only dg- markup in the test file itself
is relevant.

> and when I tried adding one in the main file (that includes
> the other test), that didn't work either.

I suggest for now we add:

/* { dg-excess-errors "partial simd clone support" { target { aarch64*-*-* } } }  */

> gcc.dg/gomp/simd-clones-1.c
> g++.dg/gomp/declare-simd-1.C
>
> These two tests are generating an ICE and I am not sure why.
>
> I cut declare-simd-1.C down to:
>
> #pragma omp declare simd simdlen (2) aligned (b : sizeof (long long) * 2)
> __extension__ long long
> f10 (long long *b)
> {
>       return *b;
> }
>
> And it results in:
>
> % install/usr/bin/g++ -fopenmp-simd -c b1.C
> during RTL pass: expand
> b1.C: In function ‘long long int f10(long long int*)’:
> b1.C:5:15: internal compiler error: in expand_assignment, at expr.c:5101
>     5 |       return *b;
>       |               ^
> 0xaeee73 expand_assignment(tree_node*, tree_node*, bool)
> 	/home/sellcey/gcc-vect/src/gcc/gcc/expr.c:5101
> 0x9aeecf expand_gimple_stmt_1
> 	/home/sellcey/gcc-vect/src/gcc/gcc/cfgexpand.c:3746
> 0x9aeecf expand_gimple_stmt
> 	/home/sellcey/gcc-vect/src/gcc/gcc/cfgexpand.c:3844
> 0x9b682f expand_gimple_basic_block
> 	/home/sellcey/gcc-vect/src/gcc/gcc/cfgexpand.c:5880
> 0x9b90a7 execute
> 	/home/sellcey/gcc-vect/src/gcc/gcc/cfgexpand.c:6503
> Please submit a full bug report,
> with preprocessed source if appropriate.
> Please include the complete backtrace with any bug report.
> See <https://gcc.gnu.org/bugs/> for instructions.

I haven't checked whether this is the reason, but:

> +  clonei->vecsize_mangle = 'n';
> +  clonei->mask_mode = VOIDmode;
> +  clonei->vecsize_int = (num == 0) ? 64 :128;
> +  clonei->vecsize_float = (num == 0) ? 64 :128;
> +  if (clonei->simdlen == 0)
> +    {
> +      if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
> +	clonei->simdlen = clonei->vecsize_int;
> +      else
> +	clonei->simdlen = clonei->vecsize_float;
> +      clonei->simdlen /= GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type));
> +      return 2;
> +    }
> +
> +  /* Restrict ourselves to vectors that fit in a single register  */
> +
> +  gcc_assert (tree_fits_shwi_p (TYPE_SIZE (base_type)));
> +  vsize = clonei->simdlen * tree_to_shwi (TYPE_SIZE (base_type));
> +  if (vsize != 64 && vsize != 128)
> +    {
> +      warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
> +		  "GCC does not currently support simdlen %d for type %qT",
> +		  clonei->simdlen, base_type);
> +      return 0;
> +    }
> +  return 2;
> +}

...this doesn't handle explicit simdlen correctly.  The vecsize_int and
vecsize_float need to be set from the user's simdlen, with num only
making a difference for the default simdlen.  And there should only
be 1 size for an explicit simdlen.

Maybe this would be more obvious if we have something like:

  unsigned int elt_bits = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type));
  unsigned int vec_bits, count;
  if (clone->simdlen == 0)
    {
      count = 2;
      vec_bits = (num == 0 ? 64 : 128);
      clone->simdlen = vec_bits / elt_bits;
    }
  else
    {
      count = 1;
      vec_bits = clone->simdlen * elt_bits;
      if (vec_bits != 64 && vec_bits != 128)
        {
          ...warning...
          return 0;
        }
    }
  clone->vecsize_int = vec_bits;
  clone->vecsize_float = vec_bits;
  return count;

Thanks,
Richard
Steve Ellcey Jan. 16, 2019, 9:58 p.m. UTC | #14
On Wed, 2019-01-16 at 08:50 +0000, Richard Sandiford wrote:
> 
> I suggest for now we add:
> 
> /* { dg-excess-errors "partial simd clone support" { target { aarch64*-*-* } } }  */

OK, that works.

> 
> ...this doesn't handle explicit simdlen correctly.  The vecsize_int and
> vecsize_float need to be set from the user's simdlen, with num only
> making a difference for the default simdlen.  And there should only
> be 1 size for an explicit simdlen.
> 
> Maybe this would be more obvious if we have something like:

OK, that works better, I think returning 2 instead of 1 is what was
causing the ICE.  I used your code to set the return value and the
vecsize and everything works now.

Here is a new version of the patch, it bootstraps on aarch64 and x86
and the GCC testsuite ran with no regressions on both platforms as
well.

Steve Ellcey
sellcey@marvell.com


2018-01-16  Steve Ellcey  <sellcey@cavium.com>

	* config/aarch64/aarch64.c (cgraph.h): New include.
	(intl.h): New include.
	(supported_simd_type): New function.
	(currently_supported_simd_type): Ditto.
	(aarch64_simd_clone_compute_vecsize_and_simdlen): Ditto.
	(aarch64_simd_clone_adjust): Ditto.
	(aarch64_simd_clone_usable): Ditto.
	(TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN): New macro.
	(TARGET_SIMD_CLONE_ADJUST): Ditto.
	(TARGET_SIMD_CLONE_USABLE): Ditto.
	* config/i386/i386.c (ix86_simd_clone_adjust): Add definition check.
	* omp-simd-clone.c (expand_simd_clones): Add targetm.simd_clone.adjust
	call.

2018-01-16  Steve Ellcey  <sellcey@cavium.com>

	* c-c++-common/gomp/pr60823-1.c: Add aarch64 specific
	warning checks and assembler scans.
	* c-c++-common/gomp/pr60823-3.c: Ditto.
	* c-c++-common/gomp/pr63328.c: Ditto.
	* g++.dg/gomp/declare-simd-1.C: Ditto.
	* g++.dg/gomp/declare-simd-3.C: Ditto.
	* g++.dg/gomp/declare-simd-4.C: Ditto.
	* g++.dg/gomp/declare-simd-7.C: Ditto.
	* g++.dg/gomp/pr88182.C: Ditto.
	* g++.dg/vect/simd-clone-7.cc: Ditto.
	* gcc.dg/gomp/declare-simd-1.c: Ditto.
	* gcc.dg/gomp/declare-simd-3.c: Ditto.
	* gcc.dg/gomp/pr59669-2.c: Ditto.
	* gcc.dg/gomp/pr87895-1.c: Ditto.
	* gcc.dg/gomp/pr87895-2.c: Ditto.
	* gcc.dg/gomp/simd-clones-2.c: Ditto.
	* gfortran.dg/gomp/declare-simd-2.f90: Ditto.
	* gfortran.dg/gomp/pr79154-1.f90: Ditto.
	* gfortran.dg/gomp/pr83977.f90: Ditto.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index fd60bdd..7331482 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -40,6 +40,7 @@
 #include "regs.h"
 #include "emit-rtl.h"
 #include "recog.h"
+#include "cgraph.h"
 #include "diagnostic.h"
 #include "insn-attr.h"
 #include "alias.h"
@@ -71,6 +72,7 @@
 #include "selftest.h"
 #include "selftest-rtl.h"
 #include "rtx-vector-builder.h"
+#include "intl.h"
 
 /* This file should be included last.  */
 #include "target-def.h"
@@ -18420,6 +18422,149 @@ aarch64_estimated_poly_value (poly_int64 val)
   return val.coeffs[0] + val.coeffs[1] * over_128 / 128;
 }
 
+
+/* Return true for types that could be supported as SIMD return or
+   argument types.  */
+
+static bool supported_simd_type (tree t)
+{
+  if (SCALAR_FLOAT_TYPE_P (t) || INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
+    {
+      HOST_WIDE_INT s = tree_to_shwi (TYPE_SIZE_UNIT (t));
+      return s == 1 || s == 2 || s == 4 || s == 8;
+    }
+  return false;
+}
+
+/* Return true for types that currently are supported as SIMD return
+   or argument types.  */
+
+static bool currently_supported_simd_type (tree t, tree b)
+{
+  if (COMPLEX_FLOAT_TYPE_P (t))
+    return false;
+
+  if (TYPE_SIZE (t) != TYPE_SIZE (b))
+    return false;
+
+  return supported_simd_type (t);
+}
+
+/* Implement TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN.  */
+
+static int
+aarch64_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
+					struct cgraph_simd_clone *clonei,
+					tree base_type, int num)
+{
+  tree t, ret_type, arg_type;
+  unsigned int elt_bits, vec_bits, count;
+
+  if (!TARGET_SIMD)
+    return 0;
+
+  if (clonei->simdlen
+      && (clonei->simdlen < 2
+	  || clonei->simdlen > 1024
+	  || (clonei->simdlen & (clonei->simdlen - 1)) != 0))
+    {
+      warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		  "unsupported simdlen %d", clonei->simdlen);
+      return 0;
+    }
+
+  ret_type = TREE_TYPE (TREE_TYPE (node->decl));
+  if (TREE_CODE (ret_type) != VOID_TYPE
+      && !currently_supported_simd_type (ret_type, base_type))
+    {
+      if (TYPE_SIZE (ret_type) != TYPE_SIZE (base_type))
+	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		    "GCC does not currently support mixed size types "
+		    "for %<simd%> functions");
+      else if (supported_simd_type (ret_type))
+	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		    "GCC does not currently support return type %qT "
+		    "for %<simd%> functions", ret_type);
+      else
+	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		    "unsupported return type %qT for %<simd%> functions",
+		    ret_type);
+      return 0;
+    }
+
+  for (t = DECL_ARGUMENTS (node->decl); t; t = DECL_CHAIN (t))
+    {
+      arg_type = TREE_TYPE (t);
+
+      if (!currently_supported_simd_type (arg_type, base_type))
+	{
+	  if (TYPE_SIZE (arg_type) != TYPE_SIZE (base_type))
+	    warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+			"GCC does not currently support mixed size types "
+			"for %<simd%> functions");
+	  else
+	    warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+			"GCC does not currently support argument type %qT "
+			"for %<simd%> functions", arg_type);
+	  return 0;
+	}
+    }
+
+  clonei->vecsize_mangle = 'n';
+  clonei->mask_mode = VOIDmode;
+  elt_bits = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type));
+  if (clonei->simdlen == 0)
+    {
+      count = 2;
+      vec_bits = (num == 0 ? 64 : 128);
+      clonei->simdlen = vec_bits / elt_bits;
+    }
+  else
+    {
+      count = 1;
+      vec_bits = clonei->simdlen * elt_bits;
+      if (vec_bits != 64 && vec_bits != 128)
+        {
+	  warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		      "GCC does not currently support simdlen %d for type %qT",
+		      clonei->simdlen, base_type);
+          return 0;
+        }
+    }
+  clonei->vecsize_int = vec_bits;
+  clonei->vecsize_float = vec_bits;
+  return count;
+}
+
+/* Implement TARGET_SIMD_CLONE_ADJUST.  */
+
+static void
+aarch64_simd_clone_adjust (struct cgraph_node *node)
+{
+  /* Add aarch64_vector_pcs target attribute to SIMD clones so they
+     use the correct ABI.  */
+
+  tree t = TREE_TYPE (node->decl);
+  TYPE_ATTRIBUTES (t) = make_attribute ("aarch64_vector_pcs", "default",
+					TYPE_ATTRIBUTES (t));
+}
+
+/* Implement TARGET_SIMD_CLONE_USABLE.  */
+
+static int
+aarch64_simd_clone_usable (struct cgraph_node *node)
+{
+  switch (node->simdclone->vecsize_mangle)
+    {
+    case 'n':
+      if (!TARGET_SIMD)
+	return -1;
+      return 0;
+    default:
+      gcc_unreachable ();
+    }
+}
+
 /* Target-specific selftests.  */
 
 #if CHECKING_P
@@ -18913,6 +19058,16 @@ aarch64_libgcc_floating_mode_supported_p
 #undef TARGET_ATTRIBUTE_TABLE
 #define TARGET_ATTRIBUTE_TABLE aarch64_attribute_table
 
+#undef TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN
+#define TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN \
+  aarch64_simd_clone_compute_vecsize_and_simdlen
+
+#undef TARGET_SIMD_CLONE_ADJUST
+#define TARGET_SIMD_CLONE_ADJUST aarch64_simd_clone_adjust
+
+#undef TARGET_SIMD_CLONE_USABLE
+#define TARGET_SIMD_CLONE_USABLE aarch64_simd_clone_usable
+
 #if CHECKING_P
 #undef TARGET_RUN_TARGET_SELFTESTS
 #define TARGET_RUN_TARGET_SELFTESTS selftest::aarch64_run_selftests
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b0b7580..2f6e786 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -50649,6 +50649,11 @@ static void
 ix86_simd_clone_adjust (struct cgraph_node *node)
 {
   const char *str = NULL;
+
+  /* Attributes need to be adjusted for definitions, not declarations.  */
+  if (!node->definition)
+    return;
+
   gcc_assert (node->decl == cfun->decl);
   switch (node->simdclone->vecsize_mangle)
     {
diff --git a/gcc/omp-simd-clone.c b/gcc/omp-simd-clone.c
index 783118f..9b8111c 100644
--- a/gcc/omp-simd-clone.c
+++ b/gcc/omp-simd-clone.c
@@ -1685,6 +1685,7 @@ expand_simd_clones (struct cgraph_node *node)
 	    simd_clone_adjust (n);
 	  else
 	    {
+	      targetm.simd_clone.adjust (n);
 	      simd_clone_adjust_return_type (n);
 	      simd_clone_adjust_argument_types (n);
 	    }
diff --git a/gcc/testsuite/c-c++-common/gomp/pr60823-1.c b/gcc/testsuite/c-c++-common/gomp/pr60823-1.c
index 5f98572..d0aeb2e 100644
--- a/gcc/testsuite/c-c++-common/gomp/pr60823-1.c
+++ b/gcc/testsuite/c-c++-common/gomp/pr60823-1.c
@@ -17,3 +17,4 @@ foo (const double c1, const double c2)
     }
   return res;
 }
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-13 } */
diff --git a/gcc/testsuite/c-c++-common/gomp/pr60823-3.c b/gcc/testsuite/c-c++-common/gomp/pr60823-3.c
index 93e9fbe..5c36286 100644
--- a/gcc/testsuite/c-c++-common/gomp/pr60823-3.c
+++ b/gcc/testsuite/c-c++-common/gomp/pr60823-3.c
@@ -28,5 +28,6 @@ foo (double c1, double c2)
   baz (*(struct S *)&c1, *(struct S *)&c2);
   return c1 + c2 + ((struct S *)&c1)->c[1];
 }
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-16 } */
 
 #endif
diff --git a/gcc/testsuite/c-c++-common/gomp/pr63328.c b/gcc/testsuite/c-c++-common/gomp/pr63328.c
index 3958abe..54eface 100644
--- a/gcc/testsuite/c-c++-common/gomp/pr63328.c
+++ b/gcc/testsuite/c-c++-common/gomp/pr63328.c
@@ -3,3 +3,5 @@
 /* { dg-options "-O2 -fopenmp-simd -fno-strict-aliasing -fcompare-debug" } */
 
 #include "pr60823-3.c"
+/* { dg-excess-errors "partial simd clone support" { target { aarch64*-*-* } } }  */
+
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-1.C b/gcc/testsuite/g++.dg/gomp/declare-simd-1.C
index d2659e1..cc17c9c 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-1.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-1.C
@@ -14,6 +14,7 @@ int f2 (int a, int *b, int c)
   return a + *b + c;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbM8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -89,6 +90,8 @@ namespace N1
 // { dg-final { scan-assembler-times "_ZGVdN2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnM2va16__ZN2N12N23f10EPx:" 1 { target { aarch64-*-* } } } }
+// { dg-final { scan-assembler-times "_ZGVnN2va16__ZN2N12N23f10EPx:" 1 { target { aarch64-*-* } } } }
 
 struct A
 {
@@ -191,6 +194,7 @@ int B<int>::f25<7> (int a, int *b, int c)
   return a + *b + c;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbM8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -208,6 +212,7 @@ int B<int>::f26<-1> (int a, int *b, int c)
   return a + *b + c;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbM4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -239,6 +244,7 @@ f30 (int x)
   return x;
 }
 
+// { dg-warning "GCC does not currently support simdlen 16 for type 'int'" "" { target aarch64-*-* } .-7 }
 // { dg-final { scan-assembler-times "_ZGVbM16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -281,6 +287,7 @@ struct D
   int f37 (int a);
   int e;
 };
+// { dg-warning "GCC does not currently support simdlen 16 for type 'int'" "" { target aarch64-*-* } .-3 }
 
 void
 f38 (D &d)
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-3.C b/gcc/testsuite/g++.dg/gomp/declare-simd-3.C
index 32cdc58..0706c79 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-3.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-3.C
@@ -13,6 +13,7 @@ int f1 (int a, int b, int c, int &d, int &e, int &f)
   return a + b + c + d + e + f;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-11 }
 // { dg-final { scan-assembler-times "_ZGVbM4vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN4vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM4vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -21,6 +22,7 @@ int f1 (int a, int b, int c, int &d, int &e, int &f)
 // { dg-final { scan-assembler-times "_ZGVdN8vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeM16vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVeN16vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
+                                      
 
 #pragma omp declare simd uniform(b) linear(c, d) linear(uval(e)) linear(ref(f))
 int f2 (int a, int b, int c, int &d, int &e, int &f)
@@ -40,6 +42,7 @@ int f2 (int a, int b, int c, int &d, int &e, int &f)
   return a + b + c + d + e + f;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-17 }
 // { dg-final { scan-assembler-times "_ZGVbM4vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN4vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM4vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -55,6 +58,7 @@ int f3 (const int a, const int b, const int c, const int &d, const int &e, const
   return a + b + c + d + e + f;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbM4vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN4vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM4vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -76,6 +80,7 @@ int f4 (const int a, const int b, const int c, const int &d, const int &e, const
   return a + b + c + d + e + f;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-11 }
 // { dg-final { scan-assembler-times "_ZGVbM4vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN4vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM4vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } }
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-4.C b/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
index acf03d9..1289f48 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-4.C
@@ -5,6 +5,7 @@ f1 (int *p, int *q, short *s)
   return *p + *q + *s;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbM4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVbN4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcM4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -21,6 +22,7 @@ f2 (int *p, short *q, int s, int r, int &t)
   return *p + *q + r;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVdN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } }
@@ -33,6 +35,7 @@ f3 (int &p, short &q, int s, int &r, int &t)
   return p + q + r;
 }
 
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 }
 // { dg-final { scan-assembler-times "_ZGVbN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVcN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
 // { dg-final { scan-assembler-times "_ZGVdN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } }
diff --git a/gcc/testsuite/g++.dg/gomp/declare-simd-7.C b/gcc/testsuite/g++.dg/gomp/declare-simd-7.C
index 52e9f18..1614db5 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-simd-7.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-simd-7.C
@@ -18,6 +18,7 @@ foo1 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j,
 {
   return bar1 (a, b, c, d, e, f, g, h, i, j, k);
 }
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-4 }
 
 #pragma omp declare simd inbranch uniform (b, c, d, e) aligned (e : 16) \
 		    linear (f : 2) linear (ref (g) : 1) \
@@ -28,6 +29,7 @@ foo2 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j,
 {
   return bar2 (a, b, c, d, e, f, g, h, i, j, k);
 }
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-4 }
 
 #pragma omp declare simd notinbranch uniform (b, c, d, e) aligned (e : 16) \
 		    linear (f : 2) linear (ref (g) : 1) \
@@ -38,6 +40,7 @@ foo3 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j,
 {
   return bar3 (a, b, c, d, e, f, g, h, i, j, k);
 }
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-4 }
 
 #pragma omp declare simd inbranch uniform (b, c, d, e) aligned (e : 16) \
 		    linear (f : 2) linear (ref (g) : 1) \
@@ -48,3 +51,4 @@ foo4 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j,
 {
   return bar4 (a, b, c, d, e, f, g, h, i, j, k);
 }
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-4 }
diff --git a/gcc/testsuite/g++.dg/gomp/pr88182.C b/gcc/testsuite/g++.dg/gomp/pr88182.C
index 6eeeed9..c783edc 100644
--- a/gcc/testsuite/g++.dg/gomp/pr88182.C
+++ b/gcc/testsuite/g++.dg/gomp/pr88182.C
@@ -18,6 +18,7 @@ foo (double c1, double c2)
     }
   return res;
 }
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-15 }
 
 __attribute__((noinline, noclone)) void
 bar (double *x, double *y)
diff --git a/gcc/testsuite/g++.dg/vect/simd-clone-7.cc b/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
index fd5751b..c2a63cd 100644
--- a/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
+++ b/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
@@ -8,3 +8,4 @@ bar (float x, float *y, int)
 {
   return y[0] + y[1] * x;
 }
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-4 }
diff --git a/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c b/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c
index b8bba1f..003b054 100644
--- a/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c
+++ b/gcc/testsuite/gcc.dg/gomp/declare-simd-1.c
@@ -13,6 +13,7 @@ int f2 (int a, int *b, int c)
   return a + *b + c;
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' function" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -49,6 +50,7 @@ f7 (int x)
   return x;
 }
 
+/* { dg-warning "GCC does not currently support simdlen 16 for type 'int'" "" { target aarch64-*-* } .-7 } */
 /* { dg-final { scan-assembler-times "_ZGVbM16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -68,6 +70,7 @@ f13 (int c; int *b; int a; int a, int *b, int c)
   return a + *b + c;
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' function" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -86,6 +89,7 @@ f14 (a, b, c)
   return a + *b + c;
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' function" "" { target aarch64-*-* } .-7 } */
 /* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -102,6 +106,7 @@ f15 (int a, int *b, int c)
   return a + *b + c;
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' function" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -123,6 +128,7 @@ int f17 (int g, long *h)
   return g + h[0];
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' function" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbM4l20va8_f17:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN4l20va8_f17:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM4l20va8_f17:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */
@@ -149,6 +155,7 @@ f18 (j, i)
   return j + i[0];
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' function" "" { target aarch64-*-* } .-7 } */
 /* { dg-final { scan-assembler-times "_ZGVbM4l20va8_f18:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN4l20va8_f18:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM4l20va8_f18:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c b/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c
index 9b8546d..66dc740 100644
--- a/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c
+++ b/gcc/testsuite/gcc.dg/gomp/declare-simd-3.c
@@ -5,6 +5,7 @@ f1 (int *p, int *q, short *s)
   return *p + *q + *s;
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbM4l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVbN4l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcM4l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */
@@ -21,6 +22,7 @@ f2 (int *p, short *q, int s, int r, int t)
   return *p + *q + r;
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 } */
 /* { dg-final { scan-assembler-times "_ZGVbN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVcN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
 /* { dg-final { scan-assembler-times "_ZGVdN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/pr59669-2.c b/gcc/testsuite/gcc.dg/gomp/pr59669-2.c
index f6aad89..46294db 100644
--- a/gcc/testsuite/gcc.dg/gomp/pr59669-2.c
+++ b/gcc/testsuite/gcc.dg/gomp/pr59669-2.c
@@ -7,3 +7,4 @@ void
 bar (int *a)
 {
 }
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-3 } */
diff --git a/gcc/testsuite/gcc.dg/gomp/pr87895-1.c b/gcc/testsuite/gcc.dg/gomp/pr87895-1.c
index 22f5c69..7f5397b 100644
--- a/gcc/testsuite/gcc.dg/gomp/pr87895-1.c
+++ b/gcc/testsuite/gcc.dg/gomp/pr87895-1.c
@@ -17,3 +17,4 @@ bar (int *x, int y)
   if ((y == 0) ? (*x = 0) : *x)
     return 0;
 }
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-5 } */
diff --git a/gcc/testsuite/gcc.dg/gomp/pr87895-2.c b/gcc/testsuite/gcc.dg/gomp/pr87895-2.c
index 3d27715..26827ac 100644
--- a/gcc/testsuite/gcc.dg/gomp/pr87895-2.c
+++ b/gcc/testsuite/gcc.dg/gomp/pr87895-2.c
@@ -3,3 +3,4 @@
 /* { dg-additional-options "-O1" } */
 
 #include "pr87895-1.c"
+/* { dg-excess-errors "partial simd clone support" { target { aarch64*-*-* } } }  */
diff --git a/gcc/testsuite/gcc.dg/gomp/simd-clones-2.c b/gcc/testsuite/gcc.dg/gomp/simd-clones-2.c
index df7f631..3201c96 100644
--- a/gcc/testsuite/gcc.dg/gomp/simd-clones-2.c
+++ b/gcc/testsuite/gcc.dg/gomp/simd-clones-2.c
@@ -6,6 +6,7 @@ int addit(int a, int b, int *c)
 {
   return a + b;
 }
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-4 } */
 
 #pragma omp declare simd uniform(a) aligned(a:32) linear(k:1) notinbranch
 float setArray(float *a, float x, int k)
@@ -14,6 +15,7 @@ float setArray(float *a, float x, int k)
   return a[k];
 }
 
+/* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-6 } */
 /* { dg-final { scan-tree-dump "_ZGVbN4ua32vl_setArray" "optimized" { target i?86-*-* x86_64-*-* } } } */
 /* { dg-final { scan-tree-dump "_ZGVbN4vvva32_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */
 /* { dg-final { scan-tree-dump "_ZGVbM4vl66u_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */
diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-simd-2.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-simd-2.f90
index 8f76774..fd4e119 100644
--- a/gcc/testsuite/gfortran.dg/gomp/declare-simd-2.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/declare-simd-2.f90
@@ -1,6 +1,6 @@
 ! { dg-do compile }
 
-function f1 (a, b, c, d, e, f)
+function f1 (a, b, c, d, e, f) ! { dg-warning "GCC does not currently support mixed size types for 'simd' functions" }
   integer, value :: a, b, c
   integer :: d, e, f, f1
 !$omp declare simd (f1) uniform(b) linear(c, d) linear(uval(e)) linear(ref(f))
@@ -12,7 +12,7 @@ function f1 (a, b, c, d, e, f)
   f = f + 1
   f1 = a + b + c + d + e + f
 end function f1
-integer function f2 (a, b)
+integer function f2 (a, b) ! { dg-warning "GCC does not currently support mixed size types for 'simd' functions" }
   integer :: a, b
 !$omp declare simd uniform(b) linear(ref(a):b)
   a = a + 1
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr79154-1.f90 b/gcc/testsuite/gfortran.dg/gomp/pr79154-1.f90
index 6c86ded..953dcad 100644
--- a/gcc/testsuite/gfortran.dg/gomp/pr79154-1.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/pr79154-1.f90
@@ -1,7 +1,7 @@
 ! PR fortran/79154
 ! { dg-do compile }
 
-pure real function foo (a, b)
+pure real function foo (a, b)		! { dg-warning "GCC does not currently support mixed size types for 'simd' functions" }
 !$omp declare simd(foo)			! { dg-bogus "may not appear in PURE or ELEMENTAL" }
   real, intent(in) :: a, b
   foo = a + b
@@ -20,7 +20,7 @@ pure real function baz (a, b)
   real, intent(in) :: a, b
   baz = a + b
 end function baz
-elemental real function fooe (a, b)
+elemental real function fooe (a, b)	! { dg-warning "GCC does not currently support mixed size types for 'simd' functions" }
 !$omp declare simd(fooe)		! { dg-bogus "may not appear in PURE or ELEMENTAL" }
   real, intent(in) :: a, b
   fooe = a + b
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr83977.f90 b/gcc/testsuite/gfortran.dg/gomp/pr83977.f90
index b8ad1a7..6dfdbc3 100644
--- a/gcc/testsuite/gfortran.dg/gomp/pr83977.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/pr83977.f90
@@ -1,7 +1,7 @@
 ! PR middle-end/83977
 ! { dg-do compile }
 
-integer function foo (a, b)
+integer function foo (a, b) ! { dg-warning "GCC does not currently support mixed size types for 'simd' functions" }
    integer :: a, b
 !$omp declare simd uniform(b) linear(ref(a):b)
    a = a + 1
Richard Sandiford Jan. 17, 2019, 9:10 a.m. UTC | #15
Steve Ellcey <sellcey@marvell.com> writes:
> +/* Return true for types that could be supported as SIMD return or
> +   argument types.  */
> +
> +static bool supported_simd_type (tree t)

Missing line break after "static bool".

> +{
> +  if (SCALAR_FLOAT_TYPE_P (t) || INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
> +    {
> +      HOST_WIDE_INT s = tree_to_shwi (TYPE_SIZE_UNIT (t));
> +      return s == 1 || s == 2 || s == 4 || s == 8;
> +    }
> +  return false;
> +}
> +
> +/* Return true for types that currently are supported as SIMD return
> +   or argument types.  */
> +
> +static bool currently_supported_simd_type (tree t, tree b)

Same here.

> +{
> +  if (COMPLEX_FLOAT_TYPE_P (t))
> +    return false;
> +
> +  if (TYPE_SIZE (t) != TYPE_SIZE (b))
> +    return false;
> +
> +  return supported_simd_type (t);
> +}
> +
> +/* Implement TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN.  */
> +
> +static int
> +aarch64_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
> +					struct cgraph_simd_clone *clonei,
> +					tree base_type, int num)
> +{
> +  tree t, ret_type, arg_type;
> +  unsigned int elt_bits, vec_bits, count;
> +
> +  if (!TARGET_SIMD)
> +    return 0;
> +
> +  if (clonei->simdlen
> +      && (clonei->simdlen < 2
> +	  || clonei->simdlen > 1024
> +	  || (clonei->simdlen & (clonei->simdlen - 1)) != 0))
> +    {
> +      warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
> +		  "unsupported simdlen %d", clonei->simdlen);
> +      return 0;
> +    }
> +
> +  ret_type = TREE_TYPE (TREE_TYPE (node->decl));
> +  if (TREE_CODE (ret_type) != VOID_TYPE
> +      && !currently_supported_simd_type (ret_type, base_type))
> +    {
> +      if (TYPE_SIZE (ret_type) != TYPE_SIZE (base_type))
> +	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
> +		    "GCC does not currently support mixed size types "
> +		    "for %<simd%> functions");
> +      else if (supported_simd_type (ret_type))
> +	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
> +		    "GCC does not currently support return type %qT "
> +		    "for %<simd%> functions", ret_type);
> +      else
> +	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
> +		    "unsupported return type %qT for %<simd%> functions",
> +		    ret_type);
> +      return 0;
> +    }
> +
> +  for (t = DECL_ARGUMENTS (node->decl); t; t = DECL_CHAIN (t))
> +    {
> +      arg_type = TREE_TYPE (t);
> +
> +      if (!currently_supported_simd_type (arg_type, base_type))
> +	{
> +	  if (TYPE_SIZE (arg_type) != TYPE_SIZE (base_type))
> +	    warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
> +			"GCC does not currently support mixed size types "
> +			"for %<simd%> functions");
> +	  else
> +	    warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
> +			"GCC does not currently support argument type %qT "
> +			"for %<simd%> functions", arg_type);
> +	  return 0;
> +	}
> +    }
> +
> +  clonei->vecsize_mangle = 'n';
> +  clonei->mask_mode = VOIDmode;
> +  elt_bits = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type));
> +  if (clonei->simdlen == 0)
> +    {
> +      count = 2;
> +      vec_bits = (num == 0 ? 64 : 128);
> +      clonei->simdlen = vec_bits / elt_bits;
> +    }
> +  else
> +    {
> +      count = 1;
> +      vec_bits = clonei->simdlen * elt_bits;
> +      if (vec_bits != 64 && vec_bits != 128)
> +        {
> +	  warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
> +		      "GCC does not currently support simdlen %d for type %qT",
> +		      clonei->simdlen, base_type);
> +          return 0;

The return should use tab indentation.

OK otherwise, thanks.

Richard
Steve Ellcey Jan. 17, 2019, 7:10 p.m. UTC | #16
On Thu, 2019-01-17 at 09:10 +0000, Richard Sandiford wrote:
> 
> > +static bool supported_simd_type (tree t)
> 
> Missing line break after "static bool".

Fixed.

> > +static bool currently_supported_simd_type (tree t, tree b)
> 
> Same here.

Fixed.

> > +          return 0;
> 
> The return should use tab indentation.

Fixed.
> 
> OK otherwise, thanks.
> 
> Richard

Thanks for the reviews Richard, I made those changes and checked in the
patch.  That is the last of the Aarch64 SIMD / Vector ABI patches I
have so everything should be checked in and working now.

Steve Ellcey
sellcey@marvell.com
Christophe Lyon Jan. 18, 2019, 2:35 p.m. UTC | #17
On Thu, 17 Jan 2019 at 20:11, Steve Ellcey <sellcey@marvell.com> wrote:
>
> On Thu, 2019-01-17 at 09:10 +0000, Richard Sandiford wrote:
> >
> > > +static bool supported_simd_type (tree t)
> >
> > Missing line break after "static bool".
>
> Fixed.
>
> > > +static bool currently_supported_simd_type (tree t, tree b)
> >
> > Same here.
>
> Fixed.
>
> > > +          return 0;
> >
> > The return should use tab indentation.
>
> Fixed.
> >
> > OK otherwise, thanks.
> >
> > Richard
>
> Thanks for the reviews Richard, I made those changes and checked in the
> patch.  That is the last of the Aarch64 SIMD / Vector ABI patches I
> have so everything should be checked in and working now.
>

Hi Steve,

I've noticed that
FAIL: g++.dg/vect/simd-clone-7.cc  -std=c++14  (test for warnings, line 7)
(and for c++17 and c++98)
when forcing -mabi=ilp32.

I suspect you want to skip the test in this case?

Christophe

> Steve Ellcey
> sellcey@marvell.com
Steve Ellcey Jan. 18, 2019, 5:57 p.m. UTC | #18
On Fri, 2019-01-18 at 15:35 +0100, Christophe Lyon wrote:
> 
> Hi Steve,
> 
> I've noticed that
> FAIL: g++.dg/vect/simd-clone-7.cc  -std=c++14  (test for warnings,
> line 7)
> (and for c++17 and c++98)
> when forcing -mabi=ilp32.
> 
> I suspect you want to skip the test in this case?
> 
> Christophe

Actually, I think we can compile that test, it just would not generate
a warning in ILP32 mode because int, floats and pointers would now all
be the same size.  So I think the fix is:


% git diff simd-clone-7.cc
diff --git a/gcc/testsuite/g++.dg/vect/simd-clone-7.cc b/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
index c2a63cd5f8e..3617f0ab6a7 100644
--- a/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
+++ b/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
@@ -8,4 +8,4 @@ bar (float x, float *y, int)
 {
   return y[0] + y[1] * x;
 }
-// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-4 }
+// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target { { aarch64-*-* } && lp64 } } .-4 }


I haven't tested this, I don't have an ILP32 build sitting around right
now.  Does it work for you?  I can build a toolchain, test it, and
submit a patch if you want.


Steve Ellcey
sellcey@marvell.com
Tamar Christina Jan. 21, 2019, 4:08 p.m. UTC | #19
Hi All,

The simd-clone-7.cc tests seem to fail on big-endian with

testsuite/g++.dg/vect/simd-clone-7.cc:7:1: warning: GCC does not currently support mixed size types for 'simd' functions

The test probably miss an effective target check?

Cheers,
Tamar


> -----Original Message-----
> From: gcc-patches-owner@gcc.gnu.org <gcc-patches-owner@gcc.gnu.org>
> On Behalf Of Steve Ellcey
> Sent: Friday, January 18, 2019 17:58
> To: christophe.lyon@linaro.org
> Cc: gcc-patches@gcc.gnu.org; Richard Sandiford
> <Richard.Sandiford@arm.com>
> Subject: Re: [EXT] Re: [Patch 2/4][Aarch64] v2: Implement Aarch64 SIMD ABI
> 
> On Fri, 2019-01-18 at 15:35 +0100, Christophe Lyon wrote:
> >
> > Hi Steve,
> >
> > I've noticed that
> > FAIL: g++.dg/vect/simd-clone-7.cc  -std=c++14  (test for warnings,
> > line 7) (and for c++17 and c++98) when forcing -mabi=ilp32.
> >
> > I suspect you want to skip the test in this case?
> >
> > Christophe
> 
> Actually, I think we can compile that test, it just would not generate a
> warning in ILP32 mode because int, floats and pointers would now all be the
> same size.  So I think the fix is:
> 
> 
> % git diff simd-clone-7.cc
> diff --git a/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
> b/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
> index c2a63cd5f8e..3617f0ab6a7 100644
> --- a/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
> +++ b/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
> @@ -8,4 +8,4 @@ bar (float x, float *y, int)  {
>    return y[0] + y[1] * x;
>  }
> -// { dg-warning "GCC does not currently support mixed size types for 'simd'
> functions" "" { target aarch64-*-* } .-4 }
> +// { dg-warning "GCC does not currently support mixed size types for
> +'simd' functions" "" { target { { aarch64-*-* } && lp64 } } .-4 }
> 
> 
> I haven't tested this, I don't have an ILP32 build sitting around right now.
> Does it work for you?  I can build a toolchain, test it, and submit a patch if you
> want.
> 
> 
> Steve Ellcey
> sellcey@marvell.com
Richard Sandiford Jan. 21, 2019, 4:41 p.m. UTC | #20
Tamar Christina <Tamar.Christina@arm.com> writes:
> Hi All,
>
> The simd-clone-7.cc tests seem to fail on big-endian with
>
> testsuite/g++.dg/vect/simd-clone-7.cc:7:1: warning: GCC does not currently support mixed size types for 'simd' functions
>
> The test probably miss an effective target check?

The current condition is:

// { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64-*-* } .-4 }

That would need to be aarch64*-*-* to include big-endian.  Fixing that
here and in the other tests is OK under the obvious rule.

Adding && lp64 (as per Steve's patch below) is OK too if it works.

Thanks,
Richard

>> -----Original Message-----
>> From: gcc-patches-owner@gcc.gnu.org <gcc-patches-owner@gcc.gnu.org>
>> On Behalf Of Steve Ellcey
>> Sent: Friday, January 18, 2019 17:58
>> To: christophe.lyon@linaro.org
>> Cc: gcc-patches@gcc.gnu.org; Richard Sandiford
>> <Richard.Sandiford@arm.com>
>> Subject: Re: [EXT] Re: [Patch 2/4][Aarch64] v2: Implement Aarch64 SIMD ABI
>> 
>> On Fri, 2019-01-18 at 15:35 +0100, Christophe Lyon wrote:
>> >
>> > Hi Steve,
>> >
>> > I've noticed that
>> > FAIL: g++.dg/vect/simd-clone-7.cc  -std=c++14  (test for warnings,
>> > line 7) (and for c++17 and c++98) when forcing -mabi=ilp32.
>> >
>> > I suspect you want to skip the test in this case?
>> >
>> > Christophe
>> 
>> Actually, I think we can compile that test, it just would not generate a
>> warning in ILP32 mode because int, floats and pointers would now all be the
>> same size.  So I think the fix is:
>> 
>> 
>> % git diff simd-clone-7.cc
>> diff --git a/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
>> b/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
>> index c2a63cd5f8e..3617f0ab6a7 100644
>> --- a/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
>> +++ b/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
>> @@ -8,4 +8,4 @@ bar (float x, float *y, int)  {
>>    return y[0] + y[1] * x;
>>  }
>> -// { dg-warning "GCC does not currently support mixed size types for 'simd'
>> functions" "" { target aarch64-*-* } .-4 }
>> +// { dg-warning "GCC does not currently support mixed size types for
>> +'simd' functions" "" { target { { aarch64-*-* } && lp64 } } .-4 }
>> 
>> 
>> I haven't tested this, I don't have an ILP32 build sitting around right now.
>> Does it work for you?  I can build a toolchain, test it, and submit a patch if you
>> want.
>> 
>> 
>> Steve Ellcey
>> sellcey@marvell.com
Tamar Christina Jan. 21, 2019, 6 p.m. UTC | #21
Hi Richard,

> -----Original Message-----
> From: Richard Sandiford <richard.sandiford@arm.com>
> Sent: Monday, January 21, 2019 16:42
> To: Tamar Christina <Tamar.Christina@arm.com>
> Cc: Steve Ellcey <sellcey@marvell.com>; christophe.lyon@linaro.org; gcc-
> patches@gcc.gnu.org; nd <nd@arm.com>
> Subject: Re: [EXT] Re: [Patch 2/4][Aarch64] v2: Implement Aarch64 SIMD ABI
> 
> Tamar Christina <Tamar.Christina@arm.com> writes:
> > Hi All,
> >
> > The simd-clone-7.cc tests seem to fail on big-endian with
> >
> > testsuite/g++.dg/vect/simd-clone-7.cc:7:1: warning: GCC does not
> > currently support mixed size types for 'simd' functions
> >
> > The test probably miss an effective target check?
> 
> The current condition is:
> 
> // { dg-warning "GCC does not currently support mixed size types for 'simd'
> functions" "" { target aarch64-*-* } .-4 }
> 
> That would need to be aarch64*-*-* to include big-endian.  Fixing that here
> and in the other tests is OK under the obvious rule.

Ah, true, I didn't look at the testcase. I tested the ILP32 case and committed the fix for both.

Thanks,
Tamar

> 
> Adding && lp64 (as per Steve's patch below) is OK too if it works.
> 
> Thanks,
> Richard
> 
> >> -----Original Message-----
> >> From: gcc-patches-owner@gcc.gnu.org <gcc-patches-owner@gcc.gnu.org>
> >> On Behalf Of Steve Ellcey
> >> Sent: Friday, January 18, 2019 17:58
> >> To: christophe.lyon@linaro.org
> >> Cc: gcc-patches@gcc.gnu.org; Richard Sandiford
> >> <Richard.Sandiford@arm.com>
> >> Subject: Re: [EXT] Re: [Patch 2/4][Aarch64] v2: Implement Aarch64
> >> SIMD ABI
> >>
> >> On Fri, 2019-01-18 at 15:35 +0100, Christophe Lyon wrote:
> >> >
> >> > Hi Steve,
> >> >
> >> > I've noticed that
> >> > FAIL: g++.dg/vect/simd-clone-7.cc  -std=c++14  (test for warnings,
> >> > line 7) (and for c++17 and c++98) when forcing -mabi=ilp32.
> >> >
> >> > I suspect you want to skip the test in this case?
> >> >
> >> > Christophe
> >>
> >> Actually, I think we can compile that test, it just would not
> >> generate a warning in ILP32 mode because int, floats and pointers
> >> would now all be the same size.  So I think the fix is:
> >>
> >>
> >> % git diff simd-clone-7.cc
> >> diff --git a/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
> >> b/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
> >> index c2a63cd5f8e..3617f0ab6a7 100644
> >> --- a/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
> >> +++ b/gcc/testsuite/g++.dg/vect/simd-clone-7.cc
> >> @@ -8,4 +8,4 @@ bar (float x, float *y, int)  {
> >>    return y[0] + y[1] * x;
> >>  }
> >> -// { dg-warning "GCC does not currently support mixed size types for
> 'simd'
> >> functions" "" { target aarch64-*-* } .-4 }
> >> +// { dg-warning "GCC does not currently support mixed size types for
> >> +'simd' functions" "" { target { { aarch64-*-* } && lp64 } } .-4 }
> >>
> >>
> >> I haven't tested this, I don't have an ILP32 build sitting around right now.
> >> Does it work for you?  I can build a toolchain, test it, and submit a
> >> patch if you want.
> >>
> >>
> >> Steve Ellcey
> >> sellcey@marvell.com
Steve Ellcey Jan. 22, 2019, 10:34 p.m. UTC | #22
On Mon, 2019-01-21 at 18:00 +0000, Tamar Christina wrote:
> 
> > That would need to be aarch64*-*-* to include big-endian.  Fixing that here
> > and in the other tests is OK under the obvious rule.
> 
> Ah, true, I didn't look at the testcase. I tested the ILP32 case and
> committed the fix for both.
> 
> Thanks,
> Tamar
> 
> > 
> > Adding && lp64 (as per Steve's patch below) is OK too if it works.
> > 
> > Thanks,
> > Richard

Thanks for fixing this test Tamar.  I am going to change the others to
use 'aarch64*-*-*' instead of 'aarch64-*-*' since that seems to be the
standard method (though I see a few other tests that are not using 
aarch64 instead of aarch64*).

I guess that while you are testing big-endian the target triplet you
are using is still aarch64-*-* and not aarch64be-*-*?  Otherwise I
would have expected you to have more failures.

Steve Ellcey
sellcey@marvell.com
Tamar Christina Jan. 22, 2019, 11:05 p.m. UTC | #23
Hi Steve,

No we are using aarch64_be-*-* but this is the only one that popped up as a failure which is why I didn't change the others.
But now I'm wondering why... I'll check the log file manually tomorrow to be sure.

Cheers,
Tamar
Tamar Christina Jan. 23, 2019, 12:50 p.m. UTC | #24
Hi Steve,

> 
> Hi Steve,
> 
> No we are using aarch64_be-*-* but this is the only one that popped up as a
> failure which is why I didn't change the others.
> But now I'm wondering why... I'll check the log file manually tomorrow to be
> sure.

I've checked and the reason this didn't show up is because we don't run AArch64 big-endian cross linux tests by default and the baremetal builds don't support gomp.

I'm happy to update them for you if you want though.

Cheers,
Tamar

> 
> Cheers,
> Tamar
> ________________________________________
> From: Steve Ellcey <sellcey@marvell.com>
> Sent: Tuesday, January 22, 2019 10:34 PM
> To: Tamar Christina; Richard Sandiford
> Cc: gcc-patches@gcc.gnu.org; nd; christophe.lyon@linaro.org
> Subject: Re: [EXT] Re: [Patch 2/4][Aarch64] v2: Implement Aarch64 SIMD ABI
> 
> On Mon, 2019-01-21 at 18:00 +0000, Tamar Christina wrote:
> >
> > > That would need to be aarch64*-*-* to include big-endian.  Fixing
> > > that here and in the other tests is OK under the obvious rule.
> >
> > Ah, true, I didn't look at the testcase. I tested the ILP32 case and
> > committed the fix for both.
> >
> > Thanks,
> > Tamar
> >
> > >
> > > Adding && lp64 (as per Steve's patch below) is OK too if it works.
> > >
> > > Thanks,
> > > Richard
> 
> Thanks for fixing this test Tamar.  I am going to change the others to use
> 'aarch64*-*-*' instead of 'aarch64-*-*' since that seems to be the standard
> method (though I see a few other tests that are not using
> aarch64 instead of aarch64*).
> 
> I guess that while you are testing big-endian the target triplet you are using is
> still aarch64-*-* and not aarch64be-*-*?  Otherwise I would have expected
> you to have more failures.
> 
> Steve Ellcey
> sellcey@marvell.com
Steve Ellcey Jan. 23, 2019, 4:07 p.m. UTC | #25
On Wed, 2019-01-23 at 12:50 +0000, Tamar Christina wrote:
> Hi Steve,
> 
> > 
> > Hi Steve,
> > 
> > No we are using aarch64_be-*-* but this is the only one that popped
> > up as a
> > failure which is why I didn't change the others.
> > But now I'm wondering why... I'll check the log file manually
> > tomorrow to be
> > sure.
> 
> I've checked and the reason this didn't show up is because we don't
> run AArch64 big-endian cross linux tests by default and the baremetal
> builds don't support gomp.
> 
> I'm happy to update them for you if you want though.

I already updated them.  Thanks for checking on the failures.

Steve Ellcey
sellcey@cavium.com
diff mbox series

Patch

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index ea7e79f..40f18ef 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -40,6 +40,7 @@ 
 #include "regs.h"
 #include "emit-rtl.h"
 #include "recog.h"
+#include "cgraph.h"
 #include "diagnostic.h"
 #include "insn-attr.h"
 #include "alias.h"
@@ -17936,6 +17937,135 @@  aarch64_estimated_poly_value (poly_int64 val)
   return val.coeffs[0] + val.coeffs[1] * over_128 / 128;
 }
 
+/* Set CLONEI->vecsize_mangle, CLONEI->mask_mode, CLONEI->vecsize_int,
+   CLONEI->vecsize_float and if CLONEI->simdlen is 0, also
+   CLONEI->simdlen.  Return 0 if SIMD clones shouldn't be emitted,
+   or number of vecsize_mangle variants that should be emitted.  */
+
+static int
+aarch64_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
+					struct cgraph_simd_clone *clonei,
+					tree base_type,
+					int num ATTRIBUTE_UNUSED)
+{
+  int ret = 0;
+
+  if (clonei->simdlen
+      && (clonei->simdlen < 2
+	  || clonei->simdlen > 1024
+	  || (clonei->simdlen & (clonei->simdlen - 1)) != 0))
+    {
+      warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		  "unsupported simdlen %d", clonei->simdlen);
+      return 0;
+    }
+
+  tree ret_type = TREE_TYPE (TREE_TYPE (node->decl));
+  if (TREE_CODE (ret_type) != VOID_TYPE)
+    switch (TYPE_MODE (ret_type))
+      {
+      case E_QImode:
+      case E_HImode:
+      case E_SImode:
+      case E_DImode:
+      case E_SFmode:
+      case E_DFmode:
+      /* case E_SCmode: */
+      /* case E_DCmode: */
+	break;
+      default:
+	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		    "unsupported return type %qT for simd\n", ret_type);
+	return 0;
+      }
+
+  tree t;
+  for (t = DECL_ARGUMENTS (node->decl); t; t = DECL_CHAIN (t))
+    /* FIXME: Shouldn't we allow such arguments if they are uniform?  */
+    switch (TYPE_MODE (TREE_TYPE (t)))
+      {
+      case E_QImode:
+      case E_HImode:
+      case E_SImode:
+      case E_DImode:
+      case E_SFmode:
+      case E_DFmode:
+      /* case E_SCmode: */
+      /* case E_DCmode: */
+	break;
+      default:
+	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		    "unsupported argument type %qT for simd\n", TREE_TYPE (t));
+	return 0;
+      }
+
+  if (TARGET_SIMD)
+    {
+    clonei->vecsize_mangle = 'n';
+    clonei->mask_mode = VOIDmode;
+    clonei->vecsize_int = 128;
+    clonei->vecsize_float = 128;
+
+    if (clonei->simdlen == 0)
+      {
+      if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
+	clonei->simdlen = clonei->vecsize_int;
+      else
+	clonei->simdlen = clonei->vecsize_float;
+      clonei->simdlen /= GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type));
+      }
+    else if (clonei->simdlen > 16)
+      {
+      /* If it is possible for given SIMDLEN to pass CTYPE value in
+	 registers (v0-v7) accept that SIMDLEN, otherwise warn and don't
+	 emit corresponding clone.  */
+      int cnt = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type)) * clonei->simdlen;
+      if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
+	cnt /= clonei->vecsize_int;
+      else
+	cnt /= clonei->vecsize_float;
+      if (cnt > 8)
+	{
+	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		    "unsupported simdlen %d", clonei->simdlen);
+	return 0;
+	}
+      }
+      ret = 1;
+    }
+  return ret;
+}
+
+/* Add aarch64_vector_pcs target attribute to SIMD clones so they use the
+   correct ABI.  */
+
+static void
+aarch64_simd_clone_adjust (struct cgraph_node *node, bool defn ATTRIBUTE_UNUSED)
+{
+  tree t = TREE_TYPE (node->decl);
+  TYPE_ATTRIBUTES (t) =
+    make_attribute ("aarch64_vector_pcs", "default", TYPE_ATTRIBUTES (t));
+}
+
+/* If SIMD clone NODE can't be used in a vectorized loop
+   in current function, return -1, otherwise return a badness of using it
+   (0 if it is most desirable from vecsize_mangle point of view, 1
+   slightly less desirable, etc.).  */
+
+static int
+aarch64_simd_clone_usable (struct cgraph_node *node)
+{
+  switch (node->simdclone->vecsize_mangle)
+    {
+    case 'n':
+      if (!TARGET_SIMD)
+	return -1;
+      return 0;
+    default:
+      gcc_unreachable ();
+    }
+}
+
 /* Target-specific selftests.  */
 
 #if CHECKING_P
@@ -18418,6 +18548,16 @@  aarch64_libgcc_floating_mode_supported_p
 #undef TARGET_ESTIMATED_POLY_VALUE
 #define TARGET_ESTIMATED_POLY_VALUE aarch64_estimated_poly_value
 
+#undef TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN
+#define TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN \
+  aarch64_simd_clone_compute_vecsize_and_simdlen
+
+#undef TARGET_SIMD_CLONE_ADJUST
+#define TARGET_SIMD_CLONE_ADJUST aarch64_simd_clone_adjust
+
+#undef TARGET_SIMD_CLONE_USABLE
+#define TARGET_SIMD_CLONE_USABLE aarch64_simd_clone_usable
+
 #if CHECKING_P
 #undef TARGET_RUN_TARGET_SELFTESTS
 #define TARGET_RUN_TARGET_SELFTESTS selftest::aarch64_run_selftests
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index e86c39e..d9ad6e7 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -50011,9 +50011,14 @@  ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
 /* Add target attribute to SIMD clone NODE if needed.  */
 
 static void
-ix86_simd_clone_adjust (struct cgraph_node *node)
+ix86_simd_clone_adjust (struct cgraph_node *node, bool defn)
 {
   const char *str = NULL;
+
+  /* Attributes need to be adjusted for definitions, not declarations.  */
+  if (!defn)
+    return;
+
   gcc_assert (node->decl == cfun->decl);
   switch (node->simdclone->vecsize_mangle)
     {
diff --git a/gcc/omp-simd-clone.c b/gcc/omp-simd-clone.c
index ba03bd5..09d7f86 100644
--- a/gcc/omp-simd-clone.c
+++ b/gcc/omp-simd-clone.c
@@ -1112,7 +1112,7 @@  simd_clone_adjust (struct cgraph_node *node)
 {
   push_cfun (DECL_STRUCT_FUNCTION (node->decl));
 
-  targetm.simd_clone.adjust (node);
+  targetm.simd_clone.adjust (node, true);
 
   tree retval = simd_clone_adjust_return_type (node);
   ipa_parm_adjustment_vec adjustments
@@ -1685,6 +1685,7 @@  expand_simd_clones (struct cgraph_node *node)
 	    simd_clone_adjust (n);
 	  else
 	    {
+	      targetm.simd_clone.adjust (n, false);
 	      simd_clone_adjust_return_type (n);
 	      simd_clone_adjust_argument_types (n);
 	    }
diff --git a/gcc/target.def b/gcc/target.def
index 96f37e0..ffc3787 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1632,8 +1632,10 @@  int, (struct cgraph_node *, struct cgraph_simd_clone *, tree, int), NULL)
 DEFHOOK
 (adjust,
 "This hook should add implicit @code{attribute(target(\"...\"))} attribute\n\
-to SIMD clone @var{node} if needed.",
-void, (struct cgraph_node *), NULL)
+to SIMD clone @var{node} if needed.  If the @var{defn} bool argument is true\n\
+then this function is being called for a function definition, if false it is\n\
+a function declaration.",
+void, (struct cgraph_node *, bool), NULL)
 
 DEFHOOK
 (usable,