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

            Bug ID: 78617
           Summary: LRA clobbers live register during rematerialization
           Product: gcc
           Version: 6.2.1
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: thopre01 at gcc dot gnu.org
  Target Milestone: ---
            Target: arm-none-eabi

Created attachment 40208
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40208&action=edit
Testcase showing wrong rematerialization in LRA at -Os for ARMv6-M

Hi,

The attached code prints the wrong value when compiled by GCC 6 with
-march=armv6-m -mthumb pr78xxx.c -Os: it prints 0 instead of 1. The issue is in
the code generated for fn4 and gets wrong at LRA. See the code after LRA
corresponding to bitwise OR, inlined fn2 call and the comparison with !d:

(insn 46 17 18 2 (set (reg:SI 3 r3 [orig:110 D.5240 ] [110])
        (const_int 1 [0x1])) pr78xxx.c:20 744 {*thumb1_movsi_insn}
     (expr_list:REG_EQUAL (const_int 1 [0x1])
        (nil)))
(jump_insn 18 46 19 2 (set (pc)
        (if_then_else (ne (reg:SI 0 r0 [orig:115 D.5240 ] [115])
                (const_int 0 [0]))
            (label_ref:SI 22)
            (pc))) pr78xxx.c:20 753 {cbranchsi4_insn}
     (int_list:REG_BR_PROB 5000 (nil))
 -> 22)
(note 19 18 20 3 [bb 3] NOTE_INSN_BASIC_BLOCK)
(note 20 19 82 3 NOTE_INSN_DELETED)
(insn 82 20 21 3 (set (reg/v:SI 3 r3 [orig:122 p2 ] [122])
        (reg/v:SI 5 r5 [orig:122 p2 ] [122])) pr78xxx.c:20 744
{*thumb1_movsi_insn}
     (nil))
(insn 21 82 22 3 (parallel [
            (set (reg/v:SI 3 r3 [orig:122 p2 ] [122])
                (ne:SI (reg/v:SI 3 r3 [orig:122 p2 ] [122])
                    (const_int 0 [0])))
            (clobber (reg:SI 5 r5 [130]))
        ]) pr78xxx.c:20 764 {*cstoresi_ne0_thumb1_insn}
     (nil))
(code_label 22 21 23 4 10 "" [1 uses])
(note 23 22 24 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
(jump_insn 24 23 25 4 (set (pc)
        (if_then_else (gt (reg/v:SI 7 r7 [orig:121 p1 ] [121])
                (const_int 1 [0x1]))
            (label_ref 26)
            (pc))) pr78xxx.c:12 753 {cbranchsi4_insn}
     (int_list:REG_BR_PROB 6335 (nil))
 -> 26)
(note 25 24 6 5 [bb 5] NOTE_INSN_BASIC_BLOCK)
(insn 6 25 26 5 (set (reg:SI 3 r3 [orig:110 D.5240 ] [110])
        (const_int 0 [0])) pr78xxx.c:12 744 {*thumb1_movsi_insn}
     (nil))
(code_label 26 6 27 6 11 "" [1 uses])
(note 27 26 48 6 [bb 6] NOTE_INSN_BASIC_BLOCK)
(insn 48 27 86 6 (set (reg:SI 0 r0 [orig:132 D.5241 ] [132])
        (const_int 1 [0x1])) pr78xxx.c:20 744 {*thumb1_movsi_insn}
     (expr_list:REG_EQUAL (const_int 1 [0x1])
        (nil)))
(insn 86 48 84 6 (parallel [
            (set (reg:SI 2 r2 [orig:125 D.5241 ] [125])
                (eq:SI (reg:SI 4 r4 [orig:111 D.5240 ] [111])
                    (const_int 0 [0])))
            (clobber (reg:SI 3 r3 [126]))
        ]) pr78xxx.c:20 763 {*cstoresi_eq0_thumb1_insn}
     (nil))
(note 84 86 29 6 NOTE_INSN_DELETED)
(jump_insn 29 84 44 6 (set (pc)
        (if_then_else (gt (reg:SI 2 r2 [orig:125 D.5241 ] [125])
                (reg:SI 3 r3 [orig:110 D.5240 ] [110]))
            (label_ref 31)
            (pc))) pr78xxx.c:20 753 {cbranchsi4_insn}
     (int_list:REG_BR_PROB 5000 (nil))
 -> 31)


We can see that !d is rematerialized in instruction 86 but that
rematerialization clobbers r3 which is used by jump instruction 29. Before LRA
instruction 86 does not exist and jump instruction 29 uses a computation of !d
done early in the function.

Note that GCC 7 works since commit r239421 but only because the code that get
fed to LRA is different and thus the bug is not triggered.

Reply via email to