This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[SVE ACLE] Allow overloaded @ md patterns + small fixes


The first patch allows "@foo_<params>" patterns to have the same "@foo_"
even if they have a different number of operands.  There are no current
users of this on trunk, so I won't commit it there until we've had a bit
more time to try it out.

Tested on aarch64-linux-gnu and applied to aarch64/sve-acle-branch.

Richard


[SVE ACLE] Support multiple operand counts for .md @ patterns

This patch extends the support for "@..." pattern names so that
the patterns can have different numbers of operands.  This allows
things like binary and ternary operations to be handled in a
consistent way, a bit like optabs.  The generators assert that
the number of operands passed is correct for the underlying
instruction.

2018-09-25  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* doc/md.texi: Document that @ patterns can have different
	numbers of operands.
	* genemit.c (handle_overloaded_gen): Handle this case.
	* genopinit.c (handle_overloaded_gen): Likewise.


diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 0558cdfc8e6..8fbfe2f9afd 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -10980,4 +10980,13 @@ name and same types of iterator.  For example:
 would produce a single set of functions that handles both
 @code{INTEGER_MODES} and @code{FLOAT_MODES}.
 
+It is also possible for these @samp{@@} patterns to have different
+numbers of operands from each other.  For example, patterns with
+a binary rtl code might take three operands (one output and two inputs)
+while patterns with a ternary rtl code might take four operands (one
+output and three inputs).  This combination would produce separate
+@samp{maybe_gen_@var{name}} and @samp{gen_@var{name}} functions for
+each operand count, but it would still produce a single
+@samp{maybe_code_for_@var{name}} and a single @samp{code_for_@var{name}}.
+
 @end ifset
diff --git a/gcc/genemit.c b/gcc/genemit.c
index 675cf04ff4b..fc662c8ca27 100644
--- a/gcc/genemit.c
+++ b/gcc/genemit.c
@@ -800,42 +800,45 @@ handle_overloaded_code_for (overloaded_name *oname)
 static void
 handle_overloaded_gen (overloaded_name *oname)
 {
+  unsigned HOST_WIDE_INT seen = 0;
   /* All patterns must have the same number of operands.  */
-  pattern_stats stats;
-  get_pattern_stats (&stats, XVEC (oname->first_instance->insn, 1));
   for (overloaded_instance *instance = oname->first_instance->next;
        instance; instance = instance->next)
     {
-      pattern_stats stats2;
-      get_pattern_stats (&stats2, XVEC (instance->insn, 1));
-      if (stats.num_generator_args != stats2.num_generator_args)
-	fatal_at (get_file_location (instance->insn),
-		  "inconsistent number of operands for '%s'; "
-		  "this instance has %d, but previous instances had %d",
-		  oname->name, stats2.num_generator_args,
-		  stats.num_generator_args);
+      pattern_stats stats;
+      get_pattern_stats (&stats, XVEC (instance->insn, 1));
+      unsigned HOST_WIDE_INT mask
+	= HOST_WIDE_INT_1U << stats.num_generator_args;
+      if (seen & mask)
+	continue;
+
+      seen |= mask;
+
+      /* Print the function prototype.  */
+      printf ("\nrtx\nmaybe_gen_%s (", oname->name);
+      print_overload_arguments (oname);
+      for (int i = 0; i < stats.num_generator_args; ++i)
+	printf (", rtx x%d", i);
+      printf (")\n{\n");
+
+      /* Use maybe_code_for_*, instead of duplicating the selection
+	 logic here.  */
+      printf ("  insn_code code = maybe_code_for_%s (", oname->name);
+      for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+	printf ("%sarg%d", i == 0 ? "" : ", ", i);
+      printf (");\n"
+	      "  if (code != CODE_FOR_nothing)\n"
+	      "    {\n"
+	      "      gcc_assert (insn_data[code].n_generator_args == %d);\n"
+	      "      return GEN_FCN (code) (", stats.num_generator_args);
+      for (int i = 0; i < stats.num_generator_args; ++i)
+	printf ("%sx%d", i == 0 ? "" : ", ", i);
+      printf (");\n"
+	      "    }\n"
+	      "  else\n"
+	      "    return NULL_RTX;\n"
+	      "}\n");
     }
-
-  /* Print the function prototype.  */
-  printf ("\nrtx\nmaybe_gen_%s (", oname->name);
-  print_overload_arguments (oname);
-  for (int i = 0; i < stats.num_generator_args; ++i)
-    printf (", rtx x%d", i);
-  printf (")\n{\n");
-
-  /* Use maybe_code_for_*, instead of duplicating the selection logic here.  */
-  printf ("  insn_code code = maybe_code_for_%s (", oname->name);
-  for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
-    printf ("%sarg%d", i == 0 ? "" : ", ", i);
-  printf (");\n"
-	  "  if (code != CODE_FOR_nothing)\n"
-	  "    return GEN_FCN (code) (");
-  for (int i = 0; i < stats.num_generator_args; ++i)
-    printf ("%sx%d", i == 0 ? "" : ", ", i);
-  printf (");\n"
-	  "  else\n"
-	  "    return NULL_RTX;\n"
-	  "}\n");
 }
 
 int
