tree-vrp.c: Include "intl.h".
authorIan Lance Taylor <iant@google.com>
Thu, 8 Mar 2007 17:36:05 +0000 (17:36 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 8 Mar 2007 17:36:05 +0000 (17:36 +0000)
./: * tree-vrp.c: Include "intl.h".
(usable_range_p): New static function.
(compare_values_warnv): Don't test TYPE_OVERFLOW_UNDEFINED for
overflowed values, juts set *strict_overflow_p.
(compare_values): Only return -2 if one of the operands is not a
constant.
(compare_ranges): Call usable_range_p.
(compare_range_with_value): Likewise.
(vrp_evaluate_conditional_warnv): Rename from
vrp_evaluate_conditional.  Make static.  Change all callers.
(vrp_evaluate_conditional): New function.
(simplify_div_or_mod_using_ranges): Issue warning about reliance
on signed overflow.
(simplify_abs_using_ranges): Likewise.
(simplify_stmt_for_jump_threading): Add within_stmt parameter.
* tree-ssa-dom.c (simplify_stmt_for_jump_threading): Add
within_stmt parameter.
* tree-ssa-propagate.c (fold_predicate_in): Update call to
vrp_evaluate_conditional.
* tree-ssa-threadedge.c
(record_temporary_equivalences_from_stmts_at_dest): Change
simplify parameter to take a second tree parameter.
(simplify_control_stmt_condition): Likewise.
(thread_across_edge): Likewise.
* tree-flow.h (vrp_evaluate_conditional): Update declaration.
(thread_across_edge): Likewise.
* gcc/Makefile.in (tree-vrp.o): Depend upon intl.h.
testsuite/:
* gcc.dg/no-strict-overflow-5.c: New test.
* gcc.dg/no-strict-overflow-6.c: New test.
* gcc.dg/Wstrict-overflow-11.c: New test.
* gcc.dg/Wstrict-overflow-12.c: New test.
* gcc.dg/Wstrict-overflow-13.c: New test.
* gcc.dg/Wstrict-overflow-14.c: New test.
* gcc.dg/Wstrict-overflow-15.c: New test.

From-SVN: r122706

15 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/Wstrict-overflow-11.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/Wstrict-overflow-12.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/Wstrict-overflow-13.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/Wstrict-overflow-14.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/Wstrict-overflow-15.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/no-strict-overflow-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/no-strict-overflow-6.c [new file with mode: 0644]
gcc/tree-flow.h
gcc/tree-ssa-dom.c
gcc/tree-ssa-propagate.c
gcc/tree-ssa-threadedge.c
gcc/tree-vrp.c

index 98906d7..5b19aa3 100644 (file)
@@ -1,3 +1,33 @@
+2007-03-08  Ian Lance Taylor  <iant@google.com>
+
+       * tree-vrp.c: Include "intl.h".
+       (usable_range_p): New static function.
+       (compare_values_warnv): Don't test TYPE_OVERFLOW_UNDEFINED for
+       overflowed values, juts set *strict_overflow_p.
+       (compare_values): Only return -2 if one of the operands is not a
+       constant.
+       (compare_ranges): Call usable_range_p.
+       (compare_range_with_value): Likewise.
+       (vrp_evaluate_conditional_warnv): Rename from
+       vrp_evaluate_conditional.  Make static.  Change all callers.
+       (vrp_evaluate_conditional): New function.
+       (simplify_div_or_mod_using_ranges): Issue warning about reliance
+       on signed overflow.
+       (simplify_abs_using_ranges): Likewise.
+       (simplify_stmt_for_jump_threading): Add within_stmt parameter.
+       * tree-ssa-dom.c (simplify_stmt_for_jump_threading): Add
+       within_stmt parameter.
+       * tree-ssa-propagate.c (fold_predicate_in): Update call to
+       vrp_evaluate_conditional.
+       * tree-ssa-threadedge.c
+       (record_temporary_equivalences_from_stmts_at_dest): Change
+       simplify parameter to take a second tree parameter.
+       (simplify_control_stmt_condition): Likewise.
+       (thread_across_edge): Likewise.
+       * tree-flow.h (vrp_evaluate_conditional): Update declaration.
+       (thread_across_edge): Likewise.
+       * gcc/Makefile.in (tree-vrp.o): Depend upon intl.h.
+
 2007-03-08  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.h (TARGET_SAHF): New define.
index 4feaa9f..82821cb 100644 (file)
@@ -2044,7 +2044,7 @@ tree-vn.o : tree-vn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) \
 tree-vrp.o : tree-vrp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) $(DIAGNOSTIC_H) $(GGC_H) \
    $(BASIC_BLOCK_H) tree-ssa-propagate.h $(FLAGS_H) $(TREE_DUMP_H) \
