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

--- Comment #22 from Richard Biener <rguenth at gcc dot gnu.org> ---
So like the following, though maybe a maybe_eq (index, ub + 1) is enough given
any other OOB would be UB?

diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 8d74731a891..57ae40af77b 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -1010,9 +1010,29 @@ copy_reference_ops_from_ref (tree ref,
vec<vn_reference_o
p_s> *result)
            if (! temp.op2)
              temp.op2 = size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (eltype),
                                     size_int (TYPE_ALIGN_UNIT (eltype)));
+           /* Probibit value-numbering addresses of out-of-bound ARRAY_REFs
+              the same as addresses of other components before the pass
+              folding __builtin_object_size had a chance to run.  */
+           bool avoid_oob = true;
+           if (TREE_CODE (orig) != ADDR_EXPR
+               || cfun->curr_properties & PROP_objsz)
+             avoid_oob = false;
+           else if (poly_int_tree_p (temp.op0))
+             {
+               tree ub = array_ref_up_bound (ref);
+               if (ub
+                   && poly_int_tree_p (temp.op1)
+                   && poly_int_tree_p (ub)
+                   && known_le (wi::to_poly_offset (temp.op1),
+                                wi::to_poly_offset (temp.op0))
+                   && known_le (wi::to_poly_offset (temp.op0),
+                                wi::to_poly_offset (ub)))
+                 avoid_oob = false;
+             }
            if (poly_int_tree_p (temp.op0)
                && poly_int_tree_p (temp.op1)
-               && TREE_CODE (temp.op2) == INTEGER_CST)
+               && TREE_CODE (temp.op2) == INTEGER_CST
+               && !avoid_oob)
              {
                poly_offset_int off = ((wi::to_poly_offset (temp.op0)
                                        - wi::to_poly_offset (temp.op1))
@@ -1754,6 +1774,21 @@ re_valueize:
               && poly_int_tree_p (vro->op1)
               && TREE_CODE (vro->op2) == INTEGER_CST)
        {
+         /* Probibit value-numbering addresses of out-of-bound ARRAY_REFs
+            the same as addresses of other components before the pass
+            folding __builtin_object_size had a chance to run.  */
+         if (!(cfun->curr_properties & PROP_objsz))
+           {
+             tree dom = TYPE_DOMAIN ((*orig)[i + 1].type);
+             if (!dom || !poly_int_tree_p (TYPE_MAX_VALUE (dom)))
+               continue;
+             if (!(known_le (wi::to_poly_offset (vro->op1),
+                             wi::to_poly_offset (vro->op0))
+                   && known_le (wi::to_poly_offset (vro->op0),
+                                wi::to_poly_offset (TYPE_MAX_VALUE (dom)))))
+               continue;
+           }
+
          poly_offset_int off = ((wi::to_poly_offset (vro->op0)
                                  - wi::to_poly_offset (vro->op1))
                                 * wi::to_offset (vro->op2)

Reply via email to