On Tue, 16 Jul 2024, Tamar Christina wrote:

> Hi All,
> 
> As shown in PR115936 SCEV and IVOPTS create an invalidate IV when the IV is
> a pointer type:
> 
> ivtmp.39_65 = ivtmp.39_59 + 0B;
> 
> where the IVs are DI mode and the offset is a pointer.
> This comes from this weird candidate:
> 
> Candidate 8:
>   Var befor: ivtmp.39_59
>   Var after: ivtmp.39_65
>   Incr POS: before exit test
>   IV struct:
>     Type:       sizetype
>     Base:       0
>     Step:       0B
>     Biv:        N
>     Overflowness wrto loop niter:       No-overflow
> 
> This IV was always created just ended up not being used. 
> 
> This is created by SCEV.
> 
> simple_iv_with_niters in the case where no CHREC is found creates an IV with
> base == ev, offset == 0;
> 
> however in this case EV is a POINTER_PLUS_EXPR and so the type is a pointer.
> it ends up creating an unusable expression.
> 
> However IVOPTS also has code to refold expression in case the IV is a pointer.
> For most cases it uses basetype to fold both operand but the 0 case it 
> ommitted
> it.  This leads to us creating a PLUS expression with mismatched types.
> 
> This fixes that bug as well.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu,
> x86_64-pc-linux-gnu -m32, -m64 and no issues.
> 
> Ok for master?
> 
> Thanks,
> Tamar
> 
> gcc/ChangeLog:
> 
>       PR tree-optimization/115936
>       * tree-scalar-evolution.cc (simple_iv_with_niters): Use sizetype for
>       pointers.
>       * tree-ssa-loop-ivopts.cc (add_iv_candidate_for_use): Use same type for
>       both operands.
> 
> ---
> diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc
> index 
> 5aa95a2497a317f9b43408ce78a2d50c20151314..abb2bad777375889d6c980b54d60699672fd5742
>  100644
> --- a/gcc/tree-scalar-evolution.cc
> +++ b/gcc/tree-scalar-evolution.cc
> @@ -3243,7 +3243,11 @@ simple_iv_with_niters (class loop *wrto_loop, class 
> loop *use_loop,
>    if (tree_does_not_contain_chrecs (ev))
>      {
>        iv->base = ev;
> -      iv->step = build_int_cst (TREE_TYPE (ev), 0);
> +      tree ev_type = TREE_TYPE (ev);
> +      if (POINTER_TYPE_P (ev_type))
> +     ev_type = sizetype;
> +
> +      iv->step = build_int_cst (ev_type, 0);
>        iv->no_overflow = true;
>        return true;
>      }

This hunk is OK.

> diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
> index 
> c3218a3e8eedbb8d0a7f14c01eeb069cb6024c29..fe130541526e74fb80fee633f6c96b41437aa1c1
>  100644
> --- a/gcc/tree-ssa-loop-ivopts.cc
> +++ b/gcc/tree-ssa-loop-ivopts.cc
> @@ -3529,7 +3529,8 @@ add_iv_candidate_for_use (struct ivopts_data *data, 
> struct iv_use *use)
>    basetype = TREE_TYPE (iv->base);
>    if (POINTER_TYPE_P (basetype))
>      basetype = sizetype;
> -  record_common_cand (data, build_int_cst (basetype, 0), iv->step, use);
> +  record_common_cand (data, build_int_cst (basetype, 0),
> +                   fold_convert (basetype, iv->step), use);

But this looks redundant?  iv->step should already be sizetype for a 
pointer base?

Thanks,
Richard.

>    /* Compare the cost of an address with an unscaled index with the cost of
>      an address with a scaled index and add candidate if useful.  */
> 
> 
> 
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to