diff options
author | Richard Guenther <rguenther@suse.de> | 2012-03-05 13:08:55 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2012-03-05 13:08:55 +0000 |
commit | b55f62ccae9766c687dea6afc60f701a4490b0f1 (patch) | |
tree | 42d3abf28617c05fdaa5e752dbc6b7ef735744cf /gcc/optabs.c | |
parent | 8dad8b259071a3b49d8ad0f08b7b0dba30b974c0 (diff) | |
download | gcc-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.c | 23 |
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 |