Hi,

> I'm investigating an ICE in loop-iv.c:get_biv_step().  I hope you can shed 
> some light on what the correct fix would be.
> 
> The ICE happens when processing:
> ==
> (insn 111 (set (reg:SI 304)
>                (plus (subreg:SI (reg:DI 251) 4)
>                      (const_int 1))))
> 
> (insn 177 (set (subreg:SI (reg:DI 251))
>                (reg:SI 304)))
> ==
> 
> The code like the above does not occur on current mainline early enough for 
> loop-iv.c to catch it.  The subregs above are produced by Tom's (CC'ed) 
> extension elimination pass (scheduled before fwprop1) which is not in 
> mainline yet [*].
> 
> The failure is due to assert in loop-iv.c:get_biv_step():
> ==
> gcc_assert ((*inner_mode == *outer_mode) != (*extend != UNKNOWN));
> ==
> i.e., inner and outer modes can differ iff there's an extend in the chain. 
> 
> Get_biv_step_1() starts with insn 177, then gets to insn 111, then loops back 
> to insn 177 at which point it stops and returns GRD_MAYBE_BIV and sets:
> 
> * outer_mode == DImode == natural mode of (reg A);
> 
> * inner_mode == SImode == mode of (subreg (reg A)), set in get_biv_step_1:
> ==
>   if (GET_CODE (next) == SUBREG)
>     {
>       enum machine_mode amode = GET_MODE (next);
> 
>       if (GET_MODE_SIZE (amode) > GET_MODE_SIZE (*inner_mode))
>       return false;
> 
>       *inner_mode = amode;
>       *inner_step = simplify_gen_binary (PLUS, outer_mode,
>                                        *inner_step, *outer_step);
>       *outer_step = const0_rtx;
>       *extend = UNKNOWN;
>     }
> ==
> 
> * extend == UNKNOWN as there are no extensions in the chain.
> 
> It seems to me that computations of outer_mode and extend are correct, I'm 
> not sure about inner_mode.
> 
> Zdenek, what do you think is the right way to handle the above case in loop 
> analysis?

loop iv analysis currently does not handle assignments to subregs; we test for
that in iv_get_reaching_def, but the corresponding test is missing in
latch_dominating_def.  I.e., a simple fix is to add

if (single_rd && (DF_REF_FLAGS (single_rd) & DF_REF_READ_WRITE))
  return false;

at the end of latch_dominating_def.  On the other hand, this means that the
loops using the code like above will not get optimized.  So, if such a code
gets produced consistently for a large fraction of the loops, it would be
necessary to teach loop-iv to analyze induction variables represented in
subregs.  This would mean a more involved rewrite of loop-iv, though,

Zdenek

Reply via email to