]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix calling convention incompatibility with vendor compiler
authorEric Botcazou <ebotcazou@adacore.com>
Thu, 25 Apr 2024 10:44:14 +0000 (12:44 +0200)
committerEric Botcazou <ebotcazou@adacore.com>
Thu, 25 Apr 2024 10:47:57 +0000 (12:47 +0200)
For the 20th anniversary of https://gcc.gnu.org/gcc-3.4/sparc-abi.html,
a new calling convention incompatibility with the vendor compiler (and
the ABI) has been discovered in 64-bit mode, affecting small structures
containing arrays of floating-point components.  The decision has been
made to fix it on Solaris only at this point.

gcc/
PR target/114416
* config/sparc/sparc.h (SUN_V9_ABI_COMPATIBILITY): New macro.
* config/sparc/sol2.h (SUN_V9_ABI_COMPATIBILITY): Redefine it.
* config/sparc/sparc.cc (fp_type_for_abi): New predicate.
(traverse_record_type): Use it to spot floating-point types.
(compute_fp_layout): Also deal with array types.

gcc/testsuite/
* gcc.target/sparc/small-struct-1.c: New test.
* gcc.target/sparc/pr105573.c: Rename to...
* gcc.target/sparc/20230425-1.c: ...this.
* gcc.target/sparc/pr109541.c: Rename to...
* gcc.target/sparc/20230607-1.c: ...this

gcc/config/sparc/sol2.h
gcc/config/sparc/sparc.cc
gcc/config/sparc/sparc.h
gcc/testsuite/gcc.target/sparc/20230425-1.c [moved from gcc/testsuite/gcc.target/sparc/pr105573.c with 82% similarity]
gcc/testsuite/gcc.target/sparc/20230607-1.c [moved from gcc/testsuite/gcc.target/sparc/pr109541.c with 92% similarity]
gcc/testsuite/gcc.target/sparc/small-struct-1.c [new file with mode: 0644]

index e849af9038b9d77b656230639d6ae451c2d41bcc..552f58b2cc87c99a42342688e42383dcbff005cc 100644 (file)
@@ -456,3 +456,6 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 
 #undef SPARC_LOW_FE_EXCEPT_VALUES
 #define SPARC_LOW_FE_EXCEPT_VALUES 1
+
+#undef SUN_V9_ABI_COMPATIBILITY
+#define SUN_V9_ABI_COMPATIBILITY 1
index 30fa4474bbd0321260c51acc9dcb8b3e212daa22..8a5f76c8885fc8b16d18c95810fda4a6ee0745a8 100644 (file)
@@ -6782,6 +6782,22 @@ sparc_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
            || 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
@@ -6820,8 +6836,7 @@ traverse_record_type (const_tree type, bool named, T *data,
                                         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);
          }
@@ -7072,6 +7087,13 @@ compute_fp_layout (const_tree field, int bitpos, assign_data_t *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;
 
index fb074808d30d4b5a049b429e7a732137728e5a5e..232ecb30ddc98ad9a303961bd31c30cc93130d52 100644 (file)
@@ -1700,3 +1700,6 @@ extern int sparc_indent_opcode;
 #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
similarity index 82%
rename from gcc/testsuite/gcc.target/sparc/pr105573.c
rename to gcc/testsuite/gcc.target/sparc/20230425-1.c
index 14043a5fdadae44adf559f8e2e68d3e052697f7e..c07dd3261fc25e9547f6c1e8163227b1d7d6fd5e 100644 (file)
@@ -1,3 +1,6 @@
+/* PR target/105573 */
+/* Reported by Sam James <sjames@gcc.gnu.org> */
+
 /* { dg-do compile } */
 /* { dg-options "-O3 -mvis3" } */
 
similarity index 92%
rename from gcc/testsuite/gcc.target/sparc/pr109541.c
rename to gcc/testsuite/gcc.target/sparc/20230607-1.c
index 1360f1019306671977704cfa5f87bae140426365..3613dca602f0c0b0593fc9f253e1c6d99f080ae4 100644 (file)
@@ -1,3 +1,6 @@
+/* PR target.109541 */
+/* Reported by Sam James <sjames@gcc.gnu.org> */
+
 /* { dg-do compile } */
 /* { dg-options "-O1 -mcpu=niagara4 -fpic -w" } */
 
diff --git a/gcc/testsuite/gcc.target/sparc/small-struct-1.c b/gcc/testsuite/gcc.target/sparc/small-struct-1.c
new file mode 100644 (file)
index 0000000..4897288
--- /dev/null
@@ -0,0 +1,46 @@
+/* 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" } } */