https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64818

            Bug ID: 64818
           Summary: User specified register don't work correctly in
                    inline-asm operands.
           Product: gcc
           Version: 5.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: Hale.Wang at arm dot com

Created attachment 34588
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=34588&action=edit
arm-none-eabi-gcc -O1 -S -o testcase.s testcase.c

The testcase is submitted by Tim Pambor in bug #46164. But it's actually not
the same bug with #46164. So I resubmitted the comments here.

Command: arm-none-eabi-gcc -O1 -S -o testcase.s testcase.c

The expected assembler code should be:

  mov r4, .L_temp
  mov r1, r4
  ...
  mov r0, r0    @ r0
  mov r1, r1    @ r1
  mov r2, r2    @ r2

But GCC combined the insns, and the code is generated as:

  mov r4, .L_temp
  ...
  mov r0, r0    @ r0
  mov r4, r4    @ r1
  mov r2, r2    @ r2

Just "-O1" could reproduce this problem.

The combine pass combined the user specified registers into inline-asm
operation which caused this bug.

There are three insns which are related to the user specified register "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 as:

     (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])

But actually 41+43 can be combined but 98+43 can not. Because if combining the
98+43, the user specified register will be replaced with a normal virtual
register reg 154. It's not the user expected behavior.

Reply via email to