On 01-07-14 19:26, Jeff Law wrote:
On 07/01/14 09:51, Yufeng Zhang wrote:
Hi,

This patch resolves a conflict between the aapcs64 test framework for
func-ret tests and the optimization option -fuse-caller-save, which was
enabled by default at -O1 or above recently.


Minor detail: it's enabled by default at -O2 or above:
...
    { OPT_LEVELS_2_PLUS, OPT_fuse_caller_save, NULL, 1 },
...

Basically, the test framework has an inline-assembly based mechanism in
place which invokes the test facility function right on the return of a
tested function.
>>  The compiler with -fuse-caller-save is unable to
>> identify the unconventional call graph and carries out the optimization
>> regardless.

AFAIU, we're overwriting the return register to implement a function call at return in order to see the exact state of registers at return:
...
__attribute__ ((noinline)) unsigned char
func_return_val_0 (int i, double d, unsigned char t)
{
  asm (""::"r" (i),"r" (d));
  asm volatile ("mov %0, x30" : "=r" (saved_return_address));
  asm volatile ("mov x30, %0" : : "r" ((unsigned long long) myfunc));
  return t;
}
...

But we're not informing the compiler that a hidden function call takes place. This patch fixes that, and there's no need to disable fuse-caller-save.

Tested with aarch64 build.  OK for trunk?

Thanks,
- Tom

2014-07-08  Tom de Vries  <t...@codesourcery.com>

	* gcc.target/aarch64/aapcs64/aapcs64.exp
	(additional_flags_for_func_ret): Remove.
	(func-ret-*.c): Use additional_flags.
	* gcc.target/aarch64/aapcs64/abitest-2.h (FUNC_VAL_CHECK): Add missing
	call_used_regs clobbers.

Index: gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp
===================================================================
--- gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp (revision 212294)
+++ gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp (working copy)
@@ -48,15 +48,11 @@ foreach src [lsort [glob -nocomplain $sr
 }
 
 # Test function return value.
-#   Disable -fuse-caller-save to prevent the compiler from generating
-#   conflicting code.
-set additional_flags_for_func_ret $additional_flags
-append additional_flags_for_func_ret " -fno-use-caller-save"
 foreach src [lsort [glob -nocomplain $srcdir/$subdir/func-ret-*.c]] {
     if {[runtest_file_p $runtests $src]} {
 	    c-torture-execute [list $src \
 				    $srcdir/$subdir/abitest.S] \
-				    $additional_flags_for_func_ret
+				    $additional_flags
     }
 }
 
Index: gcc/testsuite/gcc.target/aarch64/aapcs64/abitest-2.h
===================================================================
--- gcc/testsuite/gcc.target/aarch64/aapcs64/abitest-2.h (revision 212294)
+++ gcc/testsuite/gcc.target/aarch64/aapcs64/abitest-2.h (working copy)
@@ -80,10 +80,18 @@ __attribute__ ((noinline)) type FUNC_NAM
        The previous approach of sequentially calling myfunc right after	  \
        this function does not guarantee myfunc see the exact register	  \
        content, as compiler may emit code in between the two calls,	  \
-       especially during the -O0 codegen.  */				  \
+       especially during the -O0 codegen.				  \
+       However, since we're doing a call, we need to clobber all call	  \
+       used regs.  */							  \
     asm volatile ("mov %0, x30" : "=r" (saved_return_address));		  \
-    asm volatile ("mov x30, %0" : : "r" ((unsigned long long) myfunc));   \
-    return t;								  \
+    asm volatile ("mov x30, %0" : : "r" ((unsigned long long) myfunc) :	  \
+		  "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",	  \
+		  "x8",	 "x9",	"x10", "x11", "x12", "x13", "x14", "x15", \
+		  "x16", "x17", "x18",					  \
+		  "v0",	 "v1",	"v2",  "v3",  "v4",  "v5",  "v6",  "v7",  \
+		  "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", \
+		  "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31");\
+    return t;								\
   }
 #include TESTFILE
 

Reply via email to