diff options
author | Richard Biener <rguenther@suse.de> | 2015-10-22 11:44:11 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2015-10-22 11:44:11 +0000 |
commit | a51ca2f4959300090a44a57010d4866e04b1b1e5 (patch) | |
tree | 277387790bdb8a7475b00903c33cb056d7e6d36d /gcc | |
parent | 08e99efb2e7b5638af23f6c2b54840e7a943e107 (diff) | |
download | gcc-a51ca2f4959300090a44a57010d4866e04b1b1e5.zip gcc-a51ca2f4959300090a44a57010d4866e04b1b1e5.tar.gz gcc-a51ca2f4959300090a44a57010d4866e04b1b1e5.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/optabs.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/ftrapv-2.c | 32 |
4 files changed, 65 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 607547e..192360d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 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 convert operands before folding a MINUS_EXPR. (fold_binary_loc): Move simplification of MINUS_EXPR on diff --git a/gcc/optabs.c b/gcc/optabs.c index 82a1ee6..e1ac0b8 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4f54df6..45a287f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gcc.dg/torture/ftrapv-2.c b/gcc/testsuite/gcc.dg/torture/ftrapv-2.c new file mode 100644 index 0000000..8065ee0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/ftrapv-2.c @@ -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; +} |