https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68317
--- Comment #10 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Jiong Wang from comment #9) > (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. Well, the GIMPLE IL should have _no_ constants with TREE_OVERFLOW set. I even had checking code for that (but it tripped, obviously as you noticed ;)) > 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); > } The constant will be always in-range so it doesn't make much sense in this form. Note also that positive/negative_overflow_infinities are to be preserved, only other overflows need to be dropped here. Yes, a workaround here might be ok in the end but in reality all those other places you identified should be fixed. So the above code should be if (TREE_OVERFLOW_P (min) && ! is_negative_overflow_infinity (min)) min = drop_tree_overflow (min); if (TREE_OVERFLOW_P (max) && ! is_positive_overflow_infinity (max)) max = drop_tree_overflow (max);