> >>When we now have way to represent different reg usages for functions, what 
> >>would be best
> >>way to make local functions to default into saving some SSE registers on 
> >>x86/x86-64?
> >
> >I wouldn't do that at all.  Leave all sse registers call-clobbered.  This way
> >you don't need to have different entry points (or one possibly less efficient
> >entry point) when a function is used both locally and globally.
> >
> >What I would investigate is how to use this hard reg usage data in the 
> >register
> >allocator.  If we know that the callee only uses xmm0-xmm4, then we can keep
> >xmm5-xmm15 live across the call.

What I was shooting for whas to
  1) make it possible to declare by attribute that some registers are not call 
clobbered
  2) have more sane default when the call usage data are not available - either 
because of LTO partitioning
     or because the callee was not copmiled yet.
> >
> 
> AFAIU, what you describe here already works. This patch contains a
> version of the fuse-caller-save test with xmm registers. The callee
> bar only uses xmm0, and caller foo keeps xmm1 live across the call.
> 
> OK for trunk?
> 
> Thanks,
> - Tom
> 

> 2014-07-13  Tom de Vries  <t...@codesourcery.com>
> 
>       * gcc.target/i386/fuse-caller-save-xmm-run.c: New test.
>       * gcc.target/i386/fuse-caller-save-xmm.c: New test.

OK
Honza
> 
> diff --git a/gcc/testsuite/gcc.target/i386/fuse-caller-save-xmm-run.c 
> b/gcc/testsuite/gcc.target/i386/fuse-caller-save-xmm-run.c
> new file mode 100644
> index 0000000..17385fa
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/fuse-caller-save-xmm-run.c
> @@ -0,0 +1,34 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2 -msse -fuse-caller-save" } */
> +
> +typedef double v2df __attribute__((vector_size (16)));
> +
> +static v2df __attribute__((noinline))
> +bar (v2df a)
> +{ 
> +  return a + (v2df){ 3.0, 3.0 };
> +}
> +
> +v2df __attribute__((noinline))
> +foo (v2df y)
> +{
> +  return y + bar (y);
> +}
> +
> +int
> +main (void)
> +{
> +  int success;
> +  union {
> +    v2df v;
> +    double d[2];
> +  } u;
> +
> +  u.v = foo ((v2df){ 5.0, 5.0});
> +  success = (u.d[0] == 13.0
> +          && u.d[1] == 13.0);
> +
> +  return !success;
> +}
> +
> +
> diff --git a/gcc/testsuite/gcc.target/i386/fuse-caller-save-xmm.c 
> b/gcc/testsuite/gcc.target/i386/fuse-caller-save-xmm.c
> new file mode 100644
> index 0000000..de1ca63
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/fuse-caller-save-xmm.c
> @@ -0,0 +1,38 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -msse -fuse-caller-save" } */
> +
> +typedef double v2df __attribute__((vector_size (16)));
> +
> +static v2df __attribute__((noinline))
> +bar (v2df a)
> +{ 
> +  return a + (v2df){ 3.0, 3.0 };
> +}
> +
> +v2df __attribute__((noinline))
> +foo (v2df y)
> +{
> +  return y + bar (y);
> +}
> +
> +int
> +main (void)
> +{
> +  int success;
> +  union {
> +    v2df v;
> +    double d[2];
> +  } u;
> +
> +  u.v = foo ((v2df){ 5.0, 5.0});
> +  success = (u.d[0] == 13.0
> +          && u.d[1] == 13.0);
> +
> +  return !success;
> +}
> +
> +/* { dg-final { scan-assembler-not "movaps\t%xmm1, \\(%rsp\\)" } } */
> +/* { dg-final { scan-assembler-not "movapd\t\\(%rsp\\), %xmm1" } } */
> +/* { dg-final { scan-assembler-times ".cfi_def_cfa_offset 16" 1 } } */
> +/* { dg-final { scan-assembler-times ".cfi_def_cfa_offset 32" 1 } } */
> +

Reply via email to