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
This commit is contained in:
Richard Biener 2015-10-22 11:44:11 +00:00 committed by Richard Biener
parent 08e99efb2e
commit a51ca2f495
4 changed files with 65 additions and 11 deletions

View File

@ -1,3 +1,11 @@
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

View File

@ -1748,11 +1748,12 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
insns = get_insns ();
end_sequence ();
bool trapv = trapv_binoptab_p (binoptab);
target = gen_reg_rtx (mode);
emit_libcall_block_1 (insns, target, value,
gen_rtx_fmt_ee (optab_to_code (binoptab),
mode, op0, op1),
trapv_binoptab_p (binoptab));
trapv ? NULL_RTX
: gen_rtx_fmt_ee (optab_to_code (binoptab),
mode, op0, op1), trapv);
return target;
}
@ -2880,13 +2881,19 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
end_sequence ();
target = gen_reg_rtx (outmode);
eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
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_unoptab_p (unoptab));
bool trapv = trapv_unoptab_p (unoptab);
if (trapv)
eq_value = NULL_RTX;
else
{
eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
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;
}
@ -3573,7 +3580,8 @@ emit_libcall_block_1 (rtx_insn *insns, rtx target, rtx result, rtx equiv,
}
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)
emit_move_insn (final_dest, target);

View File

@ -1,3 +1,9 @@
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>
PR target/68015

View File

@ -0,0 +1,32 @@
/* { 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;
}