diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 565ca5b105e..983c0924451 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2012-03-05 Richard Guenther + + 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. + 2012-03-05 Jakub Jelinek PR tree-optimization/51721 diff --git a/gcc/optabs.c b/gcc/optabs.c index fd353d7e627..565db428045 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 diff --git a/gcc/optabs.h b/gcc/optabs.h index 6ad6dae9ab6..70a7395cc05 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -1103,6 +1103,25 @@ set_direct_optab_handler (direct_optab op, enum machine_mode mode, op->handlers[(int) mode].insn_code = (int) code - (int) CODE_FOR_nothing; } +/* Return true if UNOPTAB is for a trapping-on-overflow operation. */ + +static inline bool +trapv_unoptab_p (optab unoptab) +{ + return (unoptab == negv_optab + || unoptab == absv_optab); +} + +/* Return true if BINOPTAB is for a trapping-on-overflow operation. */ + +static inline bool +trapv_binoptab_p (optab binoptab) +{ + return (binoptab == addv_optab + || binoptab == subv_optab + || binoptab == smulv_optab); +} + extern rtx optab_libfunc (optab optab, enum machine_mode mode); extern rtx convert_optab_libfunc (convert_optab optab, enum machine_mode mode1, enum machine_mode mode2);