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

Reply via email to