diff mbox

[SPARC] Fix PR target/63668

Message ID 4739213.p58MlSbaLt@polaris
State New
Headers show

Commit Message

Eric Botcazou Dec. 7, 2015, 11:18 p.m. UTC
As reported by Richard H, the -mstd-struct-return option of the SPARC compiler 
is totally broken with optimization (and has probably been so since the merge 
of the DF branch).  Now it's also undocumented, which might explain why nobody 
apparently noticed the breakage before Richard.

The problem is that the option fiddles with the return address register %i7 
and this register is marked as fixed, hence as call-used, so the adjustments 
are eliminated as dead code in non-leaf functions.  Addressed by defining 
CALL_REALLY_USED_REGISTERS and removing %i7 from the list.

Tested on SPARC/Solaris, applied on the mainline.


2015-12-07  Eric Botcazou  <ebotcazou@adacore.com>

	PR target/63668
	* doc/invoke.texi (SPARC options): Document -mstd-struct-return.
	* config/sparc/sparc.c (sparc_struct_value_rtx): Minor tweaks.
	* config/sparc/sparc.h (CALL_REALLY_USED_REGISTERS): Define.
	* config/sparc/sparc.opt (mstd-struct-return): Accept negative form.


2015-12-07  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.target/sparc/struct-ret-check.c: Rename to...
	* gcc.target/sparc/struct-ret-check-1.c: ...this.
	* gcc.target/sparc/struct-ret-check-2.c: New test.
diff mbox

Patch

Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 231318)
+++ doc/invoke.texi	(working copy)
@@ -1022,6 +1022,7 @@  See RS/6000 and PowerPC Options.
 -mfpu  -mno-fpu  -mhard-float  -msoft-float @gol
 -mhard-quad-float  -msoft-quad-float @gol
 -mstack-bias  -mno-stack-bias @gol
+-mstd-struct-return  -mno-std-struct-return @gol
 -munaligned-doubles  -mno-unaligned-doubles @gol
 -muser-mode  -mno-user-mode @gol
 -mv8plus  -mno-v8plus  -mvis  -mno-vis @gol
@@ -21586,10 +21587,10 @@  Do not generate code that can only run i
 only for the @code{casa} instruction emitted for the LEON3 processor.  This
 is the default.
 
-@item -mno-faster-structs
-@itemx -mfaster-structs
-@opindex mno-faster-structs
+@item -mfaster-structs
+@itemx -mno-faster-structs
 @opindex mfaster-structs
+@opindex mno-faster-structs
 With @option{-mfaster-structs}, the compiler assumes that structures
 should have 8-byte alignment.  This enables the use of pairs of
 @code{ldd} and @code{std} instructions for copies in structure
@@ -21599,6 +21600,17 @@  ABI@.  Thus, it's intended only for use
 acknowledges that their resulting code is not directly in line with
 the rules of the ABI@.
 
+@item -mstd-struct-return
+@itemx -mno-std-struct-return
+@opindex mstd-struct-return
+@opindex mno-std-struct-return
+With @option{-mstd-struct-return}, the compiler generates checking code
+in functions returning structures or unions that detect size mismatches
+between the two sides of function calls, as per the 32-bit ABI@.
+
+The default is @option{-mno-std-struct-return}.  This option has no effect
+in 64-bit mode.
+
 @item -mcpu=@var{cpu_type}
 @opindex mcpu
 Set the instruction set, register set, and instruction scheduling parameters
Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 231318)
+++ config/sparc/sparc.c	(working copy)
@@ -7199,17 +7199,16 @@  sparc_struct_value_rtx (tree fndecl, int
 	  && TYPE_SIZE_UNIT (TREE_TYPE (fndecl))
 	  && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (fndecl))) == INTEGER_CST)
 	{
-	  /* We must check and adjust the return address, as it is
-	     optional as to whether the return object is really
-	     provided.  */
-	  rtx ret_reg = gen_rtx_REG (Pmode, 31);
+	  /* We must check and adjust the return address, as it is optional
+	     as to whether the return object is really provided.  */
+	  rtx ret_reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
 	  rtx scratch = gen_reg_rtx (SImode);
 	  rtx_code_label *endlab = gen_label_rtx ();
 
-	  /* Calculate the return object size */
+	  /* Calculate the return object size.  */
 	  tree size = TYPE_SIZE_UNIT (TREE_TYPE (fndecl));
 	  rtx size_rtx = GEN_INT (TREE_INT_CST_LOW (size) & 0xfff);
-	  /* Construct a temporary return value */
+	  /* Construct a temporary return value.  */
 	  rtx temp_val
 	    = assign_stack_local (Pmode, TREE_INT_CST_LOW (size), 0);
 
@@ -7221,13 +7220,13 @@  sparc_struct_value_rtx (tree fndecl, int
 	  emit_move_insn (scratch, gen_rtx_MEM (SImode,
 						plus_constant (Pmode,
 							       ret_reg, 8)));
-	  /* Assume the size is valid and pre-adjust */
+	  /* Assume the size is valid and pre-adjust.  */
 	  emit_insn (gen_add3_insn (ret_reg, ret_reg, GEN_INT (4)));
 	  emit_cmp_and_jump_insns (scratch, size_rtx, EQ, const0_rtx, SImode,
 				   0, endlab);
 	  emit_insn (gen_sub3_insn (ret_reg, ret_reg, GEN_INT (4)));
 	  /* Write the address of the memory pointed to by temp_val into
-	     the memory pointed to by mem */
+	     the memory pointed to by mem.  */
 	  emit_move_insn (mem, XEXP (temp_val, 0));
 	  emit_label (endlab);
 	}
Index: config/sparc/sparc.h
===================================================================
--- config/sparc/sparc.h	(revision 231318)
+++ config/sparc/sparc.h	(working copy)
@@ -696,6 +696,31 @@  extern enum cmodel sparc_cmodel;
 				\
   1, 1, 1, 1, 1, 1, 1}
 
+/* 1 for registers not available across function calls.
+   Unlike the above, this need not include the FIXED_REGISTERS, but any
+   registers that can be used without being saved.
+   The latter must include the registers where values are returned
+   and the register where structure-value addresses are passed.
+   Aside from that, you can include as many other registers as you like.  */
+
+#define CALL_REALLY_USED_REGISTERS  \
+ {1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+				\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+				\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+				\
+  1, 1, 1, 1, 1, 1, 1}
+
 /* Return number of consecutive hard regs needed starting at reg REGNO
    to hold something of mode MODE.
    This is ordinarily the length in words of a value of mode MODE
Index: config/sparc/sparc.opt
===================================================================
--- config/sparc/sparc.opt	(revision 231318)
+++ config/sparc/sparc.opt	(working copy)
@@ -203,7 +203,7 @@  Target RejectNegative Joined Var(sparc_d
 Enable debug output.
 
 mstd-struct-return
-Target Report RejectNegative Var(sparc_std_struct_return)
+Target Report Var(sparc_std_struct_return)
 Enable strict 32-bit psABI struct return checking.
 
 mfix-at697f