<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi, <div class=""><br class=""></div><div class="">I was reading some loop related code and I don’t quite understand an assertion in <span style="font-family: Monaco; font-size: 11px;" class="">LoopBase<BlockT, LoopT>::getLoopPredecessor().</span></div><div class=""><span style="font-family: Monaco; font-size: 11px;" class=""><br class=""></span></div><div class=""><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114);" class="">/// getLoopPredecessor - If the given loop's header has exactly one unique</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114);" class="">/// predecessor outside the loop, return it. Otherwise return null.</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114);" class="">/// This is less strict that the loop "<span style="text-decoration: underline" class="">preheader</span>" concept, which requires</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114);" class="">/// the predecessor to have exactly one successor.</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114);" class="">///</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(147, 26, 104);" class="">template<span style="color: #000000" class=""><</span>class<span style="color: #000000" class=""> </span><span style="color: #785841" class="">BlockT</span><span style="color: #000000" class="">, </span>class<span style="color: #000000" class=""> </span><span style="color: #785841" class="">LoopT</span><span style="color: #000000" class="">></span></div><div style="margin: 0px; font-size: 11px; font-family: Monaco;" class=""><span style="color: #785841" class="">BlockT</span> *LoopBase<BlockT, LoopT>::getLoopPredecessor() <span style="color: #931a68" class="">const</span> {</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114);" class=""><span style="color: #000000" class="">  </span>// Keep track of nodes outside the loop branching to the header...</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;" class="">  <span style="color: #785841" class="">BlockT</span> *Out = nullptr;</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; min-height: 15px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114);" class=""><span style="color: #000000" class="">  </span>// Loop over the predecessors of the header node...</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;" class="">  <span style="color: #785841" class="">BlockT</span> *Header = getHeader();</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(0, 97, 65);" class=""><span style="color: #000000" class="">  </span><span style="color: #931a68" class="">typedef</span><span style="color: #000000" class=""> </span>GraphTraits<span style="color: #000000" class=""><</span>Inverse<span style="color: #000000" class=""><</span><span style="color: #785841" class="">BlockT</span><span style="color: #000000" class="">*> > </span>InvBlockTraits<span style="color: #000000" class="">;</span></div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(0, 97, 65);" class=""><span style="color: #000000" class="">  </span><span style="color: #931a68" class="">for</span><span style="color: #000000" class=""> (</span><span style="color: #931a68" class="">typename</span><span style="color: #000000" class=""> </span>InvBlockTraits<span style="color: #000000" class="">::</span>ChildIteratorType<span style="color: #000000" class=""> PI =</span></div><div style="margin: 0px; font-size: 11px; font-family: Monaco;" class="">         <span style="color: #006141" class="">InvBlockTraits</span>::child_begin(Header),</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;" class="">         PE = <span style="color: #006141" class="">InvBlockTraits</span>::child_end(Header); PI != PE; ++PI) {</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(0, 97, 65);" class=""><span style="color: #000000" class="">    </span><span style="color: #931a68" class="">typename</span><span style="color: #000000" class=""> </span>InvBlockTraits<span style="color: #000000" class="">::</span>NodeType<span style="color: #000000" class=""> *N = *PI;</span></div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114);" class=""><span style="color: #000000" class="">    </span><span style="color: #931a68" class="">if</span><span style="color: #000000" class=""> (!contains(N)) {     </span>// If the block is not in the loop...</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;" class="">      <span style="color: #931a68" class="">if</span> (Out && Out != N)</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114);" class=""><span style="color: #000000" class="">        </span><span style="color: #931a68" class="">return</span><span style="color: #000000" class=""> nullptr;     </span>// Multiple predecessors outside the loop</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;" class="">      Out = N;</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;" class="">    }</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;" class="">  }</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; min-height: 15px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114);" class=""><span style="color: #000000" class="">  </span>// Make sure there is only one exit out of the <span style="text-decoration: underline" class="">preheader</span>.</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(57, 51, 255);" class=""><span style="color: #000000" class="">  assert(Out && </span>"Header of loop has no predecessors from outside loop?"<span style="color: #000000" class="">);</span></div><div style="margin: 0px; font-size: 11px; font-family: Monaco;" class="">  <span style="color: #931a68" class="">return</span> Out;</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;" class="">}</div></div><div style="margin: 0px; font-size: 11px; font-family: Monaco;" class=""><br class=""></div><div style="margin: 0px;" class="">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). </div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px;" class="">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?</div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px;" class="">thanks,</div><div style="margin: 0px;" class="">chen  </div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; font-family: Monaco;" class=""><br class=""></div></body></html>