This reverts the fix for PR67769 and installs an alternate fix
which is more targeted.  This helps preserving range info where
important (int this case for emitting a -Wstringop-overflow
warning).

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2017-12-07  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/83296
        PR tree-optimization/67769
        * tree-ssa-phiopt.c (conditional_replacement): Do not reset
        flow sensitive info in an unrelated BB.
        (value_replacement): Use reset_flow_sensitive_info.
        (minmax_replacement): Reset flow sensitive info on the def
        we move.  Do not reset flow sensitive info in the whole BB
        we move the stmt to.
        (abs_replacement): Likewise.

        * g++.dg/warn/Wstringop-overflow-1.C: New testcase.

Index: gcc/tree-ssa-phiopt.c
===================================================================
--- gcc/tree-ssa-phiopt.c       (revision 255461)
+++ gcc/tree-ssa-phiopt.c       (working copy)
@@ -672,7 +672,6 @@ conditional_replacement (basic_block con
     }
 
   replace_phi_edge_with_variable (cond_bb, e1, phi, new_var);
-  reset_flow_sensitive_info_in_bb (cond_bb);
 
   /* Note that we optimized this PHI.  */
   return true;
@@ -1138,22 +1137,22 @@ value_replacement (basic_block cond_bb,
                                              cond_rhs, false, rhs2))))))
     {
       gsi = gsi_for_stmt (cond);
+      /* Moving ASSIGN might change VR of lhs, e.g. when moving u_6
+        def-stmt in:
+          if (n_5 != 0)
+            goto <bb 3>;
+          else
+            goto <bb 4>;
+
+          <bb 3>:
+          # RANGE [0, 4294967294]
+          u_6 = n_5 + 4294967295;
+
+          <bb 4>:
+          # u_3 = PHI <u_6(3), 4294967295(2)>  */
+      reset_flow_sensitive_info (lhs);
       if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
        {
-         /* Moving ASSIGN might change VR of lhs, e.g. when moving u_6
-            def-stmt in:
-            if (n_5 != 0)
-              goto <bb 3>;
-            else
-              goto <bb 4>;
-
-            <bb 3>:
-            # RANGE [0, 4294967294]
-            u_6 = n_5 + 4294967295;
-
-            <bb 4>:
-            # u_3 = PHI <u_6(3), 4294967295(2)>  */
-         SSA_NAME_RANGE_INFO (lhs) = NULL;
          /* If available, we can use VR of phi result at least.  */
          tree phires = gimple_phi_result (phi);
          struct range_info_def *phires_range_info
@@ -1166,7 +1165,7 @@ value_replacement (basic_block cond_bb,
       for (int i = prep_cnt - 1; i >= 0; --i)
        {
          tree plhs = gimple_assign_lhs (prep_stmt[i]);
-         SSA_NAME_RANGE_INFO (plhs) = NULL;
+         reset_flow_sensitive_info (plhs);
          gsi_from = gsi_for_stmt (prep_stmt[i]);
          gsi_move_before (&gsi_from, &gsi);
        }
@@ -1490,6 +1489,8 @@ minmax_replacement (basic_block cond_bb,
       /* Move the statement from the middle block.  */
       gsi = gsi_last_bb (cond_bb);
       gsi_from = gsi_last_nondebug_bb (middle_bb);
+      reset_flow_sensitive_info (SINGLE_SSA_TREE_OPERAND (gsi_stmt (gsi_from),
+                                                         SSA_OP_DEF));
       gsi_move_before (&gsi_from, &gsi);
     }
 
@@ -1508,7 +1509,6 @@ minmax_replacement (basic_block cond_bb,
   gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
 
   replace_phi_edge_with_variable (cond_bb, e1, phi, result);
-  reset_flow_sensitive_info_in_bb (cond_bb);
 
   return true;
 }
@@ -1636,7 +1636,6 @@ abs_replacement (basic_block cond_bb, ba
     }
 
   replace_phi_edge_with_variable (cond_bb, e1, phi, result);
-  reset_flow_sensitive_info_in_bb (cond_bb);
 
   /* Note that we optimized this PHI.  */
   return true;
Index: gcc/testsuite/g++.dg/warn/Wstringop-overflow-1.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wstringop-overflow-1.C    (nonexistent)
+++ gcc/testsuite/g++.dg/warn/Wstringop-overflow-1.C    (working copy)
@@ -0,0 +1,15 @@
+// { dg-do compile }
+// { dg-additional-options "-O2 -Wstringop-overflow=2" }
+
+struct S {
+    char a[5];
+    void (*pf)(void);
+};
+
+void f (struct S *s, int n)
+{
+  if (n < sizeof s->a + 1)
+    n = sizeof s->a + 1;
+
+  __builtin_strncpy (s->a, "123456", n);   // { dg-warning "writing 6" }
+}

Reply via email to