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

2019-04-10 Thread segher at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89794

Segher Boessenkool  changed:

   What|Removed |Added

 Status|NEW |ASSIGNED
   Assignee|unassigned at gcc dot gnu.org  |segher at gcc dot 
gnu.org

--- Comment #7 from Segher Boessenkool  ---
I have a patch.

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

2019-04-09 Thread rearnsha at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89794

--- Comment #6 from Richard Earnshaw  ---
There seems to be more to this than initially thought.  Another insn is in
play.

(insn 12 10 14 2 (set (reg:SI 129)
(bswap:SI (subreg:SI (reg:DI 127 [ i ]) 4))) "/tmp/test3.c":10:7 331
{*arm_rev}
 (expr_list:REG_DEAD (reg:DI 127 [ i ])
(nil)))

Which uses the value loaded by the pre-modify instruction.

Combine manages to combine (and simplify insns 10 and 12, but the
simplification is to

(set (reg:SI 129) (const_int 0))

and we've lost the pre-inc entirely.

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

2019-04-09 Thread rearnsha at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89794

Richard Earnshaw  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  ---
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 *)]+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 *)]+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 *)]+0 S2 A16])
(subreg:HI (reg:SI 140) 0))

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