diff --git a/gcc/genopinit.c b/gcc/genopinit.c
index 79835cc5d88..5f11125da85 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -134,31 +134,43 @@ handle_overloaded_code_for (FILE *file, overloaded_name *oname)
 static void
 handle_overloaded_gen (FILE *file, overloaded_name *oname)
 {
-  pattern_stats stats;
-  get_pattern_stats (&stats, XVEC (oname->first_instance->insn, 1));
-
-  fprintf (file, "\nextern rtx maybe_gen_%s (", oname->name);
-  for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
-    fprintf (file, "%s%s", i == 0 ? "" : ", ", oname->arg_types[i]);
-  for (int i = 0; i < stats.num_generator_args; ++i)
-    fprintf (file, ", rtx");
-  fprintf (file, ");\n");
-
-  fprintf (file, "inline rtx\ngen_%s (", oname->name);
-  for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
-    fprintf (file, "%s%s arg%d", i == 0 ? "" : ", ", oname->arg_types[i], i);
-  for (int i = 0; i < stats.num_generator_args; ++i)
-    fprintf (file, ", rtx x%d", i);
-  fprintf (file, ")\n{\n  rtx res = maybe_gen_%s (", oname->name);
-  for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
-    fprintf (file, "%sarg%d", i == 0 ? "" : ", ", i);
-  for (int i = 0; i < stats.num_generator_args; ++i)
-    fprintf (file, ", x%d", i);
-  fprintf (file,
-	   ");\n"
-	   "  gcc_assert (res);\n"
-	   "  return res;\n"
-	   "}\n");
+  unsigned HOST_WIDE_INT seen = 0;
+  for (overloaded_instance *instance = oname->first_instance->next;
+       instance; instance = instance->next)
+    {
+      pattern_stats stats;
+      get_pattern_stats (&stats, XVEC (instance->insn, 1));
+      unsigned HOST_WIDE_INT mask
+	= HOST_WIDE_INT_1U << stats.num_generator_args;
+      if (seen & mask)
+	continue;
+
+      seen |= mask;
+
+      fprintf (file, "\nextern rtx maybe_gen_%s (", oname->name);
+      for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+	fprintf (file, "%s%s", i == 0 ? "" : ", ", oname->arg_types[i]);
+      for (int i = 0; i < stats.num_generator_args; ++i)
+	fprintf (file, ", rtx");
+      fprintf (file, ");\n");
+
+      fprintf (file, "inline rtx\ngen_%s (", oname->name);
+      for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+	fprintf (file, "%s%s arg%d", i == 0 ? "" : ", ",
+		 oname->arg_types[i], i);
+      for (int i = 0; i < stats.num_generator_args; ++i)
+	fprintf (file, ", rtx x%d", i);
+      fprintf (file, ")\n{\n  rtx res = maybe_gen_%s (", oname->name);
+      for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+	fprintf (file, "%sarg%d", i == 0 ? "" : ", ", i);
+      for (int i = 0; i < stats.num_generator_args; ++i)
+	fprintf (file, ", x%d", i);
+      fprintf (file,
+	       ");\n"
+	       "  gcc_assert (res);\n"
+	       "  return res;\n"
+	       "}\n");
+    }
 }
 
 int
