[LLVMdev] Is loop header required to have at least one predecessor outside the loop?

Sanjoy Das sanjoy at playingwithpointers.com
Wed Jul 22 23:32:11 PDT 2015


On Wed, Jul 22, 2015 at 9:47 PM, Chen Li <meloli87 at gmail.com> wrote:
> Hi,
>
> I was reading some loop related code and I don’t quite understand an
> assertion in LoopBase<BlockT, LoopT>::getLoopPredecessor().
>
> /// getLoopPredecessor - If the given loop's header has exactly one unique
> /// predecessor outside the loop, return it. Otherwise return null.
> /// This is less strict that the loop "preheader" concept, which requires
> /// the predecessor to have exactly one successor.
> ///
> template<class BlockT, class LoopT>
> BlockT *LoopBase<BlockT, LoopT>::getLoopPredecessor() const {
>   // Keep track of nodes outside the loop branching to the header...
>   BlockT *Out = nullptr;
>
>   // Loop over the predecessors of the header node...
>   BlockT *Header = getHeader();
>   typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
>   for (typename InvBlockTraits::ChildIteratorType PI =
>          InvBlockTraits::child_begin(Header),
>          PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) {
>     typename InvBlockTraits::NodeType *N = *PI;
>     if (!contains(N)) {     // If the block is not in the loop...
>       if (Out && Out != N)
>         return nullptr;     // Multiple predecessors outside the loop
>       Out = N;
>     }
>   }
>
>   // Make sure there is only one exit out of the preheader.
>   assert(Out && "Header of loop has no predecessors from outside loop?");
>   return Out;
> }
>
> The function tries to find if there’s an unique predecessor outside of the
> loop for the loop header. At the very bottom, it asserts the loop header
> must have at least one such predecessor outside the loop (there’s an early
> return for cases there are more than one predecessors). But is it correct?
> For normal cases, I think it is. But what if the loop is dead code and
> unreachable? If you call this function in the middle of some kind dead code
> elimination, there are chances you will hit the assertion (in fact, I did
> hit it and crash the compiler).

I don't fully understand this area but from reading the code, I think
the invariants are:

 * "Loop" instances are only created for reachable loops.  This is
because the loops are gathered by doing a traversal from the dom tree
node and this traversal won't see any unreachable loops.

 * If your pass breaks / modifies edges in the CFG, it must cause a
recomputation of the loop nest.  IOW, if you are able to hit this
assert, then it means you have somehow ended up with a "stale" Loop
instance.

-- Sanjoy

>
> I removed this assertion and the build still passed all make check-all
> tests. So I don’t think there is anything depend on this or llvm has missed
> some test cases here. Does anyone know if there is a specific reason to have
> this assertion?
>
> thanks,
> chen
>
>
>
>
>
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>




More information about the llvm-dev mailing list