-   $(CFGLOOP_H) $(SCEV_H) tree-chrec.h $(TIMEVAR_H) toplev.h
+   $(CFGLOOP_H) $(SCEV_H) tree-chrec.h $(TIMEVAR_H) toplev.h intl.h
 tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
    $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(FLAGS_H) output.h \
    $(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
index 4de1a12..a2780b4 100644 (file)
@@ -1,3 +1,13 @@
+2007-03-08  Ian Lance Taylor  <iant@google.com>
+
+       * gcc.dg/no-strict-overflow-5.c: New test.
+       * gcc.dg/no-strict-overflow-6.c: New test.
+       * gcc.dg/Wstrict-overflow-11.c: New test.
+       * gcc.dg/Wstrict-overflow-12.c: New test.
+       * gcc.dg/Wstrict-overflow-13.c: New test.
+       * gcc.dg/Wstrict-overflow-14.c: New test.
+       * gcc.dg/Wstrict-overflow-15.c: New test.
+
 2007-03-08  Richard Sandiford  <richard@codesourcery.com>
 
        * gcc.c-torture/execute/strcmp-1.x: New file.  XFAIL execution
diff --git a/gcc/testsuite/gcc.dg/Wstrict-overflow-11.c b/gcc/testsuite/gcc.dg/Wstrict-overflow-11.c
new file mode 100644 (file)
index 0000000..c98610e
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow=1" } */
+
+/* Based on strict-overflow-5.c.  */
+
+/* We can only unroll when using strict overflow semantics.  */
+
+int foo (int i)
+{
+  int index;
+  int r=0;
+  for (index = i; index <= i+4; index+=2) /* { dg-warning "assuming signed overflow does not occur" "correct warning" } */
+    r++;
+  return r;
+}
diff --git a/gcc/testsuite/gcc.dg/Wstrict-overflow-12.c b/gcc/testsuite/gcc.dg/Wstrict-overflow-12.c
new file mode 100644 (file)
index 0000000..177904d
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow=2" } */
+
+/* Source: Ian Lance Taylor.  Dual of no-strict-overflow-6.c.  */
+
+/* VRP test.  This turns into an infinite loop when using strict
+   overflow semantics.  */
+
+int
+foo ()
+{
+  int i, bits;
+  for (i = 1, bits = 1; i > 0; i += i) /* { dg-warning "assuming signed overflow does not occur" "correct warning" } */
+    ++bits;
+  return bits;
+}
diff --git a/gcc/testsuite/gcc.dg/Wstrict-overflow-13.c b/gcc/testsuite/gcc.dg/Wstrict-overflow-13.c
new file mode 100644 (file)
index 0000000..170d137
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow=2" } */
+
+/* Source: Ian Lance Taylor.  Dual of no-strict-overflow-6.c.  */
+
+/* VRP test.  This turns into an infinite loop (depending on what
+   bigtime_test does), but at least we warn about it.  */
+
+extern int bigtime_test (int);
+int
+foo ()
+{
+  int j;
+  for (j = 1; 0 < j; j *= 2) /* { dg-warning "assuming signed overflow does not occur" "correct warning" } */
+    if (! bigtime_test (j))
+      return 1;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/Wstrict-overflow-14.c b/gcc/testsuite/gcc.dg/Wstrict-overflow-14.c
new file mode 100644 (file)
index 0000000..6f3c5a2
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow=4" } */
+
+/* Source: Ian Lance Taylor.  */
+
+int
+foo (int j)
+{
+  int i;
+  int sum = 0;
+
+  for (i = 1; i < j; i += i)
+    sum += i / 16; /* { dg-warning "assuming signed overflow does not occur" "" } */
+  return sum;
+}
diff --git a/gcc/testsuite/gcc.dg/Wstrict-overflow-15.c b/gcc/testsuite/gcc.dg/Wstrict-overflow-15.c
new file mode 100644 (file)
index 0000000..d1627d2
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow=4" } */
+
+/* Source: Ian Lance Taylor.  */
+
+int
+foo (int j)
+{
+  int i;
+  int sum = 0;
+
+  for (i = 1; i < j; i += i)
+    sum += __builtin_abs (i); /* { dg-warning "assuming signed overflow does not occur" "" } */
+  return sum;
+}
diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-5.c b/gcc/testsuite/gcc.dg/no-strict-overflow-5.c
new file mode 100644 (file)
index 0000000..7f82014
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-final_cleanup" } */
+
+/* Dual of strict-overflow-5.c.  */
+
+/* We can only unroll when using strict overflow semantics.  */
+
+int foo (int i)
+{
+  int index;
+  int r=0;
+  for (index = i; index <= i+4; index+=2) 
+    r++;
+  return r;
+}
+
+/* { dg-final { scan-tree-dump-times "r = 3" 0 "final_cleanup" } } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-6.c b/gcc/testsuite/gcc.dg/no-strict-overflow-6.c
new file mode 100644 (file)
index 0000000..664aa25
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-final_cleanup" } */
+
+/* Source: Ian Lance Taylor.  */
+
+/* VRP test.  We can not simplify the conditional when not using
+   strict overflow semantics.  We don't test this with
+   -fstrict-overflow because it turns into an infinite loop.  That is
+   OK but it would also be OK to not do that.  */
+
+int
+foo ()
+{
+  int i, bits;
+  for (i = 1, bits = 1; i > 0; i += i)
+    ++bits;
+  return bits;
+}
+
+/* { dg-final { scan-tree-dump "return bits" "final_cleanup" } } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
index 87b655b..bb08732 100644 (file)
@@ -776,7 +776,7 @@ bool fold_stmt_inplace (tree);
 tree widen_bitfield (tree, tree, tree);
 
 /* In tree-vrp.c  */
-tree vrp_evaluate_conditional (tree, bool, bool *);
+tree vrp_evaluate_conditional (tree, tree);
 void simplify_stmt_using_ranges (tree);
 
 /* In tree-ssa-dom.c  */
@@ -910,7 +910,7 @@ bool contains_abnormal_ssa_name_p (tree);
 /* In tree-ssa-threadedge.c */
 extern bool potentially_threadable_block (basic_block);
 extern void thread_across_edge (tree, edge, bool,
-                               VEC(tree, heap) **, tree (*) (tree));
+                               VEC(tree, heap) **, tree (*) (tree, tree));
 
 /* In tree-ssa-loop-im.c  */
 /* The possibilities of statement movement.  */
index 888c5ee..22e0121 100644 (file)
@@ -554,7 +554,7 @@ restore_vars_to_original_value (void)
 /* A trivial wrapper so that we can present the generic jump
    threading code with a simple API for simplifying statements.  */
 static tree
-simplify_stmt_for_jump_threading (tree stmt)
+simplify_stmt_for_jump_threading (tree stmt, tree within_stmt ATTRIBUTE_UNUSED)
 {
   return lookup_avail_expr (stmt, false);
 }
index 3cc3239..1981fa1 100644 (file)
@@ -1100,7 +1100,6 @@ fold_predicate_in (tree stmt)
   tree *pred_p = NULL;
   bool modify_stmt_p = false;
   tree val;
-  bool sop;
 
   if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
       && COMPARISON_CLASS_P (GIMPLE_STMT_OPERAND (stmt, 1)))