[SVE ACLE] Fix typo in __SVUint* names

I'd used __SVUInt* instead...


diff --git a/gcc/config/aarch64/aarch64-sve-builtins.def b/gcc/config/aarch64/aarch64-sve-builtins.def
index d53ae4b10d9..87d9b2125c0 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.def
+++ b/gcc/config/aarch64/aarch64-sve-builtins.def
@@ -37,10 +37,10 @@ DEF_SVE_TYPE (svint8_t, 10, __SVInt8_t, intQI_type_node)
 DEF_SVE_TYPE (svint16_t, 11, __SVInt16_t, intHI_type_node)
 DEF_SVE_TYPE (svint32_t, 11, __SVInt32_t, intSI_type_node)
 DEF_SVE_TYPE (svint64_t, 11, __SVInt64_t, intDI_type_node)
-DEF_SVE_TYPE (svuint8_t, 11, __SVUInt8_t, unsigned_intQI_type_node)
-DEF_SVE_TYPE (svuint16_t, 12, __SVUInt16_t, unsigned_intHI_type_node)
-DEF_SVE_TYPE (svuint32_t, 12, __SVUInt32_t, unsigned_intSI_type_node)
-DEF_SVE_TYPE (svuint64_t, 12, __SVUInt64_t, unsigned_intDI_type_node)
+DEF_SVE_TYPE (svuint8_t, 11, __SVUint8_t, unsigned_intQI_type_node)
+DEF_SVE_TYPE (svuint16_t, 12, __SVUint16_t, unsigned_intHI_type_node)
+DEF_SVE_TYPE (svuint32_t, 12, __SVUint32_t, unsigned_intSI_type_node)
+DEF_SVE_TYPE (svuint64_t, 12, __SVUint64_t, unsigned_intDI_type_node)
 
 DEF_SVE_TYPE_SUFFIX (b, svbool_t, 8)
 DEF_SVE_TYPE_SUFFIX (b8, svbool_t, 8)
diff --git a/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/func_redef_4.c b/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/func_redef_4.c
index 7c32956225f..9591e3d01d6 100644
--- a/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/func_redef_4.c
+++ b/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/func_redef_4.c
@@ -4,6 +4,6 @@
    to be diagnosed.  Any attempt to call the function before including
    arm_sve.h will lead to a link failure.  (Same for taking its address,
    etc.)  */
-extern __SVUInt8_t svadd_u8_x (__SVBool_t, __SVUInt8_t, __SVUInt8_t);
+extern __SVUint8_t svadd_u8_x (__SVBool_t, __SVUint8_t, __SVUint8_t);
 
 #pragma GCC aarch64 "arm_sve.h"
diff --git a/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/func_redef_5.c b/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/func_redef_5.c
index bd1562ead2d..f87201984b8 100644
--- a/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/func_redef_5.c
+++ b/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/func_redef_5.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 
-__SVUInt8_t
-svadd_u8_x (__SVBool_t pg, __SVUInt8_t x, __SVUInt8_t y)
+__SVUint8_t
+svadd_u8_x (__SVBool_t pg, __SVUint8_t x, __SVUint8_t y)
 {
   return x;
 }
diff --git a/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/func_redef_7.c b/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/func_redef_7.c
index 863a5f0f721..1f2e4bf66a3 100644
--- a/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/func_redef_7.c
+++ b/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/func_redef_7.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 
-__SVUInt8_t
-svadd_x (__SVBool_t pg, __SVUInt8_t x, __SVUInt8_t y)
+__SVUint8_t
+svadd_x (__SVBool_t pg, __SVUint8_t x, __SVUint8_t y)
 {
   return x;
 }
