From: Jakub Jelinek Date: Tue, 3 Dec 2013 07:29:20 +0000 (+0100) Subject: re PR target/58864 (ICE in connect_traces, at dwarf2cfi.c:NNNN) X-Git-Tag: releases/gcc-4.9.0~2318 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7f2f0a01cab6028542bdd57904a4147d17292d74;p=thirdparty%2Fgcc.git re PR target/58864 (ICE in connect_traces, at dwarf2cfi.c:NNNN) PR target/58864 * dojump.c (save_pending_stack_adjust, restore_pending_stack_adjust): New functions. * expr.h (struct saved_pending_stack_adjust): New type. (save_pending_stack_adjust, restore_pending_stack_adjust): New prototypes. * optabs.c (emit_conditional_move): Call save_pending_stack_adjust and get_last_insn before do_pending_stack_adjust, call restore_pending_stack_adjust after delete_insns_since. * expr.c (expand_expr_real_2): Don't call do_pending_stack_adjust before calling emit_conditional_move. * expmed.c (expand_sdiv_pow2): Likewise. * calls.c (expand_call): Use {save,restore}_pending_stack_adjust. * g++.dg/opt/pr58864.C: New test. From-SVN: r205618 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a9202c7fc916..f003eb1ed248 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2013-12-03 Jakub Jelinek + + PR target/58864 + * dojump.c (save_pending_stack_adjust, restore_pending_stack_adjust): + New functions. + * expr.h (struct saved_pending_stack_adjust): New type. + (save_pending_stack_adjust, restore_pending_stack_adjust): New + prototypes. + * optabs.c (emit_conditional_move): Call save_pending_stack_adjust + and get_last_insn before do_pending_stack_adjust, call + restore_pending_stack_adjust after delete_insns_since. + * expr.c (expand_expr_real_2): Don't call do_pending_stack_adjust + before calling emit_conditional_move. + * expmed.c (expand_sdiv_pow2): Likewise. + * calls.c (expand_call): Use {save,restore}_pending_stack_adjust. + 2013-12-02 Jeff Law PR tree-optimization/59322 diff --git a/gcc/calls.c b/gcc/calls.c index aaba8b983a7e..7d6327f28eff 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -2672,8 +2672,7 @@ expand_call (tree exp, rtx target, int ignore) recursion "call". That way we know any adjustment after the tail recursion call can be ignored if we indeed use the tail call expansion. */ - int save_pending_stack_adjust = 0; - int save_stack_pointer_delta = 0; + saved_pending_stack_adjust save; rtx insns; rtx before_call, next_arg_reg, after_args; @@ -2681,8 +2680,7 @@ expand_call (tree exp, rtx target, int ignore) { /* State variables we need to save and restore between iterations. */ - save_pending_stack_adjust = pending_stack_adjust; - save_stack_pointer_delta = stack_pointer_delta; + save_pending_stack_adjust (&save); } if (pass) flags &= ~ECF_SIBCALL; @@ -3438,8 +3436,7 @@ expand_call (tree exp, rtx target, int ignore) /* Restore the pending stack adjustment now that we have finished generating the sibling call sequence. */ - pending_stack_adjust = save_pending_stack_adjust; - stack_pointer_delta = save_stack_pointer_delta; + restore_pending_stack_adjust (&save); /* Prepare arg structure for next iteration. */ for (i = 0; i < num_actuals; i++) diff --git a/gcc/dojump.c b/gcc/dojump.c index 2aef34d307a5..73df6d163d5a 100644 --- a/gcc/dojump.c +++ b/gcc/dojump.c @@ -96,6 +96,29 @@ do_pending_stack_adjust (void) pending_stack_adjust = 0; } } + +/* Remember pending_stack_adjust/stack_pointer_delta. + To be used around code that may call do_pending_stack_adjust (), + but the generated code could be discarded e.g. using delete_insns_since. */ + +void +save_pending_stack_adjust (saved_pending_stack_adjust *save) +{ + save->x_pending_stack_adjust = pending_stack_adjust; + save->x_stack_pointer_delta = stack_pointer_delta; +} + +/* Restore the saved pending_stack_adjust/stack_pointer_delta. */ + +void +restore_pending_stack_adjust (saved_pending_stack_adjust *save) +{ + if (inhibit_defer_pop == 0) + { + pending_stack_adjust = save->x_pending_stack_adjust; + stack_pointer_delta = save->x_stack_pointer_delta; + } +} /* Expand conditional expressions. */ diff --git a/gcc/expmed.c b/gcc/expmed.c index c5123cbbe81c..8e63cd5b5c57 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -3736,11 +3736,6 @@ expand_sdiv_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d) { rtx temp2; - /* ??? emit_conditional_move forces a stack adjustment via - compare_from_rtx so, if the sequence is discarded, it will - be lost. Do it now instead. */ - do_pending_stack_adjust (); - start_sequence (); temp2 = copy_to_mode_reg (mode, op0); temp = expand_binop (mode, add_optab, temp2, gen_int_mode (d - 1, mode), diff --git a/gcc/expr.c b/gcc/expr.c index c0539da250c9..4e0e54f25b5a 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -8801,12 +8801,6 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, { rtx insn; - /* ??? Same problem as in expmed.c: emit_conditional_move - forces a stack adjustment via compare_from_rtx, and we - lose the stack adjustment if the sequence we are about - to create is discarded. */ - do_pending_stack_adjust (); - start_sequence (); /* Try to emit the conditional move. */ diff --git a/gcc/expr.h b/gcc/expr.h index a2cd6690bfe7..e734ef440168 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -473,6 +473,28 @@ extern void clear_pending_stack_adjust (void); /* Pop any previously-pushed arguments that have not been popped yet. */ extern void do_pending_stack_adjust (void); +/* Struct for saving/restoring of pending_stack_adjust/stack_pointer_delta + values. */ + +struct saved_pending_stack_adjust +{ + /* Saved value of pending_stack_adjust. */ + int x_pending_stack_adjust; + + /* Saved value of stack_pointer_delta. */ + int x_stack_pointer_delta; +}; + +/* Remember pending_stack_adjust/stack_pointer_delta. + To be used around code that may call do_pending_stack_adjust (), + but the generated code could be discarded e.g. using delete_insns_since. */ + +extern void save_pending_stack_adjust (saved_pending_stack_adjust *); + +/* Restore the saved pending_stack_adjust/stack_pointer_delta. */ + +extern void restore_pending_stack_adjust (saved_pending_stack_adjust *); + /* Return the tree node and offset if a given argument corresponds to a string constant. */ extern tree string_constant (tree, tree *); diff --git a/gcc/optabs.c b/gcc/optabs.c index dcef4809d8b3..e035af18c612 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -4566,8 +4566,10 @@ emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1, if (!COMPARISON_P (comparison)) return NULL_RTX; - do_pending_stack_adjust (); + saved_pending_stack_adjust save; + save_pending_stack_adjust (&save); last = get_last_insn (); + do_pending_stack_adjust (); prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1), GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN, &comparison, &cmode); @@ -4587,6 +4589,7 @@ emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1, } } delete_insns_since (last); + restore_pending_stack_adjust (&save); return NULL_RTX; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 80490ced7a0d..5b7430605ffe 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,7 +1,12 @@ +2013-12-03 Jakub Jelinek + + PR target/58864 + * g++.dg/opt/pr58864.C: New test. + 2013-12-02 Jeff Law PR tree-optimization/59322 - * gcc.c-torture/compile/pr59322.c: New test + * gcc.c-torture/compile/pr59322.c: New test. 2013-12-02 Sriraman Tallam diff --git a/gcc/testsuite/g++.dg/opt/pr58864.C b/gcc/testsuite/g++.dg/opt/pr58864.C new file mode 100644 index 000000000000..b8587f298a05 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr58864.C @@ -0,0 +1,21 @@ +// PR target/58864 +// { dg-do compile } +// { dg-options "-Os" } +// { dg-additional-options "-march=i686" { target { { i?86-*-* x86_64-*-* } && ia32 } } } + +struct A { A (); ~A (); }; +struct B { B (); }; + +float d, e; + +void +foo () +{ + A a; + float c = d; + while (1) + { + B b; + e = c ? -c : 0; + } +}