+2020-02-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/85667
+ * config/i386/i386.c (function_arg_ms_64): Add a type argument.
+ Don't return aggregates with only SFmode and DFmode in SSE
+ register.
+ (ix86_function_arg): Pass arg.type to function_arg_ms_64.
+
2020-02-07 Jakub Jelinek <jakub@redhat.com>
PR target/93122
static rtx
function_arg_ms_64 (const CUMULATIVE_ARGS *cum, machine_mode mode,
- machine_mode orig_mode, bool named,
+ machine_mode orig_mode, bool named, const_tree type,
HOST_WIDE_INT bytes)
{
unsigned int regno;
if (TARGET_SSE && (mode == SFmode || mode == DFmode))
{
if (named)
- regno = cum->regno + FIRST_SSE_REG;
+ {
+ if (type == NULL_TREE || !AGGREGATE_TYPE_P (type))
+ regno = cum->regno + FIRST_SSE_REG;
+ }
else
{
rtx t1, t2;
enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
if (call_abi == MS_ABI)
- reg = function_arg_ms_64 (cum, mode, arg.mode, arg.named, bytes);
+ reg = function_arg_ms_64 (cum, mode, arg.mode, arg.named,
+ arg.type, bytes);
else
reg = function_arg_64 (cum, mode, arg.mode, arg.type, arg.named);
}
+2020-02-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/85667
+ * gcc.target/i386/pr85667-10.c: New test.
+ * gcc.target/i386/pr85667-7.c: Likewise.
+ * gcc.target/i386/pr85667-8.c: Likewise.
+ * gcc.target/i386/pr85667-9.c: Likewise.
+
2020-02-07 Jakub Jelinek <jakub@redhat.com>
PR target/93122
--- /dev/null
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-final { scan-assembler-times "movq\[ \t\]*%rcx, .*" 1 } } */
+/* { dg-final { scan-assembler-times "movq\[ \t\]*%rdx, .*" 1 } } */
+/* { dg-final { scan-assembler-times "movq\[ \t\]*%r8, .*" 1 } } */
+/* { dg-final { scan-assembler-times "movq\[ \t\]*%r9, .*" 1 } } */
+/* { dg-final { scan-assembler-times "addsd\[ \t]*40\\\(%rsp\\\), .*" 1 } } */
+/* { dg-final { scan-assembler-times "movq\[^\n\r\]*, %rax" 1 } } */
+
+typedef struct
+{
+ double x;
+} Double;
+
+Double __attribute__((ms_abi))
+fn1 (Double x1, Double x2, Double x3, Double x4, Double x5)
+{
+ Double v;
+ v.x = x1.x + x2.x + x3.x + x4.x + x5.x;
+ return v;
+}
--- /dev/null
+/* { dg-do run { target lp64 } } */
+/* { dg-options "-O2" } */
+
+void abort (void);
+
+typedef struct
+{
+ float x;
+} Float;
+
+Float __attribute__((ms_abi, noinline, noclone))
+fn1 (Float x1, Float x2, Float x3, Float x4, Float x5)
+{
+ Float v;
+ v.x = x1.x + x2.x + x3.x + x4.x + x5.x;
+ return v;
+}
+int main ()
+{
+ Float a, a1, a2, a3, a4, a5;
+ float x1 = 1.1;
+ float x2 = 3.1;
+ float x3 = 4.2;
+ float x4 = 14.2;
+ float x5 = -7.2;
+ float x = x1 + x2 + x3 + x4 + x5;
+ a1.x = x1;
+ a2.x = x2;
+ a3.x = x3;
+ a4.x = x4;
+ a5.x = x5;
+ a = fn1 (a1, a2, a3, a4, a5);
+ if (a.x == x);
+ return 0;
+ abort ();
+}
--- /dev/null
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-final { scan-assembler-times "movd\[ \t\]*%ecx, .*" 1 } } */
+/* { dg-final { scan-assembler-times "movd\[ \t\]*%edx, .*" 1 } } */
+/* { dg-final { scan-assembler-times "movd\[ \t\]*%r8d, .*" 1 } } */
+/* { dg-final { scan-assembler-times "movd\[ \t\]*%r9d, .*" 1 } } */
+/* { dg-final { scan-assembler-times "addss\[ \t]*40\\\(%rsp\\\), .*" 1 } } */
+/* { dg-final { scan-assembler-times "movd\[^\n\r\]*, %eax" 1 } } */
+
+typedef struct
+{
+ float x;
+} Float;
+
+Float __attribute__((ms_abi))
+fn1 (Float x1, Float x2, Float x3, Float x4, Float x5)
+{
+ Float v;
+ v.x = x1.x + x2.x + x3.x + x4.x + x5.x;
+ return v;
+}
--- /dev/null
+/* { dg-do run { target lp64 } } */
+/* { dg-options "-O2" } */
+
+void abort (void);
+
+typedef struct
+{
+ double x;
+} Double;
+
+Double __attribute__((ms_abi, noinline, noclone))
+fn1 (Double x1, Double x2, Double x3, Double x4, Double x5)
+{
+ Double v;
+ v.x = x1.x + x2.x + x3.x + x4.x + x5.x;
+ return v;
+}
+int main ()
+{
+ Double a, a1, a2, a3, a4, a5;
+ double x1 = 1.1;
+ double x2 = 3.1;
+ double x3 = 4.2;
+ double x4 = 14.2;
+ double x5 = -7.2;
+ double x = x1 + x2 + x3 + x4 + x5;
+ a1.x = x1;
+ a2.x = x2;
+ a3.x = x3;
+ a4.x = x4;
+ a5.x = x5;
+ a = fn1 (a1, a2, a3, a4, a5);
+ if (a.x == x);
+ return 0;
+ abort ();
+}