diff --git a/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/mangle_1.C b/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/mangle_1.C
index 29284dbabb1..1138f2e22de 100644
--- a/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/mangle_1.C
+++ b/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/mangle_1.C
@@ -20,10 +20,10 @@ void f12(svfloat64_t) {}
 /* { dg-final { scan-assembler "_Z2f311__SVInt16_t:" } } */
 /* { dg-final { scan-assembler "_Z2f411__SVInt32_t:" } } */
 /* { dg-final { scan-assembler "_Z2f511__SVInt64_t:" } } */
-/* { dg-final { scan-assembler "_Z2f611__SVUInt8_t:" } } */
-/* { dg-final { scan-assembler "_Z2f712__SVUInt16_t:" } } */
-/* { dg-final { scan-assembler "_Z2f812__SVUInt32_t:" } } */
-/* { dg-final { scan-assembler "_Z2f912__SVUInt64_t:" } } */
+/* { dg-final { scan-assembler "_Z2f611__SVUint8_t:" } } */
+/* { dg-final { scan-assembler "_Z2f712__SVUint16_t:" } } */
+/* { dg-final { scan-assembler "_Z2f812__SVUint32_t:" } } */
+/* { dg-final { scan-assembler "_Z2f912__SVUint64_t:" } } */
 /* { dg-final { scan-assembler "_Z3f1013__SVFloat16_t:" } } */
 /* { dg-final { scan-assembler "_Z3f1113__SVFloat32_t:" } } */
 /* { dg-final { scan-assembler "_Z3f1213__SVFloat64_t:" } } */
diff --git a/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/mangle_2.C b/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/mangle_2.C
index ac0fef44a50..575b262b282 100644
--- a/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/mangle_2.C
+++ b/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/mangle_2.C
@@ -5,10 +5,10 @@ void f2(__SVInt8_t) {}
 void f3(__SVInt16_t) {}
 void f4(__SVInt32_t) {}
 void f5(__SVInt64_t) {}
-void f6(__SVUInt8_t) {}
-void f7(__SVUInt16_t) {}
-void f8(__SVUInt32_t) {}
-void f9(__SVUInt64_t) {}
+void f6(__SVUint8_t) {}
+void f7(__SVUint16_t) {}
+void f8(__SVUint32_t) {}
+void f9(__SVUint64_t) {}
 void f10(__SVFloat16_t) {}
 void f11(__SVFloat32_t) {}
 void f12(__SVFloat64_t) {}
@@ -18,10 +18,10 @@ void f12(__SVFloat64_t) {}
 /* { dg-final { scan-assembler "_Z2f311__SVInt16_t:" } } */
 /* { dg-final { scan-assembler "_Z2f411__SVInt32_t:" } } */
 /* { dg-final { scan-assembler "_Z2f511__SVInt64_t:" } } */
-/* { dg-final { scan-assembler "_Z2f611__SVUInt8_t:" } } */
-/* { dg-final { scan-assembler "_Z2f712__SVUInt16_t:" } } */
-/* { dg-final { scan-assembler "_Z2f812__SVUInt32_t:" } } */
-/* { dg-final { scan-assembler "_Z2f912__SVUInt64_t:" } } */
+/* { dg-final { scan-assembler "_Z2f611__SVUint8_t:" } } */
+/* { dg-final { scan-assembler "_Z2f712__SVUint16_t:" } } */
+/* { dg-final { scan-assembler "_Z2f812__SVUint32_t:" } } */
+/* { dg-final { scan-assembler "_Z2f912__SVUint64_t:" } } */
 /* { dg-final { scan-assembler "_Z3f1013__SVFloat16_t:" } } */
 /* { dg-final { scan-assembler "_Z3f1113__SVFloat32_t:" } } */
 /* { dg-final { scan-assembler "_Z3f1213__SVFloat64_t:" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve-acle/general-c/func_redef_4.c b/gcc/testsuite/gcc.target/aarch64/sve-acle/general-c/func_redef_4.c
index 7c32956225f..9591e3d01d6 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve-acle/general-c/func_redef_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve-acle/general-c/func_redef_4.c
@@ -4,6 +4,6 @@
    to be diagnosed.  Any attempt to call the function before including
    arm_sve.h will lead to a link failure.  (Same for taking its address,
    etc.)  */
