Ping! On Mon, 14 Jul 2025, Hans-Peter Nilsson wrote:
> Tested to fix build for MMIX (and to fix a few type-generic-builtin > test-cases; c-c++-common/pr111309-1.c, gcc.dg/torture/pr116480-1.c). > Also regtested cris-elf and native x86_64-pc-linux-gnu. > > Ok for master and gcc-15? > > -- >8 -- > MMIX uses the default definition of MAX_FIXED_MODE_SIZE, which is > GET_MODE_SIZE (DImode) (arguably a suboptimal default, but that's for > another patch). > > That macro doesn't reflect the size of the largest mode *valid* on the > target, but rather the size of the largest mode that *should* be > generated when synthesizing operations doing optimizations. The > keyword "generated" appears to be missing from the documentation for > MAX_FIXED_MODE_SIZE or is meant to be implied by "use": (perhaps, > s/should actually be used/should actually be generated/, and note, > still "should" not "must"). For example, when putting > larger-than-register objects on the stack it could be the threshold > when to use BLKmode instead of an integer mode (e.g. TImode). But, > this should affect only optimization, not validness of code and > certainly not cause an ICE, as in PR 120935. > > The function fold_builtin_bit_query is responsible for transforming > type-generic calls into type-specific calls. It currently makes use > of MAX_FIXED_MODE_SIZE. The effect is here, when transforming > __builtin_clzg(__int128 x), instead of an expression with calls to > __builtin_clzl, it's wrongly changed into a call to an internal > function .CLZ (x). (N.B. this would validly happen when there's a > matching instruction.) When later on, another part of gcc sees that > there is no such internal function; no such instruction, boom: ICE. > > Here, what's intended to be generated, is *half* the size of the > existing incoming type. Actually, MAX_FIXED_MODE_SIZE seems to be > inconsistently used instead of the size of unsigned long long. That > macro just doesn't have to be consulted in this code. > > PR middle-end/120935 > * builtins.cc (fold_builtin_bit_query): Do not consider > MAX_FIXED_MODE_SIZE. > --- > gcc/builtins.cc | 36 +++++++++++++----------------------- > 1 file changed, 13 insertions(+), 23 deletions(-) > > diff --git a/gcc/builtins.cc b/gcc/builtins.cc > index 7f580a3145ff..728ae5e6c2c0 100644 > --- a/gcc/builtins.cc > +++ b/gcc/builtins.cc > @@ -10283,8 +10283,8 @@ fold_builtin_bit_query (location_t loc, enum > built_in_function fcode, > gcc_unreachable (); > } > > - if (TYPE_PRECISION (arg0_type) > - <= TYPE_PRECISION (long_long_unsigned_type_node)) > + unsigned int llu_size = TYPE_PRECISION (long_long_unsigned_type_node); > + if (TYPE_PRECISION (arg0_type) <= llu_size) > { > if (TYPE_PRECISION (arg0_type) <= TYPE_PRECISION (unsigned_type_node)) > > @@ -10305,13 +10305,12 @@ fold_builtin_bit_query (location_t loc, enum > built_in_function fcode, > fcodei = fcodell; > } > } > - else if (TYPE_PRECISION (arg0_type) <= MAX_FIXED_MODE_SIZE) > + else if (TYPE_PRECISION (arg0_type) <= 2 * llu_size) > { > cast_type > - = build_nonstandard_integer_type (MAX_FIXED_MODE_SIZE, > + = build_nonstandard_integer_type (2 * llu_size, > TYPE_UNSIGNED (arg0_type)); > - gcc_assert (TYPE_PRECISION (cast_type) > - == 2 * TYPE_PRECISION (long_long_unsigned_type_node)); > + gcc_assert (TYPE_PRECISION (cast_type) == 2 * llu_size); > fcodei = END_BUILTINS; > } > else > @@ -10342,9 +10341,7 @@ fold_builtin_bit_query (location_t loc, enum > built_in_function fcode, > arg2 = NULL_TREE; > } > tree call = NULL_TREE, tem; > - if (TYPE_PRECISION (arg0_type) == MAX_FIXED_MODE_SIZE > - && (TYPE_PRECISION (arg0_type) > - == 2 * TYPE_PRECISION (long_long_unsigned_type_node)) > + if ((TYPE_PRECISION (arg0_type) == 2 * llu_size) > /* If the target supports the optab, then don't do the expansion. */ > && !direct_internal_fn_supported_p (ifn, arg0_type, OPTIMIZE_FOR_BOTH)) > { > @@ -10354,8 +10351,7 @@ fold_builtin_bit_query (location_t loc, enum > built_in_function fcode, > ? long_long_unsigned_type_node > : long_long_integer_type_node); > tree hi = fold_build2 (RSHIFT_EXPR, arg0_type, arg0, > - build_int_cst (integer_type_node, > - MAX_FIXED_MODE_SIZE / 2)); > + build_int_cst (integer_type_node, llu_size)); > hi = fold_convert (type, hi); > tree lo = fold_convert (type, arg0); > switch (fcode) > @@ -10363,8 +10359,7 @@ fold_builtin_bit_query (location_t loc, enum > built_in_function fcode, > case BUILT_IN_CLZG: > call = fold_builtin_bit_query (loc, fcode, lo, NULL_TREE); > call = fold_build2 (PLUS_EXPR, integer_type_node, call, > - build_int_cst (integer_type_node, > - MAX_FIXED_MODE_SIZE / 2)); > + build_int_cst (integer_type_node, llu_size)); > if (arg2) > call = fold_build3 (COND_EXPR, integer_type_node, > fold_build2 (NE_EXPR, boolean_type_node, > @@ -10380,8 +10375,7 @@ fold_builtin_bit_query (location_t loc, enum > built_in_function fcode, > case BUILT_IN_CTZG: > call = fold_builtin_bit_query (loc, fcode, hi, NULL_TREE); > call = fold_build2 (PLUS_EXPR, integer_type_node, call, > - build_int_cst (integer_type_node, > - MAX_FIXED_MODE_SIZE / 2)); > + build_int_cst (integer_type_node, llu_size)); > if (arg2) > call = fold_build3 (COND_EXPR, integer_type_node, > fold_build2 (NE_EXPR, boolean_type_node, > @@ -10397,15 +10391,13 @@ fold_builtin_bit_query (location_t loc, enum > built_in_function fcode, > case BUILT_IN_CLRSBG: > tem = fold_builtin_bit_query (loc, fcode, lo, NULL_TREE); > tem = fold_build2 (PLUS_EXPR, integer_type_node, tem, > - build_int_cst (integer_type_node, > - MAX_FIXED_MODE_SIZE / 2)); > + build_int_cst (integer_type_node, llu_size)); > tem = fold_build3 (COND_EXPR, integer_type_node, > fold_build2 (LT_EXPR, boolean_type_node, > fold_build2 (BIT_XOR_EXPR, type, > lo, hi), > build_zero_cst (type)), > - build_int_cst (integer_type_node, > - MAX_FIXED_MODE_SIZE / 2 - 1), > + build_int_cst (integer_type_node, llu_size - 1), > tem); > call = fold_builtin_bit_query (loc, fcode, hi, NULL_TREE); > call = save_expr (call); > @@ -10413,15 +10405,13 @@ fold_builtin_bit_query (location_t loc, enum > built_in_function fcode, > fold_build2 (NE_EXPR, boolean_type_node, > call, > build_int_cst (integer_type_node, > - MAX_FIXED_MODE_SIZE > - / 2 - 1)), > + llu_size - 1)), > call, tem); > break; > case BUILT_IN_FFSG: > call = fold_builtin_bit_query (loc, fcode, hi, NULL_TREE); > call = fold_build2 (PLUS_EXPR, integer_type_node, call, > - build_int_cst (integer_type_node, > - MAX_FIXED_MODE_SIZE / 2)); > + build_int_cst (integer_type_node, llu_size)); > call = fold_build3 (COND_EXPR, integer_type_node, > fold_build2 (NE_EXPR, boolean_type_node, > hi, build_zero_cst (type)), > -- > 2.39.2 > >