diff mbox

[#2] , Fix _Complex when there are multiple FP types the same size

Message ID 20160429205127.GA19596@ibm-tiger.the-meissners.org
State New
Headers show

Commit Message

Michael Meissner April 29, 2016, 8:51 p.m. UTC
Here is the updated patch.

I eliminated the blank lines in the ChangeLog files.

I eliminated ALTIVEC_COMPLEX, and folded the result into
ALTIVEC_ARG_MAX_RETURN. Note, due to being able to return homogeneous
aggregates, Elf v2 did not need the change, but Elf v1 needs it to return
complex values in V2 and V3 (V3 is volatile).

I eliminated the change for PRINT_OPERAND_PUNCT_VALID_P, which will be part of
another patch to update the min/max support for ISA 3.0.

I combined the tests and PowerPC specific back end changes into a single
attachment. I added a second complex test, to test whether ISA 3.0 will
generate the xsaddqp instruction for complex add instead of call __addkf3.

These patches bootstrap and have no regressions. Are they ok to install into
the tree?

Assuming there is no fallout from other ports with the machine independent
changes, can I install these patches into the GCC 6.2 tree as well?

Attachment gcc-stage7.patch002b is the machine independent changes, and
gcc-stage7.patch002c are the PowerPC specific backend and testsuite changes.

[gcc]
2016-04-29  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* machmode.h (mode_complex): Add support to give the complex mode
	for a given mode.
	(GET_MODE_COMPLEX_MODE): Likewise.
	* stor-layout.c (layout_type): For COMPLEX_TYPE, use the mode
	stored by build_complex_type instead of trying to figure out the
	appropriate mode based on the size.
	* genmodes.c (struct mode_data): Add field for the complex type of
	the given type.
	(blank_mode): Likewise.
	(make_complex_modes): Remember the complex mode created in the
	base type.
	(emit_mode_complex): Write out the mode_complex array to map a
	type mode to the complex version.
	(emit_insn_modes_c): Likewise.
	* tree.c (build_complex_type): Set the complex type to use before
	calling layout_type.
	* config/rs6000/rs6000.c (rs6000_hard_regno_nregs_internal): Add
	support for __float128 complex datatypes.
	(rs6000_hard_regno_mode_ok): Likewise.
	(rs6000_setup_reg_addr_masks): Likewise.
	(rs6000_complex_function_value): Likewise.
	* config/rs6000/rs6000.h (FLOAT128_IEEE_P): Likewise.
	__float128 and __ibm128 complex.
	(FLOAT128_IBM_P): Likewise.
	(ALTIVEC_ARG_MAX_RETURN): Likewise.
	* doc/extend.texi (Additional Floating Types): Document that
	-mfloat128 must be used to enable __float128.  Document complex
	__float128 and __ibm128 support.

[gcc/testsuite]
2016-04-29  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* gcc.target/powerpc/float128-complex-1.c: New tests for complex
	__float128.
	* gcc.target/powerpc/float128-complex-2.c: Likewise.

Comments

Segher Boessenkool April 30, 2016, 4 p.m. UTC | #1
On Fri, Apr 29, 2016 at 04:51:27PM -0400, Michael Meissner wrote:
> 2016-04-29  Michael Meissner  <meissner@linux.vnet.ibm.com>
> 
> 	* config/rs6000/rs6000.c (rs6000_hard_regno_nregs_internal): Add
> 	support for __float128 complex datatypes.
> 	(rs6000_hard_regno_mode_ok): Likewise.
> 	(rs6000_setup_reg_addr_masks): Likewise.
> 	(rs6000_complex_function_value): Likewise.
> 	* config/rs6000/rs6000.h (FLOAT128_IEEE_P): Likewise.
> 	__float128 and __ibm128 complex.
> 	(FLOAT128_IBM_P): Likewise.
> 	(ALTIVEC_ARG_MAX_RETURN): Likewise.
> 	* doc/extend.texi (Additional Floating Types): Document that
> 	-mfloat128 must be used to enable __float128.  Document complex
> 	__float128 and __ibm128 support.
> 
> [gcc/testsuite]
> 2016-04-29  Michael Meissner  <meissner@linux.vnet.ibm.com>
> 
> 	* gcc.target/powerpc/float128-complex-1.c: New tests for complex
> 	__float128.
> 	* gcc.target/powerpc/float128-complex-2.c: Likewise.

The powerpc parts are okay for trunk.  Thank you!

A few trivialities you can maybe fix when you commit this:

> @@ -2700,7 +2703,16 @@ rs6000_setup_reg_addr_masks (void)
>    for (m = 0; m < NUM_MACHINE_MODES; ++m)
>      {
>        machine_mode m2 = (machine_mode)m;

There should be a space after the cast.  Pre-existing, I know.

> @@ -19190,6 +19223,25 @@ rs6000_preferred_reload_class (rtx x, en
>        return NO_REGS;
>      }
>  
> +  /* If we haven't picked a register class, and the type is a vector or
> +     floating point type, prefer to use the VSX, FPR, or Altivec register
> +     classes.  */
> +  if (rclass == NO_REGS)
> +    {
> +      if (TARGET_VSX && VECTOR_MEM_VSX_OR_P8_VECTOR_P (mode))
> +	return VSX_REGS;
> +
> +      if (TARGET_ALTIVEC && VECTOR_MEM_ALTIVEC_P (mode))
> +	return ALTIVEC_REGS;
> +
> +      if (DECIMAL_FLOAT_MODE_P (mode))
> +	return (TARGET_DFP) ? FLOAT_REGS : NO_REGS;

Superfluous parens.

> @@ -33964,8 +34016,14 @@ rs6000_complex_function_value (machine_m
>    machine_mode inner = GET_MODE_INNER (mode);
>    unsigned int inner_bytes = GET_MODE_UNIT_SIZE (mode);
>  
> -  if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
> +  if (TARGET_FLOAT128
> +      && ((mode == KCmode)

Parens again.


Segher
Bernd Schmidt May 2, 2016, 10:54 a.m. UTC | #2
On 04/30/2016 06:00 PM, Segher Boessenkool wrote:
> On Fri, Apr 29, 2016 at 04:51:27PM -0400, Michael Meissner wrote:
>> 2016-04-29  Michael Meissner  <meissner@linux.vnet.ibm.com>
>>
>> 	* config/rs6000/rs6000.c (rs6000_hard_regno_nregs_internal): Add
>> 	support for __float128 complex datatypes.
>> 	(rs6000_hard_regno_mode_ok): Likewise.
>> 	(rs6000_setup_reg_addr_masks): Likewise.
>> 	(rs6000_complex_function_value): Likewise.
>> 	* config/rs6000/rs6000.h (FLOAT128_IEEE_P): Likewise.
>> 	__float128 and __ibm128 complex.
>> 	(FLOAT128_IBM_P): Likewise.
>> 	(ALTIVEC_ARG_MAX_RETURN): Likewise.
>> 	* doc/extend.texi (Additional Floating Types): Document that
>> 	-mfloat128 must be used to enable __float128.  Document complex
>> 	__float128 and __ibm128 support.
>>
>> [gcc/testsuite]
>> 2016-04-29  Michael Meissner  <meissner@linux.vnet.ibm.com>
>>
>> 	* gcc.target/powerpc/float128-complex-1.c: New tests for complex
>> 	__float128.
>> 	* gcc.target/powerpc/float128-complex-2.c: Likewise.
>
> The powerpc parts are okay for trunk.  Thank you!

Ok for the other parts as well. Although I wonder:

> +      /* build_complex_type has set the expected mode to allow having multiple
> +	 complex types for multiple floating point types that have the same
> +	 size such as the PowerPC with __ibm128 and __float128.  If this was
> +	 not set, figure out the mode manually.  */
> +      if (TYPE_MODE (type) == VOIDmode)
> +	{
> +	  unsigned int precision = TYPE_PRECISION (TREE_TYPE (type));
> +	  enum mode_class mclass = (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE
> +				    ? MODE_COMPLEX_FLOAT : MODE_COMPLEX_INT);
> +	  SET_TYPE_MODE (type, mode_for_size (2 * precision, mclass, 0));
> +	}

What happens if you assert that it isn't VOIDmode?


Bernd
diff mbox

Patch

Index: gcc/machmode.h
===================================================================
--- gcc/machmode.h	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/machmode.h)	(revision 235590)
+++ gcc/machmode.h	(.../gcc/machmode.h)	(working copy)
@@ -269,6 +269,10 @@  extern const unsigned char mode_wider[NU
 extern const unsigned char mode_2xwider[NUM_MACHINE_MODES];
 #define GET_MODE_2XWIDER_MODE(MODE) ((machine_mode) mode_2xwider[MODE])
 
+/* Get the complex mode from the component mode.  */
+extern const unsigned char mode_complex[NUM_MACHINE_MODES];
+#define GET_MODE_COMPLEX_MODE(MODE) ((machine_mode) mode_complex[MODE])
+
 /* Return the mode for data of a given size SIZE and mode class CLASS.
    If LIMIT is nonzero, then don't use modes bigger than MAX_FIXED_MODE_SIZE.
    The value is BLKmode if no other mode is found.  */
Index: gcc/stor-layout.c
===================================================================
--- gcc/stor-layout.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/stor-layout.c)	(revision 235590)
+++ gcc/stor-layout.c	(.../gcc/stor-layout.c)	(working copy)
@@ -2146,11 +2146,19 @@  layout_type (tree type)
 
     case COMPLEX_TYPE:
       TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
-      SET_TYPE_MODE (type,
-		     mode_for_size (2 * TYPE_PRECISION (TREE_TYPE (type)),
-				    (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE
-				     ? MODE_COMPLEX_FLOAT : MODE_COMPLEX_INT),
-				     0));
+
+      /* build_complex_type has set the expected mode to allow having multiple
+	 complex types for multiple floating point types that have the same
+	 size such as the PowerPC with __ibm128 and __float128.  If this was
+	 not set, figure out the mode manually.  */
+      if (TYPE_MODE (type) == VOIDmode)
+	{
+	  unsigned int precision = TYPE_PRECISION (TREE_TYPE (type));
+	  enum mode_class mclass = (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE
+				    ? MODE_COMPLEX_FLOAT : MODE_COMPLEX_INT);
+	  SET_TYPE_MODE (type, mode_for_size (2 * precision, mclass, 0));
+	}
+
       TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
       TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
       break;
Index: gcc/genmodes.c
===================================================================
--- gcc/genmodes.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/genmodes.c)	(revision 235590)
+++ gcc/genmodes.c	(.../gcc/genmodes.c)	(working copy)
@@ -66,6 +66,7 @@  struct mode_data
 				   this mode as a component.  */
   struct mode_data *next_cont;  /* Next mode in that list.  */
 
+  struct mode_data *complex;	/* complex type with mode as component.  */
   const char *file;		/* file and line of definition, */
   unsigned int line;		/* for error reporting */
   unsigned int counter;		/* Rank ordering of modes */
@@ -83,7 +84,7 @@  static struct mode_data *void_mode;
 static const struct mode_data blank_mode = {
   0, "<unknown>", MAX_MODE_CLASS,
   -1U, -1U, -1U, -1U,
-  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
   "<unknown>", 0, 0, 0, 0, false, 0
 };
 
@@ -472,6 +473,7 @@  make_complex_modes (enum mode_class cl,
 
       c = new_mode (cclass, buf, file, line);
       c->component = m;
+      m->complex = c;
     }
 }
 
@@ -1381,6 +1383,22 @@  emit_mode_wider (void)
 }
 
 static void
+emit_mode_complex (void)
+{
+  int c;
+  struct mode_data *m;
+
+  print_decl ("unsigned char", "mode_complex", "NUM_MACHINE_MODES");
+
+  for_all_modes (c, m)
+    tagged_printf ("%smode",
+		   m->complex ? m->complex->name : void_mode->name,
+		   m->name);
+
+  print_closer ();
+}
+
+static void
 emit_mode_mask (void)
 {
   int c;
@@ -1745,6 +1763,7 @@  emit_insn_modes_c (void)
   emit_mode_size ();
   emit_mode_nunits ();
   emit_mode_wider ();
+  emit_mode_complex ();
   emit_mode_mask ();
   emit_mode_inner ();
   emit_mode_unit_size ();
Index: gcc/tree.c
===================================================================
--- gcc/tree.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/tree.c)	(revision 235590)
+++ gcc/tree.c	(.../gcc/tree.c)	(working copy)
@@ -8767,6 +8767,7 @@  build_complex_type (tree component_type)
   t = make_node (COMPLEX_TYPE);
 
   TREE_TYPE (t) = TYPE_MAIN_VARIANT (component_type);
+  SET_TYPE_MODE (t, GET_MODE_COMPLEX_MODE (TYPE_MODE (component_type)));
 
   /* If we already have such a type, use the old one.  */
   hstate.add_object (TYPE_HASH (component_type));