https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63185

--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> ---
So the following incomplete patch solves the value-numbering issue in FRE2.

diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index a121b880bb0..745d60cbda5 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -529,6 +529,31 @@ get_ref_base_and_extent (tree exp, poly_int64_pod
*poffset,
                /* Remember that we have seen an array ref with a variable
                   index.  */
                seen_variable_array_ref = true;
+
+               wide_int min, max;
+               if (TREE_CODE (index) == SSA_NAME
+                   && integer_zerop (array_ref_low_bound (exp))
+                   && (unit_size = array_ref_element_size (exp),
+                       TREE_CODE (unit_size) == INTEGER_CST)
+                   && get_range_info (index, &min, &max) == VR_RANGE
+                   && wi::gts_p (max, 0))
+                 {
+                   poly_offset_int rmaxsize;
+                   rmaxsize = offset_int::from (max, UNSIGNED) * wi::to_offset
(unit_size);
+                   if (known_size_p (maxsize))
+                     {
+                       if (known_lt (rmaxsize, maxsize))
+                         {
+                           maxsize = rmaxsize;
+                           seen_variable_array_ref = false;
+                           }
+                     }
+                   else
+                     {
+                       maxsize = rmaxsize;
+                       seen_variable_array_ref = false;
+                     }
+                 }
              }
          }
          break;
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 1463c1d4116..dad4e4fecdf 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1960,19 +1960,46 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void
*vr_,
       && gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET)
       && integer_zerop (gimple_call_arg (def_stmt, 1))
       && poly_int_tree_p (gimple_call_arg (def_stmt, 2))
-      && TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR)
+      && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR
+         || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME))
     {
-      tree ref2 = TREE_OPERAND (gimple_call_arg (def_stmt, 0), 0);
       tree base2;
       poly_int64 offset2, size2, maxsize2;
       bool reverse;
-      base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &maxsize2,
-                                      &reverse);
+      tree ref2 = gimple_call_arg (def_stmt, 0);
+      if (TREE_CODE (ref2) == SSA_NAME)
+       {
+         ref2 = SSA_VAL (ref2);
+         if (TREE_CODE (ref2) == SSA_NAME
+             && (TREE_CODE (base) != MEM_REF
+                 || TREE_OPERAND (base, 0) != ref2))
+           {
+             gimple *def_stmt = SSA_NAME_DEF_STMT (ref2);
+             if (gimple_assign_single_p (def_stmt)
+                 && gimple_assign_rhs_code (def_stmt) == ADDR_EXPR)
+               ref2 = gimple_assign_rhs1 (def_stmt);
+           }
+       }
+      if (TREE_CODE (ref2) == ADDR_EXPR)
+       {
+         ref2 = TREE_OPERAND (ref2, 0);
+         base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &maxsize2,
+                                          &reverse);
+         if (!known_size_p (maxsize2)
+             || !operand_equal_p (base, base2, 0))
+           return (void *)-1;
+       }
+      else
+       {
+         if (TREE_CODE (base) != MEM_REF
+             || TREE_OPERAND (base, 0) != ref2
+             || !integer_zerop (TREE_OPERAND (base, 1)))
+           return (void *)-1;
+         offset2 = 0;
+       }
       tree len = gimple_call_arg (def_stmt, 2);
-      if (known_size_p (maxsize2)
-         && operand_equal_p (base, base2, 0)
-         && known_subrange_p (offset, maxsize, offset2,
-                              wi::to_poly_offset (len) << LOG2_BITS_PER_UNIT))
+      if (known_subrange_p (offset, maxsize, offset2,
+                           wi::to_poly_offset (len) << LOG2_BITS_PER_UNIT))
        {
          tree val = build_zero_cst (vr->type);
          return vn_reference_lookup_or_insert_for_pieces

Reply via email to