This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/68317] [6 regression] ice in set_value_range, at tree-vrp.c:380


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 (..);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]