https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68317
--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Jiong Wang from comment #6) > Created attachment 36741 [details] > prototype-fix > > (In reply to Richard Biener from comment #3) > > (gdb) p debug_generic_expr (max) > > 4294443008(OVF) > > + # ivtmp.8_8 = PHI <4294443008(OVF)(2), ivtmp.8_11(4)> > > + _5 = (int) ivtmp.8_8; > > fn2 (_5); > > - i_7 = i_1 + -1; > > > > <bb 4>: > > + ivtmp.8_11 = ivtmp.8_8 - 524288; > > goto <bb 3>; > > > > } > > > > note that the infinite loop contains undefined overflow. > > > > IVOPTs should simply strip the overflow flag (using drop_tree_overflow). > > And my further investigation shows PR68326 is caused by the same issue. > > # ivtmp.8_8 = PHI <4294443008(OVF)(2), ivtmp.8_11(4)> > > the new phi node destination is with unsigned int type, the constant > value 4294443008 can fit into it, it's marked as OVF because > it's treated as signed type. For the simple testcase in PR68326, > the overflow number is 4294967286 which is -10, while there happen be > another signed integer with initial value -10. So, looks like the unsigned > 4294967286 somehow inherited the signed type from the other value in some > tree pass, then some valid constant is marked with OVF unnecessarily. > > Anyway, below is my fix, does it looks the correct approach to you? > > drop_tree_overflow is invoked during create_iv, if the constant can actually > fit into the type. I only checked INTEGER_CST, not for others like REAL, as I > though they won't suffer from the unsigned/signed type issue. > > x86-64 bootstrap is OK with this patch, will do more testing if the approach > is OK. > > 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 (..);