On Mon, 11 May 2015, Jan Hubicka wrote:
> Yes, to make my original email clear, I think we are safe to remove
> peep2_reg_dead_p.
>
> I would however introduce a check that the call target is not also among
> parameters of the function. In this case the peephole would remove the load
> and make the parameter unefined.
>
> While current mainline don't seem to be able to translate the testcase above
> that way, perhaps future improvements to LRA/postreload gcse may make it
> happen
> and generally RTL patterns are better to be safe by definition not
> only for the actual RTL we are able to generate. I suppose reg_mentioned_p
> on call usage is enough.
Thanks. I have bootstrapped and regtested the following patch. OK?
* config/i386/i386.md (sibcall_memory): Check that register with
callee address is not also used as one of the arguments, instead
of checking that it is not live after the sibcall.
(sibcall_pop_memory): Ditto.
(sibcall_value_memory): Ditto.
(sibcall_value_pop_memory): Ditto.
testsuite:
* gcc.target/i386/sibcall-7.c: New test.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 0959aef..9c1aa7d 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -11673,7 +11673,8 @@
(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])"
+ && !reg_mentioned_p (operands[0],
+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
[(parallel [(call (mem:QI (match_dup 1))
(match_dup 3))
(unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
@@ -11685,7 +11686,8 @@
(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])"
+ && !reg_mentioned_p (operands[0],
+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
(parallel [(call (mem:QI (match_dup 1))
(match_dup 3))
@@ -11744,7 +11746,8 @@
(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])"
+ && !reg_mentioned_p (operands[0],
+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
[(parallel [(call (mem:QI (match_dup 1))
(match_dup 3))
(set (reg:SI SP_REG)
@@ -11762,7 +11765,8 @@
(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])"
+ && !reg_mentioned_p (operands[0],
+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
(parallel [(call (mem:QI (match_dup 1))
(match_dup 3))
@@ -11838,7 +11842,8 @@
(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])"
+ && !reg_mentioned_p (operands[0],
+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
[(parallel [(set (match_dup 2)
(call (mem:QI (match_dup 1))
(match_dup 3)))
@@ -11852,7 +11857,8 @@
(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])"
+ && !reg_mentioned_p (operands[0],
+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
(parallel [(set (match_dup 2)
(call (mem:QI (match_dup 1))
@@ -11917,7 +11923,8 @@
(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])"
+ && !reg_mentioned_p (operands[0],
+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
[(parallel [(set (match_dup 2)
(call (mem:QI (match_dup 1))
(match_dup 3)))
@@ -11937,7 +11944,8 @@
(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])"
+ && !reg_mentioned_p (operands[0],
+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
(parallel [(set (match_dup 2)
(call (mem:QI (match_dup 1))
diff --git a/gcc/testsuite/gcc.target/i386/sibcall-7.c
b/gcc/testsuite/gcc.target/i386/sibcall-7.c
index e69de29..72fdaff 100644
--- a/gcc/testsuite/gcc.target/i386/sibcall-7.c
+++ b/gcc/testsuite/gcc.target/i386/sibcall-7.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target { { ! x32 } } } } */
+/* { dg-options "-O2" } */
+
+int foo()
+{
+ int (**bar)(void);
+ asm("":"=a"(bar));
+ return (*bar)();
+}
+
+/* { dg-final { scan-assembler-not "mov" } } */