On Mon, Jan 26, 2015 at 1:55 AM, Hale Wang <hale.w...@arm.com> wrote:
> Hi,
>
> The GCC combine pass combines the insns even though they contain volatile
> registers. This doesn't make sence.
>
> The test case listed in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46164
> shows the expected asm command "mov r1, r1" is not generated."r1" is defined
> as a volatile register, and there are three insns related to r1:
>
>     (insn 98 97 40 3 (set (reg/v:SI 1 r1 [ b ]) (reg:SI 154 [ b ]))
>     (insn 41 40 43 3 (set (reg/f:SI 148)        (reg/v:SI 1 r1 [ b ]))
>     (insn 43 41 45 3 (parallel [
>             (set (reg/v:SI 0 r0 [ ret ])
>                 (asm_operands/v:SI ("mov %2, %2  mov %3, %3  mov %4, %4")
> ("=r") 0 [
>                         (reg/v:SI 0 r0 [ a ])
>                         (reg/v:SI 1 r1 [ b ])
>                         (reg/v:SI 2 r2 [ c ])
>                         (mem/c:QI (reg/f:SI 148) [0 MEM[(char *)&temp]+0 S1
> A8])
>                         ....
> The combine pass combine these insns:
>
>     (note 98 97 40 3 NOTE_INSN_DELETED)
>     (note 41 40 43 3 NOTE_INSN_DELETED)
>     (insn 43 41 45 3 (parallel [
>             (set (reg/v:SI 0 r0 [ ret ])
>                 (asm_operands/v:SI ("mov %2, %2  mov %3, %3  mov %4, %4")
> ("=r") 0 [
>                         (reg/v:SI 0 r0 [ a ])
>                         (reg:SI 154 [ b ])
>                         (reg/v:SI 2 r2 [ c ])
>                         (mem/c:QI (reg:SI 154 [ b ]) [0 MEM[(char *)&temp]+0
> S1 A8])
>                         ....
>
> The volatile register "r1" is totally disappeared in the asm_operands, and
> the generated asm code is unexpected.


I think it is allowed to the second combining, just not the first.
Also it is not about volatile registers here but rather user specified
registers into inline-asm.
Also I thought can_combine_p would reject combing into an inline-asm
to prevent this issue.

Thanks,
Andrew

>
> This patch is used to disable the combine operation if the insns contain
> volatile registers. A new test case is also added in this patch.
>
> Is it OK for trunk?
>
> BR,
> Hale Wang
>
> ChangeLog:
>
> 2015-01-22  Hale Wang  <hale.w...@arm.com>
>
>         PR middle-end/46164
>         * combine.c (can_combine_p): Don't combine the insns if
>         a volatile register is contained.
>
> 2015-01-22  Hale Wang  <hale.w...@arm.com>
>
>         PR middle-end/46164
>         * gcc.target/arm/pr46164.c: New test.
>
>
> 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" } */
> +
> +char temp[16];
> +extern int foo1 (void);
> +
> +void foo (void)
> +{
> +  int i;
> +  int len;
> +
> +  while (1)
> +  {
> +    len = foo1 ();
> +    register char *a asm ("r1") = temp;
> +    asm volatile ("mov %[r1], %[r1]\n " :: [r1]"r"(a), "m"(*a));
> +
> +    for (i = 0; i < len; i++)
> +    {
> +      if (temp[i] == 10)
> +      return;
> +    }
> +  }
> +}
> +
> +/* { dg-final { scan-assembler "\[\\t \]+mov\ r1,\ r1" } } */

Reply via email to