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)