https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84873
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- Or rather it looks like a tree sharing issue. The COND_EXPR is created via fold_binary_op_with_conditional_arg when folding (unsigned int) (long int) (1.0e+0 + 1.000000000000000055511151231257827021181583404541015625e-1) - (unsigned int) (n9 == 0) which is created via /* Contract negates. */ /* A + (-B) -> A - B */ (simplify (plus:c @0 (convert? (negate @1))) /* Apply STRIP_NOPS on the negate. */ (if (tree_nop_conversion_p (type, TREE_TYPE (@1)) && !TYPE_OVERFLOW_SANITIZED (type)) (with { tree t1 = type; if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type) != TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1))) t1 = TYPE_OVERFLOW_WRAPS (type) ? type : TREE_TYPE (@1); } (convert (minus (convert:t1 @0) (convert:t1 @1)))))) which in the end is reached via the gimplify_expr langhook doing 243 if (!VECTOR_TYPE_P (TREE_TYPE (*op1_p)) 244 && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)), 245 unsigned_type_node) 246 && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)), 247 integer_type_node)) 248 *op1_p = convert (unsigned_type_node, *op1_p); and #9 0x0000000000a40070 in convert_to_integer_1 ( type=<integer_type 0x7ffff68ac690 unsigned int>, expr=<plus_expr 0x7ffff69c1938>, dofold=true) at /space/rguenther/src/svn/early-lto-debug/gcc/convert.c:889 889 expr, inprec, outprec, dofold); (gdb) l 884 || targetm.truly_noop_truncation (outprec, inprec) 885 || inprec > TYPE_PRECISION (TREE_TYPE (arg0)) 886 || inprec > TYPE_PRECISION (TREE_TYPE (arg1))) 887 { 888 tree tem = do_narrow (loc, ex_form, type, arg0, arg1, 889 expr, inprec, outprec, dofold); and this folding ends up creating tree sharing of (unsigned int) (long int) (1.0e+0 + 1.000000000000000055511151231257827021181583404541015625e-1) which is TREE_CONSTANT: /* This transformation is only worthwhile if we don't have to wrap ARG in a SAVE_EXPR and the operation can be simplified without recursing on at least one of the branches once its pushed inside the COND_EXPR. */ if (!TREE_CONSTANT (arg) && (TREE_SIDE_EFFECTS (arg) || TREE_CODE (arg) == COND_EXPR || TREE_CODE (arg) == VEC_COND_EXPR || TREE_CONSTANT (true_value) || TREE_CONSTANT (false_value))) return NULL_TREE; ... /* Check that we have simplified at least one of the branches. */ if (!TREE_CONSTANT (arg) && !TREE_CONSTANT (lhs) && !TREE_CONSTANT (rhs)) return NULL_TREE; but of course saying this is TREE_CONSTANT is somewhat of a lie because with -frounding-math it depends on the rounding mode! Which also means in this case the folding isn't quite worthwhile. I'm somewhat hesitant to do sth like Index: gcc/tree.c =================================================================== --- gcc/tree.c (revision 258552) +++ gcc/tree.c (working copy) @@ -4682,8 +4682,9 @@ build2 (enum tree_code code, tree tt, tr /* Expressions without side effects may be constant if their arguments are as well. */ - constant = (TREE_CODE_CLASS (code) == tcc_comparison - || TREE_CODE_CLASS (code) == tcc_binary); + constant = ((TREE_CODE_CLASS (code) == tcc_comparison + || TREE_CODE_CLASS (code) == tcc_binary) + && (!FLOAT_TYPE_P (TREE_TYPE (arg1)) || !flag_rounding_math)); read_only = 1; side_effects = TREE_SIDE_EFFECTS (t); at this point though. A better localized fix would be Index: gcc/c-family/c-gimplify.c =================================================================== --- gcc/c-family/c-gimplify.c (revision 258552) +++ gcc/c-family/c-gimplify.c (working copy) @@ -245,7 +245,15 @@ c_gimplify_expr (tree *expr_p, gimple_se unsigned_type_node) && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)), integer_type_node)) - *op1_p = convert (unsigned_type_node, *op1_p); + { + /* ??? Do not use convert () here or fold arbitrary trees + since folding can introduce tree sharing which is not + allowed during gimplification. */ + if (TREE_CODE (*op1_p) == INTEGER_CST) + *op1_p = fold_convert (unsigned_type_node, *op1_p); + else + *op1_p = build1 (NOP_EXPR, unsigned_type_node, *op1_p); + } break; }