-extern __SVUInt8_t svadd_u8_x (__SVBool_t, __SVUInt8_t, __SVUInt8_t);
+extern __SVUint8_t svadd_u8_x (__SVBool_t, __SVUint8_t, __SVUint8_t);
 
 #pragma GCC aarch64 "arm_sve.h"
diff --git a/gcc/testsuite/gcc.target/aarch64/sve-acle/general-c/func_redef_5.c b/gcc/testsuite/gcc.target/aarch64/sve-acle/general-c/func_redef_5.c
index 894e3a5ae48..85923611d8e 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve-acle/general-c/func_redef_5.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve-acle/general-c/func_redef_5.c
@@ -6,8 +6,8 @@
 
    At the moment this works like other built-ins in the sense that the
    explicit definition "wins".  This isn't supported behavior though.  */
-__SVUInt8_t
-svadd_u8_x (__SVBool_t pg, __SVUInt8_t x, __SVUInt8_t y)
+__SVUint8_t
+svadd_u8_x (__SVBool_t pg, __SVUint8_t x, __SVUint8_t y)
 {
   return x;
 }
[SVE ACLE] Fix optab names for FMAXNM and FMINNM

FMAXNM and FMINNM should map to the fmax and fmin optabs, since they're
the ones that implement IEEE semantics.  The names of the fake FMAX and
FMIN optabs doesn't matter, but we might as well use "_nan" for
consistency with the other AArch64 patterns.

Fixes aarch64/sve/maxmin_strict_1.c.


diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md
index 558c58e42c5..ec5a6901037 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -1800,7 +1800,7 @@
 	   (const_int SVE_ALLOW_NEW_FAULTS)
 	   (match_operand:SVE_F 1 "register_operand")
 	   (match_operand:SVE_F 2 "register_operand")]
-	   SVE_COND_MAXMIN))]
+	  SVE_COND_MAXMIN))]
   "TARGET_SVE"
   {
     operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
@@ -1811,11 +1811,11 @@
 (define_insn "@aarch64_pred_<maxmin_uns><mode>"
   [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
 	(unspec:SVE_F
-	  [(match_operand:<VPRED> 1 "register_operand" "Upl,  Upl")
+	  [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
 	   (match_operand:SI 4 "const_int_operand" "i, i")
 	   (match_operand:SVE_F 2 "register_operand" "%0, w")
 	   (match_operand:SVE_F 3 "register_operand" "w, w")]
-	   SVE_COND_MAXMIN))]
+	  SVE_COND_MAXMIN))]
   "TARGET_SVE"
   "@
    <maxmin_uns_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 781ab434942..4b025ba64cc 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -1631,10 +1631,10 @@
 			      (UNSPEC_FMINV "smin_nan")
 			      (UNSPEC_FMAXNM "fmax")
 			      (UNSPEC_FMINNM "fmin")
-			      (UNSPEC_COND_FMAX "fmax")
-			      (UNSPEC_COND_FMIN "fmin")
-			      (UNSPEC_COND_FMAXNM "fmaxnm")
-			      (UNSPEC_COND_FMINNM "fminnm")])
+			      (UNSPEC_COND_FMAX "fmax_nan")
+			      (UNSPEC_COND_FMIN "fmin_nan")
+			      (UNSPEC_COND_FMAXNM "fmax")
+			      (UNSPEC_COND_FMINNM "fmin")])
 
 (define_int_attr  maxmin_uns_op [(UNSPEC_UMAXV "umax")
 				 (UNSPEC_UMINV "umin")

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]