PATCH COMMITTED: No overflow warnings in copied loop headers (PR 33565)

Ian Lance Taylor iant@google.com
Thu Sep 27 18:27:00 GMT 2007


PR 33565 is about an inappropriate overflow warning in a copied loop
header.  The loop header copying code already set TREE_NO_WARNING for
the COND_EXPR at the end of the header.  However, in the test case in
the PR, we got a loop header like this:

  D.1182_10 = m_2(D) + 9;
  D.1183_12 = m_2(D) <= D.1182_10;
  D.1184_13 = m_2(D) < n_6(D);
  D.1185_14 = D.1183_12 && D.1184_13;
  if (D.1185_14)
    goto <bb 3>;
  else
    goto <bb 4>;

There are conditionals in the assignments, and we also do not want to
apply overflow checking to them.

I also cleaned up the use of TREE_NO_WARNING to test it in
fold_undefer_overflow_warnings itself, rather than testing it at the
call sites.

Bootstrapped and tested on i686-unknown-linux-gnu.  Committed.

Ian


gcc/ChangeLog:
2007-09-27  Ian Lance Taylor  <iant@google.com>

	PR tree-optimization/33565
	* tree-ssa-loop-ch.c (copy_loop_headers): Set TREE_NO_WARNING on
	assignments of comparisons.
	* tree-ssa-sccvn.c (simplify_binary_expression): Add stmt
	parameter.  Change caller.  Defer overflow warnings around call to
	fold_binary.
	* fold-const.c (fold_undefer_overflow_warnings): Don't warn if
	TREE_NO_WARNING is set on the statement.
	* tree-ssa-forwprop.c
	(tree_ssa_forward_propagate_single_use_vars): Don't test
	TREE_NO_WARNING when calling fold_undefer_overflow_warnings.
	* tree-cfg.c (fold_cond_expr_cond): Likewise.

gcc/testsuite/ChangeLog:
2007-09-27  Ian Lance Taylor  <iant@google.com>

	PR tree-optimization/33565
	* gcc.dg/Wstrict-overflow-20.c: New test.


Index: tree-ssa-loop-ch.c
===================================================================
--- tree-ssa-loop-ch.c	(revision 128822)
+++ tree-ssa-loop-ch.c	(working copy)
@@ -215,11 +215,22 @@ copy_loop_headers (void)
 
 	  for (i = 0; i < n_bbs; ++i)
 	    {
-	      tree last;
+	      block_stmt_iterator bsi;
 
-	      last = last_stmt (copied_bbs[i]);
-	      if (TREE_CODE (last) == COND_EXPR)
-		TREE_NO_WARNING (last) = 1;
+	      for (bsi = bsi_start (copied_bbs[i]);
+		   !bsi_end_p (bsi);
+		   bsi_next (&bsi))
+		{
+		  tree stmt = bsi_stmt (bsi);
+		  if (TREE_CODE (stmt) == COND_EXPR)
+		    TREE_NO_WARNING (stmt) = 1;
+		  else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+		    {
+		      tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+		      if (COMPARISON_CLASS_P (rhs))
+			TREE_NO_WARNING (stmt) = 1;
+		    }
+		}
 	    }
 	}
 
Index: fold-const.c
===================================================================
--- fold-const.c	(revision 128822)
+++ fold-const.c	(working copy)
@@ -974,6 +974,9 @@ fold_undefer_overflow_warnings (bool iss
   if (!issue || warnmsg == NULL)
     return;
 
+  if (stmt != NULL_TREE && TREE_NO_WARNING (stmt))
+    return;
+
   /* Use the smallest code level when deciding to issue the
      warning.  */
   if (code == 0 || code > (int) fold_deferred_overflow_code)
Index: tree-ssa-sccvn.c
===================================================================
--- tree-ssa-sccvn.c	(revision 128822)
+++ tree-ssa-sccvn.c	(working copy)
@@ -1390,7 +1390,7 @@ valueize_expr (tree expr)
    simplified. */
 
 static tree
-simplify_binary_expression (tree rhs)
+simplify_binary_expression (tree stmt, tree rhs)
 {
   tree result = NULL_TREE;
   tree op0 = TREE_OPERAND (rhs, 0);
@@ -1421,8 +1421,13 @@ simplify_binary_expression (tree rhs)
       && op1 == TREE_OPERAND (rhs, 1))
     return NULL_TREE;
 
+  fold_defer_overflow_warnings ();
+
   result = fold_binary (TREE_CODE (rhs), TREE_TYPE (rhs), op0, op1);
 
+  fold_undefer_overflow_warnings (result && valid_gimple_expression_p (result),
+				  stmt, 0);
+
   /* Make sure result is not a complex expression consisting
      of operators of operators (IE (a + b) + (a + c))
      Otherwise, we will end up with unbounded expressions if
@@ -1522,7 +1527,7 @@ try_to_simplify (tree stmt, tree rhs)
 	  break;
 	case tcc_comparison:
 	case tcc_binary:
-	  return simplify_binary_expression (rhs);
+	  return simplify_binary_expression (stmt, rhs);
 	  break;
 	default:
 	  break;
Index: testsuite/gcc.dg/Wstrict-overflow-20.c
===================================================================
--- testsuite/gcc.dg/Wstrict-overflow-20.c	(revision 0)
+++ testsuite/gcc.dg/Wstrict-overflow-20.c	(revision 0)
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow" } */
+
+/* Don't warn about an overflow in a copied loop header.  We used to
+   get a warning in value numbering.  This is PR 33565.  */
+
+void f (int m, int n)
+{
+  int j;
+ 
+  for (j = m; j	< m + 10 && j <	n; j ++)
+    do_something (j);
+}
Index: tree-ssa-forwprop.c
===================================================================
--- tree-ssa-forwprop.c	(revision 128822)
+++ tree-ssa-forwprop.c	(working copy)
@@ -1021,8 +1021,7 @@ tree_ssa_forward_propagate_single_use_va
 	      did_something = forward_propagate_into_cond (stmt, stmt);
 	      if (did_something == 2)
 		cfg_changed = true;
-	      fold_undefer_overflow_warnings (!TREE_NO_WARNING (stmt)
-					      && did_something, stmt,
+	      fold_undefer_overflow_warnings (did_something, stmt,
 					      WARN_STRICT_OVERFLOW_CONDITIONAL);
 	      bsi_next (&bsi);
 	    }
Index: tree-cfg.c
===================================================================
--- tree-cfg.c	(revision 128822)
+++ tree-cfg.c	(working copy)
@@ -417,8 +417,7 @@ fold_cond_expr_cond (void)
 	  cond = fold (COND_EXPR_COND (stmt));
 	  zerop = integer_zerop (cond);
 	  onep = integer_onep (cond);
-	  fold_undefer_overflow_warnings (((zerop || onep)
-					   && !TREE_NO_WARNING (stmt)),
+	  fold_undefer_overflow_warnings (zerop || onep,
 					  stmt,
 					  WARN_STRICT_OVERFLOW_CONDITIONAL);
 	  if (zerop)



More information about the Gcc-patches mailing list