From 9250444b59bb08bd5939c4af410eb153153baef9 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 7 Dec 2015 23:18:29 +0000 Subject: [PATCH] re PR target/63668 (-mstd-struct-return fails for non-leaf functions) 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. From-SVN: r231387 --- gcc/ChangeLog | 10 ++++++- gcc/config/sparc/sparc.c | 15 +++++----- gcc/config/sparc/sparc.h | 25 ++++++++++++++++ gcc/config/sparc/sparc.opt | 2 +- gcc/doc/invoke.texi | 18 ++++++++++-- gcc/testsuite/ChangeLog | 6 ++++ ...truct-ret-check.c => struct-ret-check-1.c} | 0 .../gcc.target/sparc/struct-ret-check-2.c | 29 +++++++++++++++++++ 8 files changed, 92 insertions(+), 13 deletions(-) rename gcc/testsuite/gcc.target/sparc/{struct-ret-check.c => struct-ret-check-1.c} (100%) create mode 100644 gcc/testsuite/gcc.target/sparc/struct-ret-check-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ade56278e4b..f6f3ff57231 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-12-07 Eric Botcazou + + 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. + 2015-12-07 Steve Ellcey * reorg.c (optimize_skip): Do not put frame related instructions @@ -14,7 +22,7 @@ 2015-12-07 Jan Hubicka - * fold-const.c (operand_equal_p): Drp flag_strict_aliasing check. + * fold-const.c (operand_equal_p): Drop flag_strict_aliasing check. 2015-12-07 Nathan Sidwell diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index ae96a9bf8db..55ddacf511e 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -7199,17 +7199,16 @@ sparc_struct_value_rtx (tree fndecl, int incoming) && 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 incoming) 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); } diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index d2782a47bb1..d599418c088 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -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 diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt index 16583c38545..a50ba05ace4 100644 --- a/gcc/config/sparc/sparc.opt +++ b/gcc/config/sparc/sparc.opt @@ -203,7 +203,7 @@ Target RejectNegative Joined Var(sparc_debug_string) 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 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 33f579f88cd..9a30a2f769e 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 in supervisor mode. This is relevant 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 on targets where the developer 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 000165ce0f9..fec47e137fb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-12-07 Eric Botcazou + + * 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. + 2015-12-07 Jakub Jelinek PR c++/68760 diff --git a/gcc/testsuite/gcc.target/sparc/struct-ret-check.c b/gcc/testsuite/gcc.target/sparc/struct-ret-check-1.c similarity index 100% rename from gcc/testsuite/gcc.target/sparc/struct-ret-check.c rename to gcc/testsuite/gcc.target/sparc/struct-ret-check-1.c diff --git a/gcc/testsuite/gcc.target/sparc/struct-ret-check-2.c b/gcc/testsuite/gcc.target/sparc/struct-ret-check-2.c new file mode 100644 index 00000000000..2b815345ab9 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/struct-ret-check-2.c @@ -0,0 +1,29 @@ +/* { dg-do run } */ +/* { dg-options "-O -mstd-struct-return" } */ +/* { dg-require-effective-target ilp32 } */ + +extern void abort (void); + +struct S { int x, y, z; }; + +extern void bar (struct S *s) __attribute__ ((noinline, noclone)); + +void bar (struct S *s) +{ + s->x++; +} + +struct S foo (void) +{ + struct S s = { 0, 2, 3 }; + bar (&s); + return s; +} + +int main (void) +{ + struct S s = foo (); + if (s.x != 1) + abort (); + return 0; +} -- 2.30.2