From 67bc84fbb05664ec45d2a0319520c96f011a9596 Mon Sep 17 00:00:00 2001 From: Greta Yorsh Date: Fri, 19 Apr 2013 13:55:26 +0100 Subject: [PATCH] re PR target/56797 (internal compiler error: in extract_insn, at recog.c:2150) 2013-04-19 Greta Yorsh PR target/56797 * config/arm/arm.c (load_multiple_sequence): Require SP as base register for loads if SP is in the register list. From-SVN: r198091 --- gcc/ChangeLog | 6 ++++++ gcc/config/arm/arm.c | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 43ed933b77a..439471d4d79 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-04-19 Greta Yorsh + + PR target/56797 + * config/arm/arm.c (load_multiple_sequence): Require SP + as base register for loads if SP is in the register list. + 2013-04-19 Martin Jambor PR tree-optimization/56718 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 9088d1a64ab..7567afc719a 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -10755,6 +10755,13 @@ load_multiple_sequence (rtx *operands, int nops, int *regs, int *saved_order, || (i != nops - 1 && unsorted_regs[i] == base_reg)) return 0; + /* Don't allow SP to be loaded unless it is also the base + register. It guarantees that SP is reset correctly when + an LDM instruction is interruptted. Otherwise, we might + end up with a corrupt stack. */ + if (unsorted_regs[i] == SP_REGNUM && base_reg != SP_REGNUM) + return 0; + unsorted_offsets[i] = INTVAL (offset); if (i == 0 || unsorted_offsets[i] < unsorted_offsets[order[0]]) order[0] = i; -- 2.30.2