[Bug target/89794] combine incorrectly forwards register value through auto-inc operation

rearnsha at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Apr 9 16:03:00 GMT 2019


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

Richard Earnshaw <rearnsha at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |segher at gcc dot gnu.org
            Summary|wrong code with -Og         |combine incorrectly
                   |-fno-forward-propagate      |forwards register value
                   |                            |through auto-inc operation

--- Comment #5 from Richard Earnshaw <rearnsha at gcc dot gnu.org> ---
This appears to be combine missing a PRE_MODIFY operation.

After expand we have:

(insn 10 7 11 2 (set (reg:DI 127)
        (zero_extend:DI (mem/c:HI (plus:SI (reg/f:SI 103 afp)
                    (const_int 8 [0x8])) [1 i+0 S2 A32]))) "/tmp/test3.c":10:7
160 {zero_extendhidi2}
     (nil))
...
(insn 24 23 25 2 (set (reg:SI 133)
        (plus:SI (reg/f:SI 103 afp)
            (const_int 8 [0x8]))) "/tmp/test3.c":12:3 4 {*arm_addsi3}
     (nil))
...
(insn 33 32 34 2 (set (mem/c:HI (reg:SI 133) [0 MEM[(void *)&i]+0 S2 A16])
        (reg:HI 141)) "/tmp/test3.c":12:3 189 {*movhi_insn_arch4}
     (nil))

The auto-inc-dec pass transforms this into:

(insn 50 7 10 2 (set (reg/f:SI 133)
        (reg/f:SI 103 afp)) "/tmp/test3.c":10:7 -1
     (nil))
(insn 10 50 12 2 (set (reg:DI 127 [ i ])
        (zero_extend:DI (mem/c:HI (pre_modify:SI (reg/f:SI 133)
                    (plus:SI (reg/f:SI 133)
                        (const_int 8 [0x8]))) [1 i+0 S2 A32])))
"/tmp/test3.c":10:7 160 {zero_extendhidi2}
     (expr_list:REG_INC (reg/f:SI 133)
        (nil)))
...
(insn 33 49 34 2 (set (mem/c:HI (reg/f:SI 133) [0 MEM[(void *)&i]+0 S2 A16])
        (subreg:HI (reg:SI 140) 0)) "/tmp/test3.c":12:3 189 {*movhi_insn_arch4}
     (expr_list:REG_DEAD (reg:SI 140)
        (expr_list:REG_DEAD (reg/f:SI 133)
            (nil))))

And combine, missing the pre_modify, then substitutes insn 50 directly into
insn 33

Trying 50 -> 33:
   50: r133:SI=afp:SI
   33: [r133:SI]=r140:SI#0
      REG_DEAD r140:SI
      REG_DEAD r133:SI
Successfully matched this instruction:
(set (mem/c:HI (reg/f:SI 103 afp) [0 MEM[(void *)&i]+0 S2 A16])
    (subreg:HI (reg:SI 140) 0))

Which is clearly wrong as it has now lost the pre-modify operation.


More information about the Gcc-bugs mailing list