From: Uros Bizjak Date: Sun, 23 Aug 2009 13:03:39 +0000 (+0200) Subject: re PR target/40718 (Invalid code produced with -foptimize-sibling-calls) X-Git-Tag: releases/gcc-4.3.5~418 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c7fb0a98622c0b914f9a35d2e0d0c1fd4bfca2c6;p=thirdparty%2Fgcc.git re PR target/40718 (Invalid code produced with -foptimize-sibling-calls) PR target/40718 * config/i386/i386.c (*call_pop_1): Disable for sibling calls. (*call_value_pop_1): Ditto. (*sibcall_pop_1): New insn pattern. (*sibcall_value_pop_1): Ditto. testsuite/ChangeLog: PR target/40718 * gcc.target/i386/pr40718.c: New test. From-SVN: r151033 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eb8c7d017921..ee1b3f6a5923 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2009-08-23 Uros Bizjak + + PR target/40718 + * config/i386/i386.c (*call_pop_1): Disable for sibling calls. + (*call_value_pop_1): Ditto. + (*sibcall_pop_1): New insn pattern. + (*sibcall_value_pop_1): Ditto. + 2009-08-16 Uros Bizjak Backport from mainline: diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 1053d47e4b53..2c6b3a3d3c5a 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -14687,19 +14687,24 @@ (match_operand:SI 1 "" "")) (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_operand:SI 2 "immediate_operand" "i")))] - "!TARGET_64BIT" + "!SIBLING_CALL_P (insn) && !TARGET_64BIT" { if (constant_call_address_operand (operands[0], Pmode)) - { - if (SIBLING_CALL_P (insn)) - return "jmp\t%P0"; - else - return "call\t%P0"; - } - if (SIBLING_CALL_P (insn)) - return "jmp\t%A0"; - else - return "call\t%A0"; + return "call\t%P0"; + return "call\t%A0"; +} + [(set_attr "type" "call")]) + +(define_insn "*sibcall_pop_1" + [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a")) + (match_operand:SI 1 "" "")) + (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) + (match_operand:SI 2 "immediate_operand" "i,i,i,i")))] + "SIBLING_CALL_P (insn) && !TARGET_64BIT" +{ + if (constant_call_address_operand (operands[0], Pmode)) + return "jmp\t%P0"; + return "jmp\t%A0"; } [(set_attr "type" "call")]) @@ -21064,19 +21069,25 @@ (match_operand:SI 2 "" ""))) (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_operand:SI 3 "immediate_operand" "i")))] - "!TARGET_64BIT" + "!SIBLING_CALL_P (insn) && !TARGET_64BIT" { if (constant_call_address_operand (operands[1], Pmode)) - { - if (SIBLING_CALL_P (insn)) - return "jmp\t%P1"; - else - return "call\t%P1"; - } - if (SIBLING_CALL_P (insn)) - return "jmp\t%A1"; - else - return "call\t%A1"; + return "call\t%P1"; + return "call\t%A1"; +} + [(set_attr "type" "callv")]) + +(define_insn "*sibcall_value_pop_1" + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a")) + (match_operand:SI 2 "" ""))) + (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) + (match_operand:SI 3 "immediate_operand" "i,i,i,i")))] + "SIBLING_CALL_P (insn) && !TARGET_64BIT" +{ + if (constant_call_address_operand (operands[1], Pmode)) + return "jmp\t%P1"; + return "jmp\t%A1"; } [(set_attr "type" "callv")]) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f5dc05aa58ac..991ca592c551 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-08-23 Uros Bizjak + + PR target/40718 + * gcc.target/i386/pr40718.c: New test. + 2009-08-16 Uros Bizjak Backport from mainline: diff --git a/gcc/testsuite/gcc.target/i386/pr40718.c b/gcc/testsuite/gcc.target/i386/pr40718.c new file mode 100644 index 000000000000..f6029ed98ab7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr40718.c @@ -0,0 +1,36 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-options "-O1 -foptimize-sibling-calls" } */ + +void abort (void); + +struct S +{ + void (__attribute__((__stdcall__)) *f) (struct S *); + int i; +}; + +void __attribute__((__stdcall__)) +foo (struct S *s) +{ + s->i++; +} + +void __attribute__((__stdcall__)) +bar (struct S *s) +{ + foo(s); + s->f(s); +} + +int main (void) +{ + struct S s = { foo, 0 }; + + bar (&s); + if (s.i != 2) + abort (); + + return 0; +} +