Alexandre Oliva <ol...@adacore.com> writes: > On Feb 6, 2025, Sam James <s...@gentoo.org> wrote: > >> Richard Biener <richard.guent...@gmail.com> writes: >>> On Thu, Feb 6, 2025 at 2:41 PM Alexandre Oliva <ol...@adacore.com> wrote: >>>> >>>> On Jan 27, 2025, Richard Biener <richard.guent...@gmail.com> wrote: >>>> > (I see the assert is no longer in the patch). >>>> >>>> That's because the assert went in as part of an earlier patch. I take >>>> it it should be backed out along with the to-be-split-out bits above, >>>> right? >>> >>> Yes. >>> >>> (IIRC there's also a PR tripping over this or a similar assert) > >> Right, PR118706. > > Thanks. I've added its testcase to the patch below, reverted the > assert, and dropped the other unwanted bits. Regstrapped on > x86_64-linux-gnu. Ok to install?
Thanks. BTW, there's another for you at PR118805 (sorry). > > > > If decode_field_reference finds a load that accesses past the inner > object's size, bail out. > > Drop the too-strict assert. > > > for gcc/ChangeLog > > PR tree-optimization/118514 > PR tree-optimization/118706 > * gimple-fold.cc (decode_field_reference): Refuse to consider > merging out-of-bounds BIT_FIELD_REFs. > (make_bit_field_load): Drop too-strict assert. > * tree-eh.cc (bit_field_ref_in_bounds_p): Rename to... > (access_in_bounds_of_type_p): ... this. Change interface, > export. > (tree_could_trap_p): Adjust. > * tree-eh.h (access_in_bounds_of_type_p): Declare. > > for gcc/testsuite/ChangeLog > > PR tree-optimization/118514 > PR tree-optimization/118706 > * gcc.dg/field-merge-25.c: New. > --- > gcc/gimple-fold.cc | 11 ++--------- > gcc/testsuite/gcc.dg/field-merge-25.c | 15 +++++++++++++++ > gcc/tree-eh.cc | 25 +++++++++++++------------ > gcc/tree-eh.h | 1 + > 4 files changed, 31 insertions(+), 21 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/field-merge-25.c > > diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc > index 45485782cdf91..29191685a43c5 100644 > --- a/gcc/gimple-fold.cc > +++ b/gcc/gimple-fold.cc > @@ -7686,10 +7686,8 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT > *pbitsize, > || bs <= shiftrt > || offset != 0 > || TREE_CODE (inner) == PLACEHOLDER_EXPR > - /* Reject out-of-bound accesses (PR79731). */ > - || (! AGGREGATE_TYPE_P (TREE_TYPE (inner)) > - && compare_tree_int (TYPE_SIZE (TREE_TYPE (inner)), > - bp + bs) < 0) > + /* Reject out-of-bound accesses (PR79731, PR118514). */ > + || !access_in_bounds_of_type_p (TREE_TYPE (inner), bs, bp) > || (INTEGRAL_TYPE_P (TREE_TYPE (inner)) > && !type_has_mode_precision_p (TREE_TYPE (inner)))) > return NULL_TREE; > @@ -7859,11 +7857,6 @@ make_bit_field_load (location_t loc, tree inner, tree > orig_inner, tree type, > gimple *new_stmt = gsi_stmt (i); > if (gimple_has_mem_ops (new_stmt)) > gimple_set_vuse (new_stmt, reaching_vuse); > - gcc_checking_assert (! (gimple_assign_load_p (point) > - && gimple_assign_load_p (new_stmt)) > - || (tree_could_trap_p (gimple_assign_rhs1 (point)) > - == tree_could_trap_p (gimple_assign_rhs1 > - (new_stmt)))); > } > > gimple_stmt_iterator gsi = gsi_for_stmt (point); > diff --git a/gcc/testsuite/gcc.dg/field-merge-25.c > b/gcc/testsuite/gcc.dg/field-merge-25.c > new file mode 100644 > index 0000000000000..e769b0ae7b846 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/field-merge-25.c > @@ -0,0 +1,15 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O1 -fno-tree-fre" } */ > + > +/* PR tree-optimization/118706 */ > + > +int a[1][1][3], b; > +int main() { > + int c = -1; > + while (b) { > + if (a[c][c][6]) > + break; > + if (a[0][0][0]) > + break; > + } > +} > diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc > index 7015189a2de83..a4d59954c0597 100644 > --- a/gcc/tree-eh.cc > +++ b/gcc/tree-eh.cc > @@ -2646,24 +2646,22 @@ range_in_array_bounds_p (tree ref) > return true; > } > > -/* Return true iff EXPR, a BIT_FIELD_REF, accesses a bit range that is known > to > - be in bounds for the referred operand type. */ > +/* Return true iff a BIT_FIELD_REF <(TYPE)???, SIZE, OFFSET> would access a > bit > + range that is known to be in bounds for TYPE. */ > > -static bool > -bit_field_ref_in_bounds_p (tree expr) > +bool > +access_in_bounds_of_type_p (tree type, poly_uint64 size, poly_uint64 offset) > { > - tree size_tree; > - poly_uint64 size_max, min, wid, max; > + tree type_size_tree; > + poly_uint64 type_size_max, min = offset, wid = size, max; > > - size_tree = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (expr, 0))); > - if (!size_tree || !poly_int_tree_p (size_tree, &size_max)) > + type_size_tree = TYPE_SIZE (type); > + if (!type_size_tree || !poly_int_tree_p (type_size_tree, &type_size_max)) > return false; > > - min = bit_field_offset (expr); > - wid = bit_field_size (expr); > max = min + wid; > if (maybe_lt (max, min) > - || maybe_lt (size_max, max)) > + || maybe_lt (type_size_max, max)) > return false; > > return true; > @@ -2712,7 +2710,10 @@ tree_could_trap_p (tree expr) > switch (code) > { > case BIT_FIELD_REF: > - if (DECL_P (TREE_OPERAND (expr, 0)) && !bit_field_ref_in_bounds_p > (expr)) > + if (DECL_P (TREE_OPERAND (expr, 0)) > + && !access_in_bounds_of_type_p (TREE_TYPE (TREE_OPERAND (expr, 0)), > + bit_field_size (expr), > + bit_field_offset (expr))) > return true; > /* Fall through. */ > > diff --git a/gcc/tree-eh.h b/gcc/tree-eh.h > index 69fe193f1b82f..1fe6de80c42e7 100644 > --- a/gcc/tree-eh.h > +++ b/gcc/tree-eh.h > @@ -36,6 +36,7 @@ extern void redirect_eh_dispatch_edge (geh_dispatch *, > edge, basic_block); > extern bool operation_could_trap_helper_p (enum tree_code, bool, bool, bool, > bool, tree, bool *); > extern bool operation_could_trap_p (enum tree_code, bool, bool, tree); > +extern bool access_in_bounds_of_type_p (tree, poly_uint64, poly_uint64); > extern bool tree_could_trap_p (tree); > extern tree rewrite_to_non_trapping_overflow (tree); > extern bool stmt_could_throw_p (function *, gimple *);