]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/52353 (-ftrapv -fnon-call-exceptions does not work)
authorRichard Guenther <rguenther@suse.de>
Mon, 5 Mar 2012 13:08:55 +0000 (13:08 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 5 Mar 2012 13:08:55 +0000 (13:08 +0000)
2012-03-05  Richard Guenther  <rguenther@suse.de>

PR middle-end/52353
* optabs.h (trapv_unoptab_p): New function.
(trapv_binoptab_p): Likewise.
* optabs.c (expand_binop): Use emit_libcall_block_1 with
a proper equiv_may_trap argument.
(expand_unop): Likewise.
(emit_libcall_block_1): Take extra argument whether the
instruction may trap.  Renamed from ...
(emit_libcall_block): ... this.  New wrapper.

From-SVN: r184932

gcc/ChangeLog
gcc/optabs.c
gcc/optabs.h

index 565ca5b105efa3feb6218e15fbde0a59e81b350f..983c0924451dcb49c02a33a93216926d5bf4cf6c 100644 (file)
@@ -1,3 +1,15 @@
+2012-03-05  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/52353
+       * optabs.h (trapv_unoptab_p): New function.
+       (trapv_binoptab_p): Likewise.
+       * optabs.c (expand_binop): Use emit_libcall_block_1 with
+       a proper equiv_may_trap argument.
+       (expand_unop): Likewise.
+       (emit_libcall_block_1): Take extra argument whether the
+       instruction may trap.  Renamed from ...
+       (emit_libcall_block): ... this.  New wrapper.
+
 2012-03-05  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/51721
index fd353d7e627c2ce4af288f5a3a3a66f1b0fcb581..565db428045c74cf1f6064fe4360d1a23874eca7 100644 (file)
@@ -60,6 +60,7 @@ optab code_to_optab[NUM_RTX_CODE + 1];
 static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
                                   enum machine_mode *);
 static rtx expand_unop_direct (enum machine_mode, optab, rtx, rtx, int);
+static void emit_libcall_block_1 (rtx, rtx, rtx, rtx, bool);
 
 /* Debug facility for use in GDB.  */
 void debug_optab_libfuncs (void);
@@ -2115,8 +2116,9 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
       end_sequence ();
 
       target = gen_reg_rtx (mode);
-      emit_libcall_block (insns, target, value,
-                         gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
+      emit_libcall_block_1 (insns, target, value,
+                           gen_rtx_fmt_ee (binoptab->code, mode, op0, op1),
+                           trapv_binoptab_p (binoptab));
 
       return target;
     }
@@ -3197,7 +3199,8 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
        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 (insns, target, value, eq_value);
+      emit_libcall_block_1 (insns, target, value, eq_value,
+                           trapv_unoptab_p (unoptab));
 
       return target;
     }
@@ -3775,8 +3778,9 @@ no_conflict_move_test (rtx dest, const_rtx set, void *p0)
    an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
    note with an operand of EQUIV.  */
 
-void
-emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
+static void
+emit_libcall_block_1 (rtx insns, rtx target, rtx result, rtx equiv,
+                     bool equiv_may_trap)
 {
   rtx final_dest = target;
   rtx next, last, insn;
@@ -3789,7 +3793,8 @@ emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
   /* If we're using non-call exceptions, a libcall corresponding to an
      operation that may trap may also trap.  */
   /* ??? See the comment in front of make_reg_eh_region_note.  */
-  if (cfun->can_throw_non_call_exceptions && may_trap_p (equiv))
+  if (cfun->can_throw_non_call_exceptions
+      && (equiv_may_trap || may_trap_p (equiv)))
     {
       for (insn = insns; insn; insn = NEXT_INSN (insn))
        if (CALL_P (insn))
@@ -3870,6 +3875,12 @@ emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
   if (final_dest != target)
     emit_move_insn (final_dest, target);
 }
+
+void
+emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
+{
+  emit_libcall_block_1 (insns, target, result, equiv, false);
+}
 \f
 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
    PURPOSE describes how this comparison will be used.  CODE is the rtx
index 6ad6dae9ab676b4c3dd8839e9147ded239bf980c..70a7395cc0525d0dd301c52d2aed56c9765f0f3d 100644 (file)
@@ -1103,6 +1103,25 @@ set_direct_optab_handler (direct_optab op, enum machine_mode mode,
   op->handlers[(int) mode].insn_code = (int) code - (int) CODE_FOR_nothing;
 }
 
+/* Return true if UNOPTAB is for a trapping-on-overflow operation.  */
+
+static inline bool
+trapv_unoptab_p (optab unoptab)
+{
+  return (unoptab == negv_optab
+         || unoptab == absv_optab); 
+}
+
+/* Return true if BINOPTAB is for a trapping-on-overflow operation.  */
+
+static inline bool
+trapv_binoptab_p (optab binoptab)
+{
+  return (binoptab == addv_optab
+         || binoptab == subv_optab
+         || binoptab == smulv_optab);
+}
+
 extern rtx optab_libfunc (optab optab, enum machine_mode mode);
 extern rtx convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
                                  enum machine_mode mode2);