aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@gcc.gnu.org>2013-12-03 08:29:20 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2013-12-03 08:29:20 +0100
commit7f2f0a01cab6028542bdd57904a4147d17292d74 (patch)
tree4a5227f73abdd560a3d6b712c6c89fc4768357e7 /gcc
parent4dd0ef2765ed87adce1dadc3187d6f7bd7ff29bb (diff)
downloadgcc-7f2f0a01cab6028542bdd57904a4147d17292d74.zip
gcc-7f2f0a01cab6028542bdd57904a4147d17292d74.tar.gz
gcc-7f2f0a01cab6028542bdd57904a4147d17292d74.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/calls.c9
-rw-r--r--gcc/dojump.c23
-rw-r--r--gcc/expmed.c5
-rw-r--r--gcc/expr.c6
-rw-r--r--gcc/expr.h22
-rw-r--r--gcc/optabs.c5
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/opt/pr58864.C21
9 files changed, 95 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a9202c7..f003eb1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
PR tree-optimization/59322
diff --git a/gcc/calls.c b/gcc/calls.c
index aaba8b9..7d6327f 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 2aef34d..73df6d1 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 c5123cb..8e63cd5 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 c0539da..4e0e54f 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 a2cd669..e734ef4 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 dcef480..e035af1 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 80490ce..5b74306 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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>
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>
diff --git a/gcc/testsuite/g++.dg/opt/pr58864.C b/gcc/testsuite/g++.dg/opt/pr58864.C
new file mode 100644
index 0000000..b8587f2
--- /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;
+ }
+}