Hi,

ix86_function_arg sets cfun->machine->callee_pass_avx256_p from the
current argument.  It clears callee_pass_avx256_p when ix86_function_arg
is called to generate a library call to passs an argument.  This patch
adds callee_pass_avx256_p and callee_return_avx256_p to ix86_args to store
the AVX info in CUM and copy it to cfun->machine->callee_pass_avx256_p
when ix86_function_arg is called immediately before the call instruction
is emitted.  OK for 4.7 branch?

Thanks.


H.J.
--
gcc/

2013-03-18  H.J. Lu  <hongjiu...@intel.com>

        PR target/56560
        * config/i386/i386.c (init_cumulative_args): Also set
        cum->callee_return_avx256_p.
        (ix86_function_arg): Set cum->callee_pass_avx256_p.  Set
        cfun->machine->callee_pass_avx256_p only when MODE == VOIDmode.

        * config/i386/i386.h (ix86_args): Add callee_pass_avx256_p and
        callee_return_avx256_p.

gcc/

2013-03-18  H.J. Lu  <hongjiu...@intel.com>

        PR target/56560
        * gcc.target/i386/pr56560.c: New file.

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index c1f6c88..7a441c7 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -5592,7 +5592,10 @@ init_cumulative_args (CUMULATIVE_ARGS *cum,  /* Argument 
info to initialize */
        {
          /* The return value of this function uses 256bit AVX modes.  */
          if (caller)
-           cfun->machine->callee_return_avx256_p = true;
+           {
+             cfun->machine->callee_return_avx256_p = true;
+             cum->callee_return_avx256_p = true;
+           }
          else
            cfun->machine->caller_return_avx256_p = true;
        }
@@ -6863,11 +6866,20 @@ ix86_function_arg (cumulative_args_t cum_v, enum 
machine_mode omode,
     {
       /* This argument uses 256bit AVX modes.  */
       if (cum->caller)
-       cfun->machine->callee_pass_avx256_p = true;
+       cum->callee_pass_avx256_p = true;
       else
        cfun->machine->caller_pass_avx256_p = true;
     }
 
+  if (cum->caller && mode == VOIDmode)
+    {
+      /* This function is called with MODE == VOIDmode immediately
+        before the call instruction is emitted.  We copy callee 256bit
+        AVX info from the current CUM here.  */
+      cfun->machine->callee_return_avx256_p = cum->callee_return_avx256_p;
+      cfun->machine->callee_pass_avx256_p = cum->callee_pass_avx256_p;
+    }
+
   return arg;
 }
 
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 80d19f1..899678d 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1502,6 +1502,10 @@ typedef struct ix86_args {
                                   in SSE registers.  Otherwise 0.  */
   enum calling_abi call_abi;   /* Set to SYSV_ABI for sysv abi. Otherwise
                                   MS_ABI for ms abi.  */
+  /* Nonzero if it passes 256bit AVX modes.  */
+  BOOL_BITFIELD callee_pass_avx256_p : 1;
+  /* Nonzero if it returns 256bit AVX modes.  */
+  BOOL_BITFIELD callee_return_avx256_p : 1;
 } CUMULATIVE_ARGS;
 
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
diff --git a/gcc/testsuite/gcc.target/i386/pr56560.c 
b/gcc/testsuite/gcc.target/i386/pr56560.c
new file mode 100644
index 0000000..5417cbd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr56560.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx -mvzeroupper -dp" } */
+
+extern void abort (void);
+
+typedef double vec_t __attribute__((vector_size(32)));
+
+struct S { int i1; int i2; int i3; };
+
+extern int bar (vec_t, int, int, int, int, int, struct S);
+
+void foo (vec_t v, struct S s)
+{
+  int i = bar (v, 1, 2, 3, 4, 5, s);
+  if (i == 0)
+    abort ();
+}
+
+/* { dg-final { scan-assembler-not "avx_vzeroupper" } } */

Reply via email to