@@ -1113,8 +1112,7 @@ fold_predicate_in (tree stmt)
   else
     return false;
 
-  sop = false;
-  val = vrp_evaluate_conditional (*pred_p, true, &sop);
+  val = vrp_evaluate_conditional (*pred_p, stmt);
   if (val)
     {
       if (modify_stmt_p)
index 72018c0..777685a 100644 (file)
@@ -211,7 +211,8 @@ record_temporary_equivalences_from_phis (edge e, VEC(tree, heap) **stack)
 static tree
 record_temporary_equivalences_from_stmts_at_dest (edge e,
                                                  VEC(tree, heap) **stack,
-                                                 tree (*simplify) (tree))
+                                                 tree (*simplify) (tree,
+                                                                   tree))
 {
   block_stmt_iterator bsi;
   tree stmt = NULL;
@@ -315,7 +316,7 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
              cached_lhs = fold (pre_fold_expr);
              if (TREE_CODE (cached_lhs) != SSA_NAME
                  && !is_gimple_min_invariant (cached_lhs))
-               cached_lhs = (*simplify) (stmt);
+               cached_lhs = (*simplify) (stmt, stmt);
            }
 
          /* Restore the statement's original uses/defs.  */
@@ -353,7 +354,7 @@ static tree
 simplify_control_stmt_condition (edge e,
                                 tree stmt,
                                 tree dummy_cond,
-                                tree (*simplify) (tree),
+                                tree (*simplify) (tree, tree),
                                 bool handle_dominating_asserts)
 {
   tree cond, cached_lhs;
@@ -439,7 +440,7 @@ simplify_control_stmt_condition (edge e,
       /* If we have not simplified the condition down to an invariant,
         then use the pass specific callback to simplify the condition.  */
       if (! is_gimple_min_invariant (cached_lhs))
-       cached_lhs = (*simplify) (dummy_cond);
+       cached_lhs = (*simplify) (dummy_cond, stmt);
     }
 
   /* We can have conditionals which just test the state of a variable
@@ -466,7 +467,7 @@ simplify_control_stmt_condition (edge e,
       /* If we haven't simplified to an invariant yet, then use the
         pass specific callback to try and simplify it further.  */
       if (cached_lhs && ! is_gimple_min_invariant (cached_lhs))
-        cached_lhs = (*simplify) (stmt);
+        cached_lhs = (*simplify) (stmt, stmt);
     }
   else
     cached_lhs = NULL;
