On Mon, Jan 26, 2015 at 05:55:52PM +0800, Hale Wang wrote:
> diff --git a/gcc/combine.c b/gcc/combine.c
> index 5c763b4..cf48666 100644
> --- a/gcc/combine.c
> +++ b/gcc/combine.c
> @@ -2004,6 +2004,13 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn
> *pred ATTRIBUTE_UNUSED,
> return 0;
> }
>
> + /* If src contains a volatile register, reject, because the register may
> + possibly be used in a asm operand. The combined insn may cause the
> asm
> + operand to be generated unexpectly. */
> +
> + if (REG_P (src) && REG_USERVAR_P (src))
> + return 0;
> +
> /* If INSN contains anything volatile, or is an `asm' (whether volatile
> or not), reject, unless nothing volatile comes between it and I3 */
> diff --git a/gcc/testsuite/gcc.target/arm/pr46164.c
> b/gcc/testsuite/gcc.target/arm/pr46164.c
> new file mode 100644
> index 0000000..ad3b7cb
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pr46164.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mcpu=cortex-m3 -mthumb -O1" } */
Just "-O1" reproduces the problem here, FWIW.
Could you try this patch please?
Segher
diff --git a/gcc/combine.c b/gcc/combine.c
index 58de157..10c3b0e 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1928,6 +1928,10 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn
*pred ATTRIBUTE_UNUSED,
set = expand_field_assignment (set);
src = SET_SRC (set), dest = SET_DEST (set);
+ /* Don't eliminate a register variable. */
+ if (REG_P (dest) && REG_USERVAR_P (dest))
+ return 0;
+
/* Don't eliminate a store in the stack pointer. */
if (dest == stack_pointer_rtx
/* Don't combine with an insn that sets a register to itself if it has