https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68317
--- Comment #9 from Jiong Wang <jiwang at gcc dot gnu.org> --- (In reply to Richard Biener from comment #7) > (In reply to Jiong Wang from comment #6) > > Created attachment 36741 [details] > > prototype-fix > > > > diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c > > index b614412..55a6334 100644 > > --- a/gcc/tree-ssa-loop-manip.c > > +++ b/gcc/tree-ssa-loop-manip.c > > @@ -136,6 +136,11 @@ create_iv (tree base, tree step, tree var, struct loop > > *loop, > > gsi_insert_seq_on_edge_immediate (pe, stmts); > > > > phi = create_phi_node (vb, loop->header); > > + if (TREE_OVERFLOW (initial) > > + && TREE_CODE (initial) == INTEGER_CST > > + && int_fits_type_p (initial, TREE_TYPE (vb))) > > + initial = drop_tree_overflow (initial); > > + > > add_phi_arg (phi, initial, loop_preheader_edge (loop), UNKNOWN_LOCATION); > > add_phi_arg (phi, va, loop_latch_edge (loop), UNKNOWN_LOCATION); > > } > > I think it's better to track down where the constant is generated. I > see initial is created by > > initial = force_gimple_operand (base, &stmts, true, var); > > thus likely base is already the same constant (passed from the caller). > > I usually set a breakpoint on the return statement of ggc_internal_alloc > conditional on the return value being the tree with the overflow. > > Once the overflow value is returned from fold_* () it should be stripped > off its overflow flag. Unconditionally so with just > > if (TREE_OVERFLOW_P (..)) > .. = drop_tree_overflow (..); Richard, After further investigation on where the overflow flag comes from. I found there are too many possibility. For example, for the testcase reported in PR68326, it's originated at fully_constant_expression, at tree-ssa-pre.c when handling tcc_unary, the fold_unary will set overflag flag. While for the testcase in this PR, there are quite a few OVF variables, For the one caused the ICE, the OVF is inherited from another OVF variable and the most early I can track down is at tree-ssa-ccp.c, tree variable "simplified" is simplifed by gimple-fold infrastructure, and conclude to be overflowed which is correct (C source code is print(..."0x%08x...", (0xff4 + i) * 0x100000..., the multiply are assumed to be generating signed int, thus overflowed.), While my understanding is it's only used to generate warning. So I tested to call drop_tree_overflow, but then later passes will re-calculate the variable, and re-set the overflow flag, for example in chrec_fold*. I don't undertand related code base, and fell it will be dangerous to just call drop_tree_overflow in those places. After a second thinking, this ICE is caused by adjust_range_with_scev getting range with overflowed constants min or max. So given there are too many places to generate OVF, can we just do a check in adjust_range_with_scev, if the constant min or max in the range info can fit into the variable type, then naturally we should treat those OVF as false alarm and drop them? something like the following, which I think can fix the OVF side-effect caused by r230150. diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index e2393e4..56440b1 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4331,6 +4331,16 @@ adjust_range_with_scev (value_range *vr, struct loop *loop, && is_positive_overflow_infinity (max))) return; + if (TREE_CODE (min) == INTEGER_CST + && TREE_OVERFLOW (min) + && int_fits_type_p (min, type)) + min = drop_tree_overflow (min); + + if (TREE_CODE (max) == INTEGER_CST + && TREE_OVERFLOW (max) + && int_fits_type_p (max, type)) + max = drop_tree_overflow (max); + set_value_range (vr, VR_RANGE, min, max, vr->equiv); }