+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
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;
{
/* 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;
/* 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++)
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;
+ }
+}
\f
/* Expand conditional expressions. */
{
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),
{
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. */
/* 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 *);
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);
}
}
delete_insns_since (last);
+ restore_pending_stack_adjust (&save);
return NULL_RTX;
}
+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>
--- /dev/null
+// 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;
+ }
+}