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
This commit is contained in:
parent
4dd0ef2765
commit
7f2f0a01ca
@ -1,3 +1,19 @@
|
|||||||
|
2013-12-03 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
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 <law@redhat.com>
|
2013-12-02 Jeff Law <law@redhat.com>
|
||||||
|
|
||||||
PR tree-optimization/59322
|
PR tree-optimization/59322
|
||||||
|
@ -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". That way we know any adjustment after the tail
|
||||||
recursion call can be ignored if we indeed use the tail
|
recursion call can be ignored if we indeed use the tail
|
||||||
call expansion. */
|
call expansion. */
|
||||||
int save_pending_stack_adjust = 0;
|
saved_pending_stack_adjust save;
|
||||||
int save_stack_pointer_delta = 0;
|
|
||||||
rtx insns;
|
rtx insns;
|
||||||
rtx before_call, next_arg_reg, after_args;
|
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
|
/* State variables we need to save and restore between
|
||||||
iterations. */
|
iterations. */
|
||||||
save_pending_stack_adjust = pending_stack_adjust;
|
save_pending_stack_adjust (&save);
|
||||||
save_stack_pointer_delta = stack_pointer_delta;
|
|
||||||
}
|
}
|
||||||
if (pass)
|
if (pass)
|
||||||
flags &= ~ECF_SIBCALL;
|
flags &= ~ECF_SIBCALL;
|
||||||
@ -3438,8 +3436,7 @@ expand_call (tree exp, rtx target, int ignore)
|
|||||||
/* Restore the pending stack adjustment now that we have
|
/* Restore the pending stack adjustment now that we have
|
||||||
finished generating the sibling call sequence. */
|
finished generating the sibling call sequence. */
|
||||||
|
|
||||||
pending_stack_adjust = save_pending_stack_adjust;
|
restore_pending_stack_adjust (&save);
|
||||||
stack_pointer_delta = save_stack_pointer_delta;
|
|
||||||
|
|
||||||
/* Prepare arg structure for next iteration. */
|
/* Prepare arg structure for next iteration. */
|
||||||
for (i = 0; i < num_actuals; i++)
|
for (i = 0; i < num_actuals; i++)
|
||||||
|
23
gcc/dojump.c
23
gcc/dojump.c
@ -96,6 +96,29 @@ do_pending_stack_adjust (void)
|
|||||||
pending_stack_adjust = 0;
|
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. */
|
/* Expand conditional expressions. */
|
||||||
|
|
||||||
|
@ -3736,11 +3736,6 @@ expand_sdiv_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d)
|
|||||||
{
|
{
|
||||||
rtx temp2;
|
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 ();
|
start_sequence ();
|
||||||
temp2 = copy_to_mode_reg (mode, op0);
|
temp2 = copy_to_mode_reg (mode, op0);
|
||||||
temp = expand_binop (mode, add_optab, temp2, gen_int_mode (d - 1, mode),
|
temp = expand_binop (mode, add_optab, temp2, gen_int_mode (d - 1, mode),
|
||||||
|
@ -8801,12 +8801,6 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
|
|||||||
{
|
{
|
||||||
rtx insn;
|
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 ();
|
start_sequence ();
|
||||||
|
|
||||||
/* Try to emit the conditional move. */
|
/* Try to emit the conditional move. */
|
||||||
|
22
gcc/expr.h
22
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. */
|
/* Pop any previously-pushed arguments that have not been popped yet. */
|
||||||
extern void do_pending_stack_adjust (void);
|
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
|
/* Return the tree node and offset if a given argument corresponds to
|
||||||
a string constant. */
|
a string constant. */
|
||||||
extern tree string_constant (tree, tree *);
|
extern tree string_constant (tree, tree *);
|
||||||
|
@ -4566,8 +4566,10 @@ emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
|
|||||||
if (!COMPARISON_P (comparison))
|
if (!COMPARISON_P (comparison))
|
||||||
return NULL_RTX;
|
return NULL_RTX;
|
||||||
|
|
||||||
do_pending_stack_adjust ();
|
saved_pending_stack_adjust save;
|
||||||
|
save_pending_stack_adjust (&save);
|
||||||
last = get_last_insn ();
|
last = get_last_insn ();
|
||||||
|
do_pending_stack_adjust ();
|
||||||
prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
|
prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
|
||||||
GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
|
GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
|
||||||
&comparison, &cmode);
|
&comparison, &cmode);
|
||||||
@ -4587,6 +4589,7 @@ emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete_insns_since (last);
|
delete_insns_since (last);
|
||||||
|
restore_pending_stack_adjust (&save);
|
||||||
return NULL_RTX;
|
return NULL_RTX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
|
2013-12-03 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR target/58864
|
||||||
|
* g++.dg/opt/pr58864.C: New test.
|
||||||
|
|
||||||
2013-12-02 Jeff Law <law@redhat.com>
|
2013-12-02 Jeff Law <law@redhat.com>
|
||||||
|
|
||||||
PR tree-optimization/59322
|
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 <tmsriram@google.com>
|
2013-12-02 Sriraman Tallam <tmsriram@google.com>
|
||||||
|
|
||||||
|
21
gcc/testsuite/g++.dg/opt/pr58864.C
Normal file
21
gcc/testsuite/g++.dg/opt/pr58864.C
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user