From: Alexander Monakov Date: Thu, 14 May 2015 17:43:28 +0000 (+0300) Subject: i386.md (sibcall_memory): Check that register with callee address is not also used... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f226d22967576772030669a06d5bea73a5802d2f;p=gcc.git i386.md (sibcall_memory): Check that register with callee address is not also used as one of the arguments... * 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. * gcc.target/i386/sibcall-8.c: New test. From-SVN: r223201 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f41771ee24b..97aa0ebe341 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2015-05-14 Alexander Monakov + + * 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. + 2015-05-14 Marc Glisse * generic-match-head.c (types_match): Handle non-types. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 7bec509f48c..aefca43c450 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -11680,7 +11680,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)])]) @@ -11692,7 +11693,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)) @@ -11751,7 +11753,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) @@ -11769,7 +11772,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)) @@ -11845,7 +11849,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))) @@ -11859,7 +11864,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)) @@ -11924,7 +11930,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))) @@ -11944,7 +11951,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/ChangeLog b/gcc/testsuite/ChangeLog index 504dc075ef1..2d48683d6f1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-05-14 Alexander Monakov + + * gcc.target/i386/sibcall-7.c: New test. + * gcc.target/i386/sibcall-8.c: New test. + 2015-05-14 Wilco Dijkstra * gcc.target/aarch64/abs_1.c (abs64): Update test for new abs expansion. @@ -97,7 +102,7 @@ PR tree-optimization/37021 * gcc.target/i386/vect-addsub.c: New testcase. -2015-05-11 Alexander Monakov +2015-05-12 Alexander Monakov * gcc.target/i386/pr65753.c: Use -O2 instead of -O. diff --git a/gcc/testsuite/gcc.target/i386/sibcall-7.c b/gcc/testsuite/gcc.target/i386/sibcall-7.c new file mode 100644 index 00000000000..6effb8f8256 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sibcall-7.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target { ! x32 } } } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-not "mov" } } */ + +int foo() +{ + int (**bar)(void); + asm("":"=a"(bar)); + return (*bar)(); +} diff --git a/gcc/testsuite/gcc.target/i386/sibcall-8.c b/gcc/testsuite/gcc.target/i386/sibcall-8.c new file mode 100644 index 00000000000..3ab3809036d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sibcall-8.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +extern void abort (void); + +static int __attribute__((regparm(1))) +bar(void *arg) +{ + return arg != bar; +} + +static int __attribute__((noinline,noclone,regparm(1))) +foo(int (__attribute__((regparm(1))) **bar)(void*)) +{ + return (*bar)(*bar); +} + +int main() +{ + int (__attribute__((regparm(1))) *p)(void*) = bar; + if (foo(&p)) + abort(); + return 0; +}