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" } } */