2014-07-24  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	* config/rs6000/rs6000-protos.h (rs6000_special_adjust_field_align_p):
	Add prototype.
	* config/rs6000/rs6000.c (rs6000_special_adjust_field_align_p): New
	function.  Issue -Wpsabi warning if future GCC releases will use
	different field alignment rules for this type.
	* config/rs6000/sysv4.h (ADJUST_FIELD_ALIGN): Call it.
	* config/rs6000/linux64.h (ADJUST_FIELD_ALIGN): Likewise.
	* config/rs6000/freebsd64.h (ADJUST_FIELD_ALIGN): Likewise.

2014-07-24  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	* config/rs6000/rs6000.c (rs6000_function_arg_boundary): Issue
	-Wpsabi note when encountering a type where future GCC releases
	will apply different alignment requirements.

2014-07-24  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	* config/rs6000/rs6000.c (rs6000_function_arg): If a float argument
	does not fit fully into floating-point registers, and there is still
	space in the register parameter area, issue -Wpsabi note that the ABI
	will change in a future GCC release.

2014-07-24  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	Backport from mainline:
	2014-07-24  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	* gcc.target/powerpc/ppc64-abi-warn-3.c: New test.

	* gcc.c-torture/execute/20050316-1.x: Add -Wno-psabi.
	* gcc.c-torture/execute/20050604-1.x: Add -Wno-psabi.
	* gcc.c-torture/execute/20050316-3.x: New file.  Add -Wno-psabi.
	* gcc.c-torture/execute/pr23135.x: Likewise.

2014-07-24  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	Backport from mainline:
	2014-07-24  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	* gcc.target/powerpc/ppc64-abi-warn-2.c: New test.

2014-07-24  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	Backport from mainline:
	2014-07-24  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	* gcc.target/powerpc/ppc64-abi-warn-1.c: New test.

2014-07-24  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	Backport from mainline:
	2014-07-24  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	* g++.dg/compat/struct-layout-1.exp: Load g++-dg.exp.

