re PR middle-end/68046 (-ftrapv doesn't catch leaq-based overflows on x86-64)
authorRichard Biener <rguenther@suse.de>
Thu, 22 Oct 2015 11:44:11 +0000 (11:44 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 22 Oct 2015 11:44:11 +0000 (11:44 +0000)
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

gcc/ChangeLog
gcc/optabs.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/ftrapv-2.c [new file with mode: 0644]

index 607547e1a9fd3ce9f6343e8d448359fd008db865..192360dc752d25fa40209f40598e50ad7f3bc565 100644 (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
index 82a1ee6c28d893dfb0066f078ae8f0d9410ee474..e1ac0b85e5e8130ee5d1854684a49b816ac46535 100644 (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);
index 4f54df62c182d60eff61b1b1efc9c880d26a800d..45a287f3ec149d7c3f58f309ffc591751b41fe2b 100644 (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
diff --git a/gcc/testsuite/gcc.dg/torture/ftrapv-2.c b/gcc/testsuite/gcc.dg/torture/ftrapv-2.c
new file mode 100644 (file)
index 0000000..8065ee0
--- /dev/null
@@ -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;
+}