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)