@@ -494,7 +495,7 @@ thread_across_edge (tree dummy_cond,
                    edge e,
                    bool handle_dominating_asserts,
                    VEC(tree, heap) **stack,
-                   tree (*simplify) (tree))
+                   tree (*simplify) (tree, tree))
 {
   tree stmt;
 
index fd5ba64..0e0e327 100644 (file)
@@ -33,6 +33,7 @@ Boston, MA 02110-1301, USA.  */
 #include "timevar.h"
 #include "diagnostic.h"
 #include "toplev.h"
+#include "intl.h"
 #include "cfgloop.h"
 #include "tree-scalar-evolution.h"
 #include "tree-ssa-propagate.h"
@@ -46,6 +47,7 @@ static sbitmap found_in_subgraph;
 static int compare_values (tree val1, tree val2);
 static int compare_values_warnv (tree val1, tree val2, bool *);
 static void vrp_meet (value_range_t *, value_range_t *);
+static tree vrp_evaluate_conditional_warnv (tree, bool, bool *);
 
 /* Location information for ASSERT_EXPRs.  Each instance of this
    structure describes an ASSERT_EXPR for an SSA name.  Since a single
@@ -543,6 +545,32 @@ overflow_infinity_range_p (value_range_t *vr)
              || is_overflow_infinity (vr->max)));
 }
 
+/* Return false if we can not make a valid comparison based on VR;
+   this will be the case if it uses an overflow infinity and overflow
+   is not undefined (i.e., -fno-strict-overflow is in effect).
+   Otherwise return true, and set *STRICT_OVERFLOW_P to true if VR
+   uses an overflow infinity.  */
+
+static bool
+usable_range_p (value_range_t *vr, bool *strict_overflow_p)
+{
+  gcc_assert (vr->type == VR_RANGE);
+  if (is_overflow_infinity (vr->min))
+    {
+      *strict_overflow_p = true;
+      if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (vr->min)))
+       return false;
+    }
+  if (is_overflow_infinity (vr->max))
+    {
+      *strict_overflow_p = true;
+      if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (vr->max)))
+       return false;
+    }
+  return true;
+}
+
+
 /* Like tree_expr_nonnegative_warnv_p, but this function uses value
    ranges obtained so far.  */
 
