aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2012-03-05 13:08:55 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2012-03-05 13:08:55 +0000
commitb55f62ccae9766c687dea6afc60f701a4490b0f1 (patch)
tree42d3abf28617c05fdaa5e752dbc6b7ef735744cf /gcc/optabs.c
parent8dad8b259071a3b49d8ad0f08b7b0dba30b974c0 (diff)
downloadgcc-b55f62ccae9766c687dea6afc60f701a4490b0f1.zip
gcc-b55f62ccae9766c687dea6afc60f701a4490b0f1.tar.gz
gcc-b55f62ccae9766c687dea6afc60f701a4490b0f1.tar.bz2
re PR middle-end/52353 (-ftrapv -fnon-call-exceptions does not work)
2012-03-05 Richard Guenther <rguenther@suse.de> PR middle-end/52353 * optabs.h (trapv_unoptab_p): New function. (trapv_binoptab_p): Likewise. * optabs.c (expand_binop): Use emit_libcall_block_1 with a proper equiv_may_trap argument. (expand_unop): Likewise. (emit_libcall_block_1): Take extra argument whether the instruction may trap. Renamed from ... (emit_libcall_block): ... this. New wrapper. From-SVN: r184932
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r--gcc/optabs.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index fd353d7..565db42 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -60,6 +60,7 @@ optab code_to_optab[NUM_RTX_CODE + 1];
static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
enum machine_mode *);
static rtx expand_unop_direct (enum machine_mode, optab, rtx, rtx, int);
+static void emit_libcall_block_1 (rtx, rtx, rtx, rtx, bool);
/* Debug facility for use in GDB. */
void debug_optab_libfuncs (void);
@@ -2115,8 +2116,9 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
end_sequence ();
target = gen_reg_rtx (mode);
- emit_libcall_block (insns, target, value,
- gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
+ emit_libcall_block_1 (insns, target, value,
+ gen_rtx_fmt_ee (binoptab->code, mode, op0, op1),
+ trapv_binoptab_p (binoptab));
return target;
}
@@ -3197,7 +3199,8 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
else if (GET_MODE_SIZE (outmode) > GET_MODE_SIZE (mode))
eq_value = simplify_gen_unary (ZERO_EXTEND, outmode, eq_value, mode);
- emit_libcall_block (insns, target, value, eq_value);
+ emit_libcall_block_1 (insns, target, value, eq_value,
+ trapv_unoptab_p (unoptab));
return target;
}
@@ -3775,8 +3778,9 @@ no_conflict_move_test (rtx dest, const_rtx set, void *p0)
an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
note with an operand of EQUIV. */
-void
-emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
+static void
+emit_libcall_block_1 (rtx insns, rtx target, rtx result, rtx equiv,
+ bool equiv_may_trap)
{
rtx final_dest = target;
rtx next, last, insn;
@@ -3789,7 +3793,8 @@ emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
/* If we're using non-call exceptions, a libcall corresponding to an
operation that may trap may also trap. */
/* ??? See the comment in front of make_reg_eh_region_note. */
- if (cfun->can_throw_non_call_exceptions && may_trap_p (equiv))
+ if (cfun->can_throw_non_call_exceptions
+ && (equiv_may_trap || may_trap_p (equiv)))
{
for (insn = insns; insn; insn = NEXT_INSN (insn))
if (CALL_P (insn))
@@ -3870,6 +3875,12 @@ emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
if (final_dest != target)
emit_move_insn (final_dest, target);
}
+
+void
+emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
+{
+ emit_libcall_block_1 (insns, target, result, equiv, false);
+}
/* Nonzero if we can perform a comparison of mode MODE straightforwardly.
PURPOSE describes how this comparison will be used. CODE is the rtx