#undef SPARC_LOW_FE_EXCEPT_VALUES
#define SPARC_LOW_FE_EXCEPT_VALUES 1
+
+#undef SUN_V9_ABI_COMPATIBILITY
+#define SUN_V9_ABI_COMPATIBILITY 1
|| GET_MODE_SIZE (mode) > 16);
}
+/* Return true if TYPE is considered as a floating-point type by the ABI. */
+
+static bool
+fp_type_for_abi (const_tree type)
+{
+ /* This is the original GCC implementation. */
+ if (FLOAT_TYPE_P (type) || VECTOR_TYPE_P (type))
+ return true;
+
+ /* This has been introduced in GCC 14 to match the vendor compiler. */
+ if (SUN_V9_ABI_COMPATIBILITY && TREE_CODE (type) == ARRAY_TYPE)
+ return fp_type_for_abi (TREE_TYPE (type));
+
+ return false;
+}
+
/* Traverse the record TYPE recursively and call FUNC on its fields.
NAMED is true if this is for a named parameter. DATA is passed
to FUNC for each field. OFFSET is the starting position and
packed);
else
{
- const bool fp_type
- = FLOAT_TYPE_P (field_type) || VECTOR_TYPE_P (field_type);
+ const bool fp_type = fp_type_for_abi (field_type);
Func (field, bitpos, fp_type && named && !packed && TARGET_FPU,
data);
}
mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (field)));
nregs = 2;
}
+ else if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)
+ {
+ tree elt_type = strip_array_types (TREE_TYPE (field));
+ mode = TYPE_MODE (elt_type);
+ nregs
+ = int_size_in_bytes (TREE_TYPE (field)) / int_size_in_bytes (elt_type);
+ }
else
nregs = 1;
#define SPARC_LOW_FE_EXCEPT_VALUES 0
#define TARGET_SUPPORTS_WIDE_INT 1
+
+/* Define this to 1 to accept ABI changes to match the vendor compiler. */
+#define SUN_V9_ABI_COMPATIBILITY 0
--- /dev/null
+/* PR target/114416 */
+/* Reported by Rainer Orth <ro@gcc.gnu.org> */
+
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+/* { dg-require-effective-target lp64 } */
+
+struct vec2
+{
+ double x[2];
+};
+
+struct vec2x
+{
+ double x;
+ double y;
+};
+
+struct vec2 sum2 (double val)
+{
+ struct vec2 v;
+ v.x[0] = val;
+ v.x[1] = val;
+ return v;
+}
+
+struct vec2x sum2x (double val)
+{
+ struct vec2x v;
+ v.x = val;
+ v.y = val;
+ return v;
+}
+
+double get2 (struct vec2 v)
+{
+ return v.x[0] + v.x[1];
+}
+
+double get2x (struct vec2x v)
+{
+ return v.x + v.y;
+}
+
+/* { dg-final { scan-assembler-not "ldx" } } */
+/* { dg-final { scan-assembler-not "stx" } } */