aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/optabs.c30
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/torture/ftrapv-2.c32
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;
+}