https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114084
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Bet the associate code is really unprepared to have unfolded trees around, which hasn't been the case before delayed folding has been introduced to C and C++ FEs. Unfortunately it isn't complete, because e.g. convert_to_integer_1 -> do_narrow -> fold_build2_loc happily folds. Anyway, quick fix could be not trying to reassociate TREE_CONSTANT parts: --- gcc/fold-const.cc.jj 2024-01-26 00:07:58.000000000 +0100 +++ gcc/fold-const.cc 2024-02-24 09:38:40.150808529 +0100 @@ -908,6 +908,8 @@ split_tree (tree in, tree type, enum tre if (TREE_CODE (in) == INTEGER_CST || TREE_CODE (in) == REAL_CST || TREE_CODE (in) == FIXED_CST) *litp = in; + else if (TREE_CONSTANT (in)) + *conp = in; else if (TREE_CODE (in) == code || ((! FLOAT_TYPE_P (TREE_TYPE (in)) || flag_associative_math) && ! SAT_FIXED_POINT_TYPE_P (TREE_TYPE (in)) @@ -956,8 +958,6 @@ split_tree (tree in, tree type, enum tre if (neg_var_p && var) *minus_varp = var, var = 0; } - else if (TREE_CONSTANT (in)) - *conp = in; else if (TREE_CODE (in) == BIT_NOT_EXPR && code == PLUS_EXPR) { So, the problem happens on typedef unsigned _BitInt (__SIZEOF_INT__ * __CHAR_BIT__ - 1) T; T a, b; void foo (void) { b = (T) ((a | (-1U >> 1)) >> 1 | (a | 5) << 4); } when fold_binary_loc is called on (unsigned _BitInt(31)) a << 4 | 80 and (unsigned _BitInt(31)) (2147483647 >> 1), but the important part is that the op0 has the unsigned _BitInt(31) type, while op1 is NOP_EXPR to that type from RSHIFT_EXPR done on T type (the typedef). Soon BIT_IOR_EXPR folding is called on (unsigned _BitInt(31)) a << 4 and 2147483647 >> 1 | 80 where the latter is all in T type (fold_binary_loc does STRIP_NOPS). Because split_tree prefers same code over TREE_CONSTANT, this splits it into the LSHIFT_EXPR var0, RSHIFT_EXPR con1 (because it is TREE_CONSTANT) and the T type 80 literal in lit1, everything else is NULL. As there are 3 objects, it reassociates. We first associate_tree the 0 vs. 1 cases, but that just moves the *1 into *0 because their counterparts are NULL. Both the RSHIFT_EXPR and INTEGER_CST 80 have T type but atype is the build_bitint_type non-typedef type, so 11835 /* Eliminate lit0 and minus_lit0 to con0 and minus_con0. */ 11836 con0 = associate_trees (loc, con0, lit0, code, atype); returns NOP_EXPR of the RSHIFT_EXPR | INTEGER_CST. And then we associate_trees the LSHIFT_EXPR with this result and so it recurses infinitely. Perhaps my above patch is an improvement, if we know some subtree is TREE_CONSTANT, all we need is just wait for it to be constant folded (not sure it would always do e.g. because of division by zero or similar) trying to reassociate its parts with other expressions might just split the constants to other spots instead of keeping it together.