On Thu, 31 Jul 2025, Jakub Jelinek wrote: > Hi! > > The following testcase is miscompiled, because byte 0x20000000 > is bit 0x100000000 and ifcombine incorrectly combines the two loads > into a BIT_FIELD_REF even when they are very far away. > The problem is that gimple-fold.cc ifcombine uses get_best_mode heavily, > and that function has just int bitsize and int bitpos arguments, so > when called e.g. with > if (get_best_mode (end_bit - first_bit, first_bit, 0, ll_end_region, > ll_align, BITS_PER_WORD, volatilep, &lnmode)) > where end_bit - first_bit doesn't fit into int, it is silently truncated. > If there was just a single problematic get_best_mode call, I would probably > just check for overflows in the caller, but there are many. > And the two arguments are used solely as arguments to > bit_field_mode_iterator constructor which has HOST_WIDE_INT arguments, > so I think the easiest fix is just make the get_best_mode arguments > also HOST_WIDE_INT. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/15.2?
OK. Richard. > 2025-07-31 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/121264 > * machmode.h (get_best_mode): Change type of first 2 arguments > from int to HOST_WIDE_INT. > * stor-layout.cc (get_best_mode): Likewise. > > * gcc.dg/tree-ssa/pr121264.c: New test. > > --- gcc/machmode.h.jj 2025-04-08 14:08:52.826259940 +0200 > +++ gcc/machmode.h 2025-07-30 14:03:25.468655462 +0200 > @@ -958,7 +958,8 @@ private: > > /* Find the best mode to use to access a bit field. */ > > -extern bool get_best_mode (int, int, poly_uint64, poly_uint64, unsigned int, > +extern bool get_best_mode (HOST_WIDE_INT, HOST_WIDE_INT, > + poly_uint64, poly_uint64, unsigned int, > unsigned HOST_WIDE_INT, bool, scalar_int_mode *); > > /* Determine alignment, 1<=result<=BIGGEST_ALIGNMENT. */ > --- gcc/stor-layout.cc.jj 2025-04-28 11:35:40.798888512 +0200 > +++ gcc/stor-layout.cc 2025-07-30 14:04:00.148195383 +0200 > @@ -3167,7 +3167,7 @@ bit_field_mode_iterator::prefer_smaller_ > decide which of the above modes should be used. */ > > bool > -get_best_mode (int bitsize, int bitpos, > +get_best_mode (HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos, > poly_uint64 bitregion_start, poly_uint64 bitregion_end, > unsigned int align, > unsigned HOST_WIDE_INT largest_mode_bitsize, bool volatilep, > --- gcc/testsuite/gcc.dg/tree-ssa/pr121264.c.jj 2025-07-30 > 14:13:14.529877964 +0200 > +++ gcc/testsuite/gcc.dg/tree-ssa/pr121264.c 2025-07-30 14:15:47.050867722 > +0200 > @@ -0,0 +1,12 @@ > +/* PR tree-optimization/121264 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > +/* { dg-final { scan-tree-dump " \\\| " "optimized" } } */ > + > +struct A { char b; char c[0x20000010]; } a; > + > +int > +foo () > +{ > + return a.c[0x20000000] || a.c[1]; > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)