gimple-fold: Fix up big endian _BitInt adjustment [PR121131]

The following testcase ICEs because SCALAR_INT_TYPE_MODE of course
doesn't work for large BITINT_TYPE types which have BLKmode.
native_encode* as well as e.g. r14-8276 use in cases like these
GET_MODE_SIZE (SCALAR_INT_TYPE_MODE ()) and TREE_INT_CST_LOW (TYPE_SIZE_UNIT
()) for the BLKmode ones.
In this case, it wants bits rather than bytes, so I've used
GET_MODE_BITSIZE like before and TYPE_SIZE otherwise.

Furthermore, the patch only computes encoding_size for big endian
targets, for little endian we don't really adjust anything, so there
is no point computing it.

2025-07-18  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/121131
	* gimple-fold.cc (fold_nonarray_ctor_reference): Use
	TREE_INT_CST_LOW (TYPE_SIZE ()) instead of
	GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE ()) for BLKmode BITINT_TYPEs.
	Don't compute encoding_size at all for little endian targets.

	* gcc.dg/bitint-124.c: New test.
This commit is contained in:
Jakub Jelinek
2025-07-18 09:20:30 +02:00
committed by Jakub Jelinek
parent 0c473aa8fd
commit 90955b2f61
2 changed files with 40 additions and 3 deletions

View File

@ -9916,10 +9916,17 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
{
if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
return NULL_TREE;
const unsigned int encoding_size
= GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (cfield)));
if (BYTES_BIG_ENDIAN)
inner_offset += encoding_size - wi::to_offset (field_size);
{
tree ctype = TREE_TYPE (cfield);
unsigned int encoding_size;
if (TYPE_MODE (ctype) != BLKmode)
encoding_size
= GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (ctype));
else
encoding_size = TREE_INT_CST_LOW (TYPE_SIZE (ctype));
inner_offset += encoding_size - wi::to_offset (field_size);
}
}
return fold_ctor_reference (type, cval,

View File

@ -0,0 +1,30 @@
/* PR tree-optimization/121131 */
/* { dg-do run { target bitint } } */
/* { dg-options "-O2" } */
#if __BITINT_MAXWIDTH__ >= 156
struct A { _BitInt(156) b : 135; };
static inline _BitInt(156)
foo (struct A *x)
{
return x[1].b;
}
__attribute__((noipa)) _BitInt(156)
bar (void)
{
struct A a[] = { 1, 1, -13055525270329736316393717310914023773847wb,
1, 1, 1, 1, 1, 1, 1, 1, 1 };
return foo (&a[1]);
}
#endif
int
main ()
{
#if __BITINT_MAXWIDTH__ >= 156
if (bar () != -13055525270329736316393717310914023773847wb)
__builtin_abort ();
#endif
}