https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68317

--- Comment #6 from Jiong Wang <jiwang at gcc dot gnu.org> ---
Created attachment 36741
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36741&action=edit
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);
 }

Reply via email to