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

            Bug ID: 65648
           Summary: [5 Regression] Bad code due to IRA fails to recognize
                    the clobber in parallel
           Product: gcc
           Version: 5.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: terry.guo at arm dot com

Created attachment 35200
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35200&action=edit
test case

When compile attached case with command:
arm-none-eabi-gcc -march=armv6-m -mthumb -Os x.c -S

The gcc generates bad code as below:
main:
        push    {r0, r1, r2, r4, r5, r6, r7, lr}
        ldr     r4, .L5
        movs    r5, #0
        ldr     r0, [r4, #8]
        add     r1, sp, #4
        rsbs    r2, r0, #0
        adcs    r2, r2, r0
        subs    r3, r2, r3  //r3 is used but not initialized

The instruction to initialize r3 is removed due to IRA failed to recognize the
clobber in reload pass. Before the reload pass, we have three instructions like
below:
(insn 12 11 14 2 (parallel [
            (set (reg:SI 128)
                (eq:SI (reg:SI 110 [ D.4914 ])
                    (const_int 0 [0])))
            (clobber (reg:SI 129))
        ]) x.c:23 760 {*cstoresi_eq0_thumb1_insn}
     (expr_list:REG_UNUSED (reg:SI 129)
        (nil)))
(insn 20 19 22 2 (set (reg:SI 135)
        (plus:SI (plus:SI (reg:SI 136)
                (reg:SI 137))
            (geu:SI (reg:SI 131 [ D.4914 ])
                (reg:SI 134 [ c ])))) x.c:23 764 {thumb1_addsi3_addgeu}
     (expr_list:REG_DEAD (reg:SI 137)
        (expr_list:REG_DEAD (reg:SI 136)
            (expr_list:REG_DEAD (reg:SI 134 [ c ])
                (expr_list:REG_DEAD (reg:SI 131 [ D.4914 ])
                    (nil))))))
(insn 22 20 23 2 (set (reg:SI 138)
        (minus:SI (reg:SI 128)
            (reg:SI 135))) x.c:23 720 {thumb1_subsi3_insn}
     (expr_list:REG_DEAD (reg:SI 135)
        (expr_list:REG_DEAD (reg:SI 128)
            (nil))))

After the reload pass, those instructions are wrongly turned into:
(insn 20 53 58 2 (set (reg:SI 3 r3 [135])
        (plus:SI (plus:SI (reg:SI 3 r3 [137])
                (reg:SI 2 r2 [136]))
            (geu:SI (reg:SI 7 r7 [orig:131 D.4914 ] [131])
                (reg:SI 6 r6 [153])))) x.c:23 764 {thumb1_addsi3_addgeu}
     (nil))
(insn 58 20 55 2 (parallel [
            (set (reg:SI 2 r2 [128])
                (eq:SI (reg:SI 0 r0 [orig:110 D.4914 ] [110])
                    (const_int 0 [0])))
            (clobber (reg:SI 3 r3 [129]))
        ]) x.c:23 760 {*cstoresi_eq0_thumb1_insn}
     (nil))
(note 55 58 22 2 NOTE_INSN_DELETED)
(insn 22 55 23 2 (set (reg:SI 3 r3 [138])
        (minus:SI (reg:SI 2 r2 [128])
            (reg:SI 3 r3 [135]))) x.c:23 720 {thumb1_subsi3_insn}
     (nil))

However the later pass can recognize the clobber in insn 58 and will remove the
insn 20 because the r3 defined in insn 20 is clobbered by insn 58.

Reply via email to