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

Reply via email to