diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a1c3658a2ab832eba5a5ce185dde9e1d605e4dec..31762851e516ca976cb8ae05ea06acc6951998cc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2010-08-20 Olivier Hainque <hainque@adacore.com> + + * config/sparc/sparc.c (sparc_asm_function_epilogue): Don't output + an extra nop past a sibling call at the very end. + 2010-08-19 Bernd Schmidt <bernds@codesourcery.com> PR bootstrap/45350 diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index ef1dd730eae7fa13e420f95454717e568fe960e0..50b981e749fa5630583de1924372e2dd71fe9a39 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -4527,11 +4527,11 @@ sparc_can_use_return_insn_p (void) static void sparc_asm_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED) { - /* If code does not drop into the epilogue, we have to still output - a dummy nop for the sake of sane backtraces. Otherwise, if the - last two instructions of a function were "call foo; dslot;" this - can make the return PC of foo (i.e. address of call instruction - plus 8) point to the first instruction in the next function. */ + /* If the last two instructions of a function are "call foo; dslot;" + the return address might point to the first instruction in the next + function and we have to output a dummy nop for the sake of sane + backtraces in such cases. This is pointless for sibling calls since + the return address is explicitly adjusted. */ rtx insn, last_real_insn; @@ -4543,7 +4543,9 @@ sparc_asm_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED) && GET_CODE (PATTERN (last_real_insn)) == SEQUENCE) last_real_insn = XVECEXP (PATTERN (last_real_insn), 0, 0); - if (last_real_insn && GET_CODE (last_real_insn) == CALL_INSN) + if (last_real_insn + && CALL_P (last_real_insn) + && !SIBLING_CALL_P (last_real_insn)) fputs("\tnop\n", file); sparc_output_deferred_case_vectors (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e8bbfc1e3b5c9f3659a3af0e5750f2b1e5e5b2d1..e46fd3f22dfab7a071225b27580c3b6064a97271 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-10-19 Olivier Hainque <hainque@adacore.com> + + * gcc.target/sparc/sibcall-dslot.c: New testcase. + 2010-08-19 Jason Merrill <jason@redhat.com> * g++.dg/init/synth3.C: New. diff --git a/gcc/testsuite/gcc.target/sparc/sibcall-dslot.c b/gcc/testsuite/gcc.target/sparc/sibcall-dslot.c new file mode 100644 index 0000000000000000000000000000000000000000..db3401648e86959ebf654e2dc20aeac96f5d768c --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/sibcall-dslot.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +extern int one (); + +int some_n () +{ + return one (); +} + +/* { dg-final { scan-assembler-not "nop" } } */