On i386, peepholes that transform memory load and register-indirect jump into
memory-indirect jump are overly restrictive in that they don't allow combining
when the jump target is loaded into %eax, and the called function returns a
value (also in %eax, so it's not dead after the call).  Fix this by checking
for same source and output register operands separately.

OK?
        * config/i386/i386.md (sibcall_value_memory): Extend peepholes to
        allow memory address in %eax.
        (sibcall_value_pop_memory): Likewise.

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 729db75..7f81bcc 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -11872,13 +11872,14 @@
   [(set (match_operand:W 0 "register_operand")
        (match_operand:W 1 "memory_operand"))
    (set (match_operand 2)
    (call (mem:QI (match_dup 0))
                 (match_operand 3)))]
   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
-   && peep2_reg_dead_p (2, operands[0])"
+   && (REGNO (operands[2]) == REGNO (operands[0])
+       || peep2_reg_dead_p (2, operands[0]))"
   [(parallel [(set (match_dup 2)
                   (call (mem:QI (match_dup 1))
                         (match_dup 3)))
              (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
 
 (define_peephole2
@@ -11886,13 +11887,14 @@
        (match_operand:W 1 "memory_operand"))
    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
    (set (match_operand 2)
        (call (mem:QI (match_dup 0))
              (match_operand 3)))]
   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
-   && peep2_reg_dead_p (3, operands[0])"
+   && (REGNO (operands[2]) == REGNO (operands[0])
+       || peep2_reg_dead_p (3, operands[0]))"
   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
    (parallel [(set (match_dup 2)
                   (call (mem:QI (match_dup 1))
                         (match_dup 3)))
              (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
 
@@ -11951,13 +11953,14 @@
                   (call (mem:QI (match_dup 0))
                         (match_operand 3)))
              (set (reg:SI SP_REG)
                   (plus:SI (reg:SI SP_REG)
                            (match_operand:SI 4 "immediate_operand")))])]
   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
-   && peep2_reg_dead_p (2, operands[0])"
+   && (REGNO (operands[2]) == REGNO (operands[0])
+       || peep2_reg_dead_p (2, operands[0]))"
   [(parallel [(set (match_dup 2)
                   (call (mem:QI (match_dup 1))
                         (match_dup 3)))
              (set (reg:SI SP_REG)
                   (plus:SI (reg:SI SP_REG)
                            (match_dup 4)))
@@ -11971,13 +11974,14 @@
                   (call (mem:QI (match_dup 0))
                         (match_operand 3)))
              (set (reg:SI SP_REG)
                   (plus:SI (reg:SI SP_REG)
                            (match_operand:SI 4 "immediate_operand")))])]
   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
-   && peep2_reg_dead_p (3, operands[0])"
+   && (REGNO (operands[2]) == REGNO (operands[0])
+       || peep2_reg_dead_p (3, operands[0]))"
   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
    (parallel [(set (match_dup 2)
                   (call (mem:QI (match_dup 1))
                         (match_dup 3)))
              (set (reg:SI SP_REG)
                   (plus:SI (reg:SI SP_REG)

Reply via email to