Index: gcc/testsuite/gcc.target/powerpc/ppc64-abi-warn-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/ppc64-abi-warn-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/ppc64-abi-warn-1.c	(revision 213025)
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-options "-mabi=elfv2" } */
+
+struct f8
+  {
+    float x[8];
+  };
+
+void test (struct f8 a, struct f8 b) /* { dg-message "note: the ABI of passing homogeneous float aggregates will change" } */
+{
+}
+
Index: gcc/testsuite/gcc.target/powerpc/ppc64-abi-warn-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/ppc64-abi-warn-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/ppc64-abi-warn-2.c	(revision 213025)
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-options "-mno-compat-align-parm" } */
+
+struct test
+  {
+    long a __attribute__((aligned (16)));
+  };
+
+void test (struct test a) /* { dg-message "note: the ABI of passing aggregates with 16-byte alignment will change" } */
+{
+}
+
Index: gcc/testsuite/gcc.target/powerpc/ppc64-abi-warn-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/ppc64-abi-warn-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/ppc64-abi-warn-3.c	(revision 213025)
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec" } */
+
+struct test
+  {
+    int a __attribute__((vector_size (8)));
+  }; /* { dg-message "note: the layout of aggregates containing vectors with 8-byte alignment will change" } */
+
Index: gcc/testsuite/gcc.c-torture/execute/pr23135.x
===================================================================
--- gcc/testsuite/gcc.c-torture/execute/pr23135.x	(revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr23135.x	(revision 213025)
@@ -0,0 +1,2 @@
+set additional_flags "-Wno-psabi"
+return 0
Index: gcc/testsuite/gcc.c-torture/execute/20050604-1.x
===================================================================
--- gcc/testsuite/gcc.c-torture/execute/20050604-1.x	(revision 213021)
+++ gcc/testsuite/gcc.c-torture/execute/20050604-1.x	(revision 213025)
@@ -6,4 +6,5 @@ if { [istarget "i?86-*-*"] || [istarget
 	set additional_flags "-mno-mmx"
 }
 
+set additional_flags "-Wno-psabi"
 return 0
Index: gcc/testsuite/gcc.c-torture/execute/20050316-1.x
===================================================================
--- gcc/testsuite/gcc.c-torture/execute/20050316-1.x	(revision 213021)
+++ gcc/testsuite/gcc.c-torture/execute/20050316-1.x	(revision 213025)
@@ -4,4 +4,5 @@ if { [check_effective_target_int16] } {
 	return 1
 }
 
+set additional_flags "-Wno-psabi"
 return 0;
Index: gcc/testsuite/gcc.c-torture/execute/20050316-3.x
===================================================================
--- gcc/testsuite/gcc.c-torture/execute/20050316-3.x	(revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/20050316-3.x	(revision 213025)
@@ -0,0 +1,2 @@
+set additional_flags "-Wno-psabi"
+return 0
Index: gcc/testsuite/g++.dg/compat/struct-layout-1.exp
===================================================================
--- gcc/testsuite/g++.dg/compat/struct-layout-1.exp	(revision 213021)
+++ gcc/testsuite/g++.dg/compat/struct-layout-1.exp	(revision 213025)
@@ -89,6 +89,9 @@ proc compat-use-tst-compiler { } {
 # This must be done after the compat-use-*-compiler definitions.
 load_lib compat.exp
 
+# Provide the g++-dg-prune routine (gcc-dp.exp is loaded by compat.exp)
+load_lib g++-dg.exp
+
 g++_init
 
 # Save variables for the C++ compiler under test, which each test will
Index: gcc/config/rs6000/freebsd64.h
===================================================================
--- gcc/config/rs6000/freebsd64.h	(revision 213021)
+++ gcc/config/rs6000/freebsd64.h	(revision 213025)
@@ -367,7 +367,7 @@ extern int dot_symbols;
 /* PowerPC64 Linux word-aligns FP doubles when -malign-power is given.  */
 #undef  ADJUST_FIELD_ALIGN
 #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
-  ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE)     \
+  (rs6000_special_adjust_field_align_p ((FIELD), (COMPUTED))		\
    ? 128                                                                \
    : (TARGET_64BIT                                                      \
       && TARGET_ALIGN_NATURAL == 0                                      \
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
--- gcc/config/rs6000/rs6000-protos.h	(revision 213021)
+++ gcc/config/rs6000/rs6000-protos.h	(revision 213025)
@@ -153,6 +153,7 @@ extern void rs6000_split_logical (rtx []
 
 #ifdef TREE_CODE
 extern unsigned int rs6000_data_alignment (tree, unsigned int, enum data_align);
+extern bool rs6000_special_adjust_field_align_p (tree, unsigned int);
 extern unsigned int rs6000_special_round_type_align (tree, unsigned int,
 						     unsigned int);
 extern unsigned int darwin_rs6000_special_round_type_align (tree, unsigned int,
Index: gcc/config/rs6000/linux64.h
===================================================================
--- gcc/config/rs6000/linux64.h	(revision 213021)
+++ gcc/config/rs6000/linux64.h	(revision 213025)
@@ -246,7 +246,7 @@ extern int dot_symbols;
 /* PowerPC64 Linux word-aligns FP doubles when -malign-power is given.  */
 #undef  ADJUST_FIELD_ALIGN
 #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
-  ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE)	\
+  (rs6000_special_adjust_field_align_p ((FIELD), (COMPUTED))		\
    ? 128								\
    : (TARGET_64BIT							\
       && TARGET_ALIGN_NATURAL == 0					\
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 213021)
+++ gcc/config/rs6000/rs6000.c	(revision 213025)
@@ -5862,6 +5862,34 @@ rs6000_data_alignment (tree type, unsign
   return align;
 }
 
+/* Previous GCC releases forced all vector types to have 16-byte alignment.  */
+
+bool
+rs6000_special_adjust_field_align_p (tree field, unsigned int computed)
+{
+  if (TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (field)) == VECTOR_TYPE)
+    {
+      if (computed != 128)
+	{
+	  static bool warned;
+	  if (!warned && warn_psabi)
+	    {
+	      warned = true;
+	      inform (input_location,
+		      "the layout of aggregates containing vectors with"
+		      " %d-byte alignment will change in a future GCC release",
+		      computed / BITS_PER_UNIT);
+	    }
+	}
+      /* GCC 4.8/4.9 Note: To avoid any ABI change on a release branch, we
+	 keep the special treatment of vector types, but warn if there will
+	 be differences in future GCC releases.  */
+      return true;
+    }
+
+  return false;
+}
+
 /* AIX increases natural record alignment to doubleword if the first
    field is an FP double while the FP fields remain word aligned.  */
 
@@ -9200,14 +9228,51 @@ rs6000_function_arg_boundary (enum machi
 	   || (type && TREE_CODE (type) == VECTOR_TYPE
 	       && int_size_in_bytes (type) >= 16))
     return 128;
-  else if (((TARGET_MACHO && rs6000_darwin64_abi)
-	    || DEFAULT_ABI == ABI_ELFv2
-            || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
- 	   && mode == BLKmode
-	   && type && TYPE_ALIGN (type) > 64)
+
+  /* Aggregate types that need > 8 byte alignment are quadword-aligned
+     in the parameter area in the ELFv2 ABI, and in the AIX ABI unless
+     -mcompat-align-parm is used.  */
+  if (((DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm)
+       || DEFAULT_ABI == ABI_ELFv2)
+      && type && TYPE_ALIGN (type) > 64)
+    {
+      /* "Aggregate" means any AGGREGATE_TYPE except for single-element
+         or homogeneous float/vector aggregates here.  We already handled
+         vector aggregates above, but still need to check for float here. */
+      bool aggregate_p = (AGGREGATE_TYPE_P (type)
+			  && !SCALAR_FLOAT_MODE_P (elt_mode));
+
+      /* We used to check for BLKmode instead of the above aggregate type
+	 check.  Warn when this results in any difference to the ABI.  */
+      if (aggregate_p != (mode == BLKmode))
+	{
+	  static bool warned;
+	  if (!warned && warn_psabi)
+	    {
+	      warned = true;
+	      inform (input_location,
+		      "the ABI of passing aggregates with %d-byte alignment"
+		      " will change in a future GCC release",
+		      (int) TYPE_ALIGN (type) / BITS_PER_UNIT);
+	    }
+	}
+
+      /* GCC 4.8/4.9 Note: To avoid any ABI change on a release branch, we
+	 keep using the BLKmode check, but warn if there will be differences
+	 in future GCC releases.  */
+      if (mode == BLKmode)
+	return 128;
+    }
+
+  /* Similar for the Darwin64 ABI.  Note that for historical reasons we
+     implement the "aggregate type" check as a BLKmode check here; this
+     means certain aggregate types are in fact not aligned.  */
+  if (TARGET_MACHO && rs6000_darwin64_abi
+      && mode == BLKmode
+      && type && TYPE_ALIGN (type) > 64)
     return 128;
-  else
-    return PARM_BOUNDARY;
+
+  return PARM_BOUNDARY;
 }
 
 /* The offset in words to the start of the parameter save area.  */
@@ -10245,6 +10310,7 @@ rs6000_function_arg (cumulative_args_t c
 	  rtx r, off;
 	  int i, k = 0;
 	  unsigned long n_fpreg = (GET_MODE_SIZE (elt_mode) + 7) >> 3;
+	  int fpr_words;
 
 	  /* Do we also need to pass this argument in the parameter
 	     save area?  */
@@ -10273,6 +10339,37 @@ rs6000_function_arg (cumulative_args_t c
 	      rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
 	    }
 
+	  /* If there were not enough FPRs to hold the argument, the rest
+	     usually goes into memory.  However, if the current position
+	     is still within the register parameter area, a portion may
+	     actually have to go into GPRs.
+
+	     Note that it may happen that the portion of the argument
+	     passed in the first "half" of the first GPR was already
+	     passed in the last FPR as well.
+
+	     For unnamed arguments, we already set up GPRs to cover the
+	     whole argument in rs6000_psave_function_arg, so there is
+	     nothing further to do at this point.
+
+	     GCC 4.8/4.9 Note: This was implemented incorrectly in earlier
+	     GCC releases.  To avoid any ABI change on the release branch,
+	     we retain that original implementation here, but warn if we
+	     encounter a case where the ABI will change in the future.  */
+	  fpr_words = (i * GET_MODE_SIZE (elt_mode)) / (TARGET_32BIT ? 4 : 8);
+	  if (i < n_elts && align_words + fpr_words < GP_ARG_NUM_REG
+	      && cum->nargs_prototype > 0)
+            {
+	      static bool warned;
+	      if (!warned && warn_psabi)
+		{
+		  warned = true;
+		  inform (input_location,
+			  "the ABI of passing homogeneous float aggregates"
+			  " will change in a future GCC release");
+		}
+	    }
+
 	  return rs6000_finish_function_arg (mode, rvec, k);
 	}
       else if (align_words < GP_ARG_NUM_REG)
Index: gcc/config/rs6000/sysv4.h
===================================================================
--- gcc/config/rs6000/sysv4.h	(revision 213021)
+++ gcc/config/rs6000/sysv4.h	(revision 213025)
@@ -292,7 +292,7 @@ do {									\
 /* An expression for the alignment of a structure field FIELD if the
    alignment computed in the usual way is COMPUTED.  */
 #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)				      \
-	((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE)     \
+	(rs6000_special_adjust_field_align_p ((FIELD), (COMPUTED))	      \
 	 ? 128 : COMPUTED)
 
 #undef  BIGGEST_FIELD_ALIGNMENT
