Hi Jeff,

On Tue, Dec 19, 2017 at 04:40:23PM -0700, Jeff Law wrote:
> On 12/15/2017 02:16 AM, Segher Boessenkool wrote:
> >> The only way to get into check_simple_exit is via find_simple_exit which
> >> is only called from get_simple_loop_desc.
> >>
> >> And if you're calling get_simple_loop_desc, then there is some kind of
> >> loop structure in place AFAICT that contains this insn which is rather
> >> surprising.
> > 
> > Why?  It *is* a loop!
> Right.  But how was the loop ever considered simple given that kind of
> test?  At one time I managed to convince myself that to trigger the
> calls Aaron is having trouble with we must have already analyzed the
> loop as "simple" and I'm just having a hard time seeing how that could
> be the case given the from of that insn.

loop-iv.c:check_simple_exit has these two relevant things:

1)
  /* It must end in a simple conditional jump.  */
  if (!any_condjump_p (BB_END (exit_bb)))
    return;

any_condjump_p just sees if it is assigning a suitable if_then_else to pc.
It is.  The comment on any_condjump_p says:

/* Return true when insn is a conditional jump.  This function works for
   instructions containing PC sets in PARALLELs.  The instruction may have
   various other effects so before removing the jump you must verify
   onlyjump_p.

   Note that unlike condjump_p it returns false for unconditional jumps.  */

bdnzt and friends are a parallel of a conditional jump, with as condition
checking whether ctr (the "counter register") will reach 0 (or not), and
whether some other condition is true (or not); and as the other arm of the
parallel it decrements ctr.

2)
  /* Test whether the condition is suitable.  */
  if (!(condition = get_condition (BB_END (ein->src), &at, false, false)))
    return;

... and that gets into trouble already: it gets the condition just fine,
but then it calls canonicalize_condition on that, which cannot handle it.
Which is what Aaron's patch fixes.

> >> However, I'm still concerned about how we got to a point where this is
> >> happening.  So while we can fix canonicalize_condition to reject this
> >> form (and you can argue we should and I'd generally agree with you), it
> >> could well be papering over a problem earlier.
> > 
> > canonicalize_condition does not do what its documentation says it does.
> > Fixing that is not papering over a problem.  Of course there could be a
> > problem elsewhere, sure.  But *this* problem is blocking Aaron's other
> > patches right now (which are approved and ready to go in).
> Given that I don't think we should be getting into
> canonicalize_condition at all, "fixing it" *is* papering over the problem.
> 
> So I think the way forward is to show that the way we're getting into
> canonicalize_condition is reasonable/valid.  Once that happens we can go
> forward with Aaron's patch.

Let me just paste all of get_condition then (it is very short):

rtx
get_condition (rtx_insn *jump, rtx_insn **earliest, int allow_cc_mode,
               int valid_at_insn_p)
{
  rtx cond;
  int reverse;
  rtx set;

  /* If this is not a standard conditional jump, we can't parse it.  */
  if (!JUMP_P (jump)
      || ! any_condjump_p (jump))
    return 0;
  set = pc_set (jump);

  cond = XEXP (SET_SRC (set), 0);

  /* If this branches to JUMP_LABEL when the condition is false, reverse
     the condition.  */
  reverse
    = GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
      && label_ref_label (XEXP (SET_SRC (set), 2)) == JUMP_LABEL (jump);

  return canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX,
                                 allow_cc_mode, valid_at_insn_p);
}

All of this is totally reasonable and expected; "cond" is an AND of two
things, which canonicalize_condition cannot handle, so it should return
NULL.


Segher

Reply via email to