@@ -783,9 +811,8 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
         infinities.  */
       if (TREE_OVERFLOW (val1) || TREE_OVERFLOW (val2))
        {
-         if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (val1)))
-           return -2;
-
+         if (strict_overflow_p != NULL)
+           *strict_overflow_p = true;
          if (is_negative_overflow_infinity (val1))
            return is_negative_overflow_infinity (val2) ? 0 : -1;
          else if (is_negative_overflow_infinity (val2))
@@ -831,8 +858,8 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
     }
 }
 
-/* Compare values like compare_values_warnv, but treat comparisons
-   which rely on undefined overflow as incomparable.  */
+/* Compare values like compare_values_warnv, but treat comparisons of
+   nonconstants which rely on undefined overflow as incomparable.  */
 
 static int
 compare_values (tree val1, tree val2)
@@ -842,7 +869,8 @@ compare_values (tree val1, tree val2)
 
   sop = false;
   ret = compare_values_warnv (val1, val2, &sop);
-  if (sop)
+  if (sop
+      && (!is_gimple_min_invariant (val1) || !is_gimple_min_invariant (val2)))
     ret = -2;
   return ret;
 }
@@ -2359,7 +2387,7 @@ static void
 extract_range_from_comparison (value_range_t *vr, tree expr)
 {
   bool sop = false;
-  tree val = vrp_evaluate_conditional (expr, false, &sop);
+  tree val = vrp_evaluate_conditional_warnv (expr, false, &sop);
 
   /* A disadvantage of using a special infinity as an overflow
      representation is that we lose the ability to record overflow
@@ -2604,6 +2632,10 @@ compare_ranges (enum tree_code comp, value_range_t *vr0, value_range_t *vr1,
       return NULL_TREE;
     }
 
+  if (!usable_range_p (vr0, strict_overflow_p)
+      || !usable_range_p (vr1, strict_overflow_p))
+    return NULL_TREE;
+
   /* Simplify processing.  If COMP is GT_EXPR or GE_EXPR, switch the
      operands around and change the comparison code.  */
   if (comp == GT_EXPR || comp == GE_EXPR)
@@ -2737,6 +2769,9 @@ compare_range_with_value (enum tree_code comp, value_range_t *vr, tree val,
       return NULL_TREE;
     }
 
+  if (!usable_range_p (vr, strict_overflow_p))
+    return NULL_TREE;
+
   if (comp == EQ_EXPR)
     {
       /* EQ_EXPR may only be computed if VR represents exactly
@@ -4531,8 +4566,9 @@ compare_names (enum tree_code comp, tree n1, tree n2,
    Set *STRICT_OVERFLOW_P to indicate whether we relied on an overflow
    infinity to produce the result.  */
 
-tree
-vrp_evaluate_conditional (tree cond, bool use_equiv_p, bool *strict_overflow_p)
+static tree
+vrp_evaluate_conditional_warnv (tree cond, bool use_equiv_p,
+                               bool *strict_overflow_p)
 {
   gcc_assert (TREE_CODE (cond) == SSA_NAME
               || TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison);
@@ -4609,6 +4645,55 @@ vrp_evaluate_conditional (tree cond, bool use_equiv_p, bool *strict_overflow_p)
   return NULL_TREE;
 }
 
+/* Given COND within STMT, try to simplify it based on value range
+   information.  Return NULL if the conditional can not be evaluated.
+   The ranges of all the names equivalent with the operands in COND
+   will be used when trying to compute the value.  If the result is
+   based on undefined signed overflow, issue a warning if
+   appropriate.  */
+
+tree
+vrp_evaluate_conditional (tree cond, tree stmt)
+{
+  bool sop;
+  tree ret;
+
+  sop = false;
+  ret = vrp_evaluate_conditional_warnv (cond, true, &sop);
+
+  if (ret && sop)
+    {
+      enum warn_strict_overflow_code wc;
+      const char* warnmsg;
+
+      if (is_gimple_min_invariant (ret))
+       {
+         wc = WARN_STRICT_OVERFLOW_CONDITIONAL;
+         warnmsg = G_("assuming signed overflow does not occur when "
+                      "simplifying conditional to constant");
+       }
+      else
+       {
+         wc = WARN_STRICT_OVERFLOW_COMPARISON;
+         warnmsg = G_("assuming signed overflow does not occur when "
+                      "simplifying conditional");
+       }
+
+      if (issue_strict_overflow_warning (wc))
+       {
+         location_t locus;
+
+         if (!EXPR_HAS_LOCATION (stmt))
+           locus = input_location;
+         else
+           locus = EXPR_LOCATION (stmt);
+         warning (OPT_Wstrict_overflow, "%H%s", &locus, warnmsg);
+       }
+    }
+
+  return ret;
+}
+
 
 /* Visit conditional statement STMT.  If we can determine which edge
    will be taken out of STMT's basic block, record it in
@@ -4693,7 +4778,7 @@ vrp_visit_cond_stmt (tree stmt, edge *taken_edge_p)
      MICO, TRAMP3D and SPEC2000) showed that doing this results in
      4 more predicates folded in SPEC.  */
   sop = false;
-  val = vrp_evaluate_conditional (cond, false, &sop);
+  val = vrp_evaluate_conditional_warnv (cond, false, &sop);
   if (val)
     {
       if (!sop)
@@ -5071,6 +5156,23 @@ simplify_div_or_mod_using_ranges (tree stmt, tree rhs, enum tree_code rhs_code)
       bool sop = false;
 
       val = compare_range_with_value (GT_EXPR, vr, integer_zero_node, &sop);
+
+      if (val
+         && sop
+         && integer_onep (val)
+         && issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
+       {
+         location_t locus;
+
+         if (!EXPR_HAS_LOCATION (stmt))
+           locus = input_location;
+         else
+           locus = EXPR_LOCATION (stmt);
+         warning (OPT_Wstrict_overflow,
+                  ("%Hassuming signed overflow does not occur when "
+                   "simplifying / or %% to >> or &"),
+                  &locus);
+       }
     }
 
   if (val && integer_onep (val))
@@ -5138,6 +5240,20 @@ simplify_abs_using_ranges (tree stmt, tree rhs)
        {
          tree t;
 
+         if (sop && issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
+           {
+             location_t locus;
+
+             if (!EXPR_HAS_LOCATION (stmt))
+               locus = input_location;
+             else
+               locus = EXPR_LOCATION (stmt);
+             warning (OPT_Wstrict_overflow,
+                      ("%Hassuming signed overflow does not occur when "
+                       "simplifying abs (X) to X or -X"),
+                      &locus);
+           }
+
          if (integer_onep (val))
            t = build1 (NEGATE_EXPR, TREE_TYPE (op), op);
          else
@@ -5330,21 +5446,21 @@ simplify_stmt_using_ranges (tree stmt)
    restored.  */
 static VEC(tree,heap) *stack;
 
-/* A trivial wrapper so that we can present the generic jump
-   threading code with a simple API for simplifying statements.  */
+/* A trivial wrapper so that we can present the generic jump threading
+   code with a simple API for simplifying statements.  STMT is the
+   statement we want to simplify, WITHIN_STMT provides the location
+   for any overflow warnings.  */
+
 static tree
-simplify_stmt_for_jump_threading (tree stmt)
+simplify_stmt_for_jump_threading (tree stmt, tree within_stmt)
 {
-  bool sop;
-
   /* We only use VRP information to simplify conditionals.  This is
      overly conservative, but it's unclear if doing more would be
      worth the compile time cost.  */
   if (TREE_CODE (stmt) != COND_EXPR)
     return NULL;
 
-  sop = false;
-  return vrp_evaluate_conditional (COND_EXPR_COND (stmt), true, &sop);
+  return vrp_evaluate_conditional (COND_EXPR_COND (stmt), within_stmt);
 }
 
 /* Blocks which have more than one predecessor and more than