From: Jakub Jelinek Date: Thu, 31 Jul 2025 10:10:02 +0000 (+0200) Subject: change get_best_mode args int -> HOST_WIDE_INT [PR121264] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e624d5559d21992c9e5da85b4ae75629a61afc2c;p=thirdparty%2Fgcc.git change get_best_mode args int -> HOST_WIDE_INT [PR121264] 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. 2025-07-31 Jakub Jelinek 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. --- diff --git a/gcc/machmode.h b/gcc/machmode.h index 467681d9d2f..2f2d349be29 100644 --- a/gcc/machmode.h +++ b/gcc/machmode.h @@ -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. */ diff --git a/gcc/stor-layout.cc b/gcc/stor-layout.cc index 12071c96ca7..63e830a4d2e 100644 --- a/gcc/stor-layout.cc +++ b/gcc/stor-layout.cc @@ -3167,7 +3167,7 @@ bit_field_mode_iterator::prefer_smaller_modes () 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, diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr121264.c b/gcc/testsuite/gcc.dg/tree-ssa/pr121264.c new file mode 100644 index 00000000000..bd5acc0b1ec --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr121264.c @@ -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]; +}