This is the mail archive of the
mailing list for the GCC project.
[PATCH ARM] -fschedule-insns2 miscompiles epilogues on Thumb1 (PR38644)
- From: Mikael Pettersson <mikpe at it dot uu dot se>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 6 Jun 2010 21:09:25 +0200
- Subject: [PATCH ARM] -fschedule-insns2 miscompiles epilogues on Thumb1 (PR38644)
When compiling for Thumb1, an epilogue can be scheduled incorrectly
causing restores via a derived pointer into the frame to occur after
the stack pointer has been adjusted to deallocate the frame. This
makes the epilogue unsafe for asynchronous events like signals.
This is a regression since gcc-4.2, see PR38644.
A similar bug was fixed recently for PowerPC (PR44199) by conditionally
emitting a stack tie in the epilogue. This patch is similar, except
I'm extending an existing conditional barrier instead of adding a new one.
A full barrier is a little more heavyweight than needed for this PR
in that it will also block some harmless scheduling around the stack
pointer restore. I did experiment with using weaker barriers for the
cases in this PR, but couldn't get them to work properly.
Bootstrapped and regtested with 4.6/4.5/4.4 on armv5tel-linux-gnueabi.
I've manually inspected the code for the test cases in PR38644 and its
duplicates to verify that all restores now occur before the stack frames
Ok for trunk? 4.5? 4.4? (I don't have svn write access.)
2010-06-06 Mikael Pettersson <email@example.com>
* config/arm/arm.c (thumb1_expand_epilogue): Block any
restores from being scheduled after the stack adjustment.
--- gcc-4.6-20100605/gcc/config/arm/arm.c.~1~ 2010-06-05 22:33:22.000000000 +0200
+++ gcc-4.6-20100605/gcc/config/arm/arm.c 2010-06-06 20:12:18.000000000 +0200
@@ -19557,7 +19557,8 @@ thumb1_expand_epilogue (void)
the stack adjustment will not be deleted. */
emit_insn (gen_prologue_use (stack_pointer_rtx));
- if (crtl->profile || !TARGET_SCHED_PROLOG)
+ if (crtl->profile || !TARGET_SCHED_PROLOG
+ || amount > 0) /* do not schedule restores past the stack adjustment */
emit_insn (gen_blockage ());
/* Emit a clobber for each insn that will be restored in the epilogue,