Commit a51ca2f4 by Richard Biener Committed by Richard Biener

re PR middle-end/68046 (-ftrapv doesn't catch leaq-based overflows on x86-64)

2015-10-22  Richard Biener  <rguenther@suse.de>

	PR middle-end/68046
	PR middle-end/61893
	* optabs.c (emit_libcall_block_1): Allow a NULL_RTX equiv.
	(expand_binop): For -ftrapv optabs do not record an REG_EQUAL note.
	(expand_unop): Likewise.

	* gcc.dg/torture/ftrapv-2.c: New testcase.

From-SVN: r229170
parent 08e99efb
2015-10-22 Richard Biener <rguenther@suse.de> 2015-10-22 Richard Biener <rguenther@suse.de>
PR middle-end/68046
PR middle-end/61893
* optabs.c (emit_libcall_block_1): Allow a NULL_RTX equiv.
(expand_binop): For -ftrapv optabs do not record an REG_EQUAL note.
(expand_unop): Likewise.
2015-10-22 Richard Biener <rguenther@suse.de>
* fold-const.c (fold_addr_of_array_ref_difference): Properly * fold-const.c (fold_addr_of_array_ref_difference): Properly
convert operands before folding a MINUS_EXPR. convert operands before folding a MINUS_EXPR.
(fold_binary_loc): Move simplification of MINUS_EXPR on (fold_binary_loc): Move simplification of MINUS_EXPR on
...@@ -1748,11 +1748,12 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, ...@@ -1748,11 +1748,12 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
insns = get_insns (); insns = get_insns ();
end_sequence (); end_sequence ();
bool trapv = trapv_binoptab_p (binoptab);
target = gen_reg_rtx (mode); target = gen_reg_rtx (mode);
emit_libcall_block_1 (insns, target, value, emit_libcall_block_1 (insns, target, value,
gen_rtx_fmt_ee (optab_to_code (binoptab), trapv ? NULL_RTX
mode, op0, op1), : gen_rtx_fmt_ee (optab_to_code (binoptab),
trapv_binoptab_p (binoptab)); mode, op0, op1), trapv);
return target; return target;
} }
...@@ -2880,13 +2881,19 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target, ...@@ -2880,13 +2881,19 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
end_sequence (); end_sequence ();
target = gen_reg_rtx (outmode); target = gen_reg_rtx (outmode);
eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0); bool trapv = trapv_unoptab_p (unoptab);
if (GET_MODE_SIZE (outmode) < GET_MODE_SIZE (mode)) if (trapv)
eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode); eq_value = NULL_RTX;
else if (GET_MODE_SIZE (outmode) > GET_MODE_SIZE (mode)) else
eq_value = simplify_gen_unary (ZERO_EXTEND, outmode, eq_value, mode); {
emit_libcall_block_1 (insns, target, value, eq_value, eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
trapv_unoptab_p (unoptab)); if (GET_MODE_SIZE (outmode) < GET_MODE_SIZE (mode))
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_1 (insns, target, value, eq_value, trapv);
return target; return target;
} }
...@@ -3573,7 +3580,8 @@ emit_libcall_block_1 (rtx_insn *insns, rtx target, rtx result, rtx equiv, ...@@ -3573,7 +3580,8 @@ emit_libcall_block_1 (rtx_insn *insns, rtx target, rtx result, rtx equiv,
} }
last = emit_move_insn (target, result); last = emit_move_insn (target, result);
set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target); if (equiv)
set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target);
if (final_dest != target) if (final_dest != target)
emit_move_insn (final_dest, target); emit_move_insn (final_dest, target);
......
2015-10-22 Richard Biener <rguenther@suse.de>
PR middle-end/68046
PR middle-end/61893
* gcc.dg/torture/ftrapv-2.c: New testcase.
2015-10-22 Andreas Krebbel <krebbel@linux.vnet.ibm.com> 2015-10-22 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
PR target/68015 PR target/68015
......
/* { dg-do run } */
/* With -flto this degenerates to constant folding which doesn't work. */
/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
/* { dg-additional-options "-ftrapv" } */
/* { dg-require-effective-target trapping } */
/* { dg-require-fork unused } */
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
/* Verify SImode operations properly trap. PR middle-end/68046 */
int i = 0x7fffffff;
int main(void)
{
pid_t child = fork ();
int status = 0;
if (child == 0)
{
volatile int x = i + 1 < i;
exit (0);
}
else if (child == -1)
return 0;
if (wait (&status) == child
&& status == 0)
abort ();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment