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
This commit is contained in:
Richard Guenther 2012-03-05 13:08:55 +00:00 committed by Richard Biener
parent 8dad8b2590
commit b55f62ccae
3 changed files with 48 additions and 6 deletions

View File

@ -1,3 +1,15 @@
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.
2012-03-05 Jakub Jelinek <jakub@redhat.com> 2012-03-05 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/51721 PR tree-optimization/51721

View File

@ -60,6 +60,7 @@ optab code_to_optab[NUM_RTX_CODE + 1];
static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *, static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
enum machine_mode *); enum machine_mode *);
static rtx expand_unop_direct (enum machine_mode, optab, rtx, rtx, int); 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. */ /* Debug facility for use in GDB. */
void debug_optab_libfuncs (void); void debug_optab_libfuncs (void);
@ -2115,8 +2116,9 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
end_sequence (); end_sequence ();
target = gen_reg_rtx (mode); target = gen_reg_rtx (mode);
emit_libcall_block (insns, target, value, emit_libcall_block_1 (insns, target, value,
gen_rtx_fmt_ee (binoptab->code, mode, op0, op1)); gen_rtx_fmt_ee (binoptab->code, mode, op0, op1),
trapv_binoptab_p (binoptab));
return target; 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); eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
else if (GET_MODE_SIZE (outmode) > GET_MODE_SIZE (mode)) else if (GET_MODE_SIZE (outmode) > GET_MODE_SIZE (mode))
eq_value = simplify_gen_unary (ZERO_EXTEND, outmode, eq_value, 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; 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 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
note with an operand of EQUIV. */ note with an operand of EQUIV. */
void static void
emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv) emit_libcall_block_1 (rtx insns, rtx target, rtx result, rtx equiv,
bool equiv_may_trap)
{ {
rtx final_dest = target; rtx final_dest = target;
rtx next, last, insn; 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 /* If we're using non-call exceptions, a libcall corresponding to an
operation that may trap may also trap. */ operation that may trap may also trap. */
/* ??? See the comment in front of make_reg_eh_region_note. */ /* ??? 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)) for (insn = insns; insn; insn = NEXT_INSN (insn))
if (CALL_P (insn)) if (CALL_P (insn))
@ -3870,6 +3875,12 @@ emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
if (final_dest != target) if (final_dest != target)
emit_move_insn (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. /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
PURPOSE describes how this comparison will be used. CODE is the rtx PURPOSE describes how this comparison will be used. CODE is the rtx

View File

@ -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; 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 optab_libfunc (optab optab, enum machine_mode mode);
extern rtx convert_optab_libfunc (convert_optab optab, enum machine_mode mode1, extern rtx convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
enum machine_mode mode2); enum machine_mode mode2);