<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Aug 23, 2017, at 10:38 AM, Jakub (Kuba) Kuderski <<a href="mailto:kubakuderski@gmail.com" class="">kubakuderski@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="auto" class="">Hi Adrian,<div dir="auto" class=""><br class=""></div><div dir="auto" class="">Expensive checks make .verifyDominatorTree to run O(n^3) sibling property verification, which can cause some major slowndowns on big CFG's. </div></div></div></blockquote><div><br class=""></div><div>Is that something that changed recently? Do you know when?</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div dir="auto" class="">I believe that the question is how expensive we want the expensive checks to be -- if that' unacceptable, then we can introduce a new flag just for that.</div></div></div></blockquote><div><br class=""></div><div>It depends on what the other options are. If the new, more expensive checks cannot be improved to perform better, we should decide whether it's worth the extra resources on the builders.</div><div><br class=""></div><div>-- adrian</div><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div dir="auto" class=""><br class=""></div><div dir="auto" class="">Please let me know what you think.</div><div dir="auto" class=""><br class=""></div><div dir="auto" class="">Best,</div><div dir="auto" class="">Kuba</div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Aug 23, 2017 19:27, "Adrian Prantl" <<a href="mailto:aprantl@apple.com" class="">aprantl@apple.com</a>> wrote:<br type="attribution" class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">A lot of jobs on green dragon are currently timing out, for example:<br class="">
<br class="">
<a href="http://green.lab.llvm.org/green/job/clang-stage1-cmake-RA-expensive/buildTimeTrend" rel="noreferrer" target="_blank" class="">http://green.lab.llvm.org/<wbr class="">green/job/clang-stage1-cmake-<wbr class="">RA-expensive/buildTimeTrend</a><br class="">
<br class="">
I logged into one of the build nodes and found several instances of clang, all running for >15min and attached LLDB to it:<br class="">
<br class="">
They were all stuck in llvm::DominatorTree::<wbr class="">verifyDomTree().<br class="">
<br class="">
(lldb) bt<br class="">
* thread #1: tid = 0x1607b1d, 0x0000000108ea1776 clang-6.0`llvm::<wbr class="">DomTreeNodeBase<llvm::<wbr class="">BasicBlock>::compare(llvm::<wbr class="">DomTreeNodeBase<llvm::<wbr class="">BasicBlock> const*) const + 118, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP<br class="">
  * frame #0: 0x0000000108ea1776 clang-6.0`llvm::<wbr class="">DomTreeNodeBase<llvm::<wbr class="">BasicBlock>::compare(llvm::<wbr class="">DomTreeNodeBase<llvm::<wbr class="">BasicBlock> const*) const + 118<br class="">
    frame #1: 0x0000000108ea1fb7 clang-6.0`llvm::<wbr class="">DominatorTreeBase<llvm::<wbr class="">BasicBlock, false>::compare(llvm::<wbr class="">DominatorTreeBase<llvm::<wbr class="">BasicBlock, false> const&) const + 327<br class="">
    frame #2: 0x0000000108eac121 clang-6.0`llvm::DominatorTree:<wbr class="">:verifyDomTree() const + 225<br class="">
    frame #3: 0x0000000108f060b9 clang-6.0`llvm::PMDataManager:<wbr class="">:verifyPreservedAnalysis(llvm:<wbr class="">:Pass*) + 313<br class="">
    frame #4: 0x00000001089e6ccb clang-6.0`llvm::LPPassManager:<wbr class="">:runOnFunction(llvm::Function&<wbr class="">) + 1515<br class="">
    frame #5: 0x0000000108f09ea3 clang-6.0`llvm::FPPassManager:<wbr class="">:runOnFunction(llvm::Function&<wbr class="">) + 547<br class="">
    frame #6: 0x0000000108f0a103 clang-6.0`llvm::FPPassManager:<wbr class="">:runOnModule(llvm::Module&) + 51<br class="">
    frame #7: 0x0000000108f0a64e clang-6.0`llvm::legacy::<wbr class="">PassManagerImpl::run(llvm::<wbr class="">Module&) + 958<br class="">
    frame #8: 0x000000010971c264 clang-6.0`clang::<wbr class="">EmitBackendOutput(clang::<wbr class="">DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::DataLayout const&, llvm::Module*, clang::BackendAction, std::__1::unique_ptr<llvm::<wbr class="">raw_pwrite_stream, std::__1::default_delete<llvm:<wbr class="">:raw_pwrite_stream> >) + 15444<br class="">
    frame #9: 0x0000000109974633 clang-6.0`clang::<wbr class="">BackendConsumer::<wbr class="">HandleTranslationUnit(clang::<wbr class="">ASTContext&) + 947<br class="">
    frame #10: 0x000000010a3c2ab5 clang-6.0`clang::ParseAST(<wbr class="">clang::Sema&, bool, bool) + 469<br class="">
    frame #11: 0x0000000109bfcfec clang-6.0`clang::<wbr class="">FrontendAction::Execute() + 76<br class="">
    frame #12: 0x0000000109bb6d91 clang-6.0`clang::<wbr class="">CompilerInstance::<wbr class="">ExecuteAction(clang::<wbr class="">FrontendAction&) + 1217<br class="">
    frame #13: 0x0000000109c6401a clang-6.0`clang::<wbr class="">ExecuteCompilerInvocation(<wbr class="">clang::CompilerInstance*) + 4970<br class="">
    frame #14: 0x0000000107c1c732 clang-6.0`cc1_main(llvm::<wbr class="">ArrayRef<char const*>, char const*, void*) + 1394<br class="">
    frame #15: 0x0000000107c1ade3 clang-6.0`main + 11939<br class="">
    frame #16: 0x00007fff8fa725ad libdyld.dylib`start + 1<br class="">
<br class="">
Since you contributed a lot of changes to this code recently, do you think that this could be related to your commits? You should be able to reproduce this by building with expensive checks enabled and watching out for the builds of the ASAN testcases. ("Generating ASAN_.*_TEST_.*" in the build log)<br class="">
<br class="">
thanks,<br class="">
Adrian<br class="">
<br class="">
> On Aug 22, 2017, at 9:30 AM, Jakub Kuderski via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a>> wrote:<br class="">
><br class="">
> Author: kuhar<br class="">
> Date: Tue Aug 22 09:30:21 2017<br class="">
> New Revision: 311467<br class="">
><br class="">
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=311467&view=rev" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project?rev=311467&view=rev</a><br class="">
> Log:<br class="">
> [ADCE][Dominators] Reapply: Teach ADCE to preserve dominators<br class="">
><br class="">
> Summary:<br class="">
> This patch teaches ADCE to preserve both DominatorTrees and PostDominatorTrees.<br class="">
><br class="">
> This is reapplies the original patch r311057 that was reverted in r311381.<br class="">
> The previous version wasn't using the batch update api for updating dominators,<br class="">
> which in vary rare cases caused assertion failures.<br class="">
><br class="">
> This also fixes PR34258.<br class="">
><br class="">
> Reviewers: dberlin, chandlerc, sanjoy, davide, grosser, brzycki<br class="">
><br class="">
> Reviewed By: davide<br class="">
><br class="">
> Subscribers: grandinj, zhendongsu, llvm-commits, david2050<br class="">
><br class="">
> Differential Revision: <a href="https://reviews.llvm.org/D35869" rel="noreferrer" target="_blank" class="">https://reviews.llvm.org/<wbr class="">D35869</a><br class="">
><br class="">
> Added:<br class="">
>    llvm/trunk/test/Transforms/<wbr class="">ADCE/2017-08-21-DomTree-<wbr class="">deletions.ll<br class="">
>    llvm/trunk/test/Transforms/<wbr class="">ADCE/domtree-DoubleDeletion.ll<br class="">
>    llvm/trunk/test/Transforms/<wbr class="">ADCE/unreachable.ll<br class="">
> Modified:<br class="">
>    llvm/trunk/lib/Transforms/<wbr class="">Scalar/ADCE.cpp<br class="">
><br class="">
> Modified: llvm/trunk/lib/Transforms/<wbr class="">Scalar/ADCE.cpp<br class="">
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ADCE.cpp?rev=311467&r1=311466&r2=311467&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/llvm/trunk/lib/<wbr class="">Transforms/Scalar/ADCE.cpp?<wbr class="">rev=311467&r1=311466&r2=<wbr class="">311467&view=diff</a><br class="">
> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
> --- llvm/trunk/lib/Transforms/<wbr class="">Scalar/ADCE.cpp (original)<br class="">
> +++ llvm/trunk/lib/Transforms/<wbr class="">Scalar/ADCE.cpp Tue Aug 22 09:30:21 2017<br class="">
> @@ -27,6 +27,7 @@<br class="">
> #include "llvm/IR/BasicBlock.h"<br class="">
> #include "llvm/IR/CFG.h"<br class="">
> #include "llvm/IR/DebugInfoMetadata.h"<br class="">
> +#include "llvm/IR/Dominators.h"<br class="">
> #include "llvm/IR/IRBuilder.h"<br class="">
> #include "llvm/IR/InstIterator.h"<br class="">
> #include "llvm/IR/Instructions.h"<br class="">
> @@ -89,6 +90,10 @@ struct BlockInfoType {<br class="">
><br class="">
> class AggressiveDeadCodeElimination {<br class="">
>   Function &F;<br class="">
> +<br class="">
> +  // ADCE does not use DominatorTree per se, but it updates it to preserve the<br class="">
> +  // analysis.<br class="">
> +  DominatorTree &DT;<br class="">
>   PostDominatorTree &PDT;<br class="">
><br class="">
>   /// Mapping of blocks to associated information, an element in BlockInfoVec.<br class="">
> @@ -157,9 +162,10 @@ class AggressiveDeadCodeElimination {<br class="">
>   void makeUnconditional(BasicBlock *BB, BasicBlock *Target);<br class="">
><br class="">
> public:<br class="">
> -  AggressiveDeadCodeElimination(<wbr class="">Function &F, PostDominatorTree &PDT)<br class="">
> -      : F(F), PDT(PDT) {}<br class="">
> -  bool performDeadCodeElimination();<br class="">
> + AggressiveDeadCodeElimination(<wbr class="">Function &F, DominatorTree &DT,<br class="">
> +                               PostDominatorTree &PDT)<br class="">
> +     : F(F), DT(DT), PDT(PDT) {}<br class="">
> + bool performDeadCodeElimination();<br class="">
> };<br class="">
> }<br class="">
><br class="">
> @@ -557,14 +563,34 @@ void AggressiveDeadCodeElimination:<wbr class="">:upda<br class="">
>     }<br class="">
>     assert((PreferredSucc && PreferredSucc->PostOrder > 0) &&<br class="">
>            "Failed to find safe successor for dead branch");<br class="">
> +<br class="">
> +    // Collect removed successors to update the (Post)DominatorTrees.<br class="">
> +    SmallPtrSet<BasicBlock *, 4> RemovedSuccessors;<br class="">
>     bool First = true;<br class="">
>     for (auto *Succ : successors(BB)) {<br class="">
> -      if (!First || Succ != PreferredSucc->BB)<br class="">
> +      if (!First || Succ != PreferredSucc->BB) {<br class="">
>         Succ->removePredecessor(BB);<br class="">
> -      else<br class="">
> +        RemovedSuccessors.insert(Succ)<wbr class="">;<br class="">
> +      } else<br class="">
>         First = false;<br class="">
>     }<br class="">
>     makeUnconditional(BB, PreferredSucc->BB);<br class="">
> +<br class="">
> +    // Inform the dominators about the deleted CFG edges.<br class="">
> +    SmallVector<DominatorTree::<wbr class="">UpdateType, 4> DeletedEdges;<br class="">
> +    for (auto *Succ : RemovedSuccessors) {<br class="">
> +      // It might have happened that the same successor appeared multiple times<br class="">
> +      // and the CFG edge wasn't really removed.<br class="">
> +      if (Succ != PreferredSucc->BB) {<br class="">
> +        DEBUG(dbgs() << "ADCE: (Post)DomTree edge enqueued for deletion"<br class="">
> +                     << BB->getName() << " -> " << Succ->getName() << "\n");<br class="">
> +        DeletedEdges.push_back({<wbr class="">DominatorTree::Delete, BB, Succ});<br class="">
> +      }<br class="">
> +    }<br class="">
> +<br class="">
> +    DT.applyUpdates(DeletedEdges);<br class="">
> +    PDT.applyUpdates(DeletedEdges)<wbr class="">;<br class="">
> +<br class="">
>     NumBranchesRemoved += 1;<br class="">
>   }<br class="">
> }<br class="">
> @@ -609,6 +635,9 @@ void AggressiveDeadCodeElimination:<wbr class="">:make<br class="">
>   InstInfo[NewTerm].Live = true;<br class="">
>   if (const DILocation *DL = PredTerm->getDebugLoc())<br class="">
>     NewTerm->setDebugLoc(DL);<br class="">
> +<br class="">
> +  InstInfo.erase(PredTerm);<br class="">
> +  PredTerm->eraseFromParent();<br class="">
> }<br class="">
><br class="">
> //===-------------------------<wbr class="">------------------------------<wbr class="">---------------===//<br class="">
> @@ -617,13 +646,16 @@ void AggressiveDeadCodeElimination:<wbr class="">:make<br class="">
> //<br class="">
> //===-------------------------<wbr class="">------------------------------<wbr class="">---------------===//<br class="">
> PreservedAnalyses ADCEPass::run(Function &F, FunctionAnalysisManager &FAM) {<br class="">
> +  auto &DT = FAM.getResult<<wbr class="">DominatorTreeAnalysis>(F);<br class="">
>   auto &PDT = FAM.getResult<<wbr class="">PostDominatorTreeAnalysis>(F);<br class="">
> -  if (!<wbr class="">AggressiveDeadCodeElimination(<wbr class="">F, PDT).<wbr class="">performDeadCodeElimination())<br class="">
> +  if (!<wbr class="">AggressiveDeadCodeElimination(<wbr class="">F, DT, PDT).<wbr class="">performDeadCodeElimination())<br class="">
>     return PreservedAnalyses::all();<br class="">
><br class="">
>   PreservedAnalyses PA;<br class="">
>   PA.preserveSet<CFGAnalyses>();<br class="">
>   PA.preserve<GlobalsAA>();<br class="">
> +  PA.preserve<<wbr class="">DominatorTreeAnalysis>();<br class="">
> +  PA.preserve<<wbr class="">PostDominatorTreeAnalysis>();<br class="">
>   return PA;<br class="">
> }<br class="">
><br class="">
> @@ -637,14 +669,23 @@ struct ADCELegacyPass : public FunctionP<br class="">
>   bool runOnFunction(Function &F) override {<br class="">
>     if (skipFunction(F))<br class="">
>       return false;<br class="">
> +<br class="">
> +    auto &DT = getAnalysis<<wbr class="">DominatorTreeWrapperPass>().<wbr class="">getDomTree();<br class="">
>     auto &PDT = getAnalysis<<wbr class="">PostDominatorTreeWrapperPass>(<wbr class="">).getPostDomTree();<br class="">
> -    return AggressiveDeadCodeElimination(<wbr class="">F, PDT).<wbr class="">performDeadCodeElimination();<br class="">
> +    return AggressiveDeadCodeElimination(<wbr class="">F, DT, PDT)<br class="">
> +        .performDeadCodeElimination();<br class="">
>   }<br class="">
><br class="">
>   void getAnalysisUsage(AnalysisUsage &AU) const override {<br class="">
> +    // We require DominatorTree here only to update and thus preserve it.<br class="">
> +    AU.addRequired<<wbr class="">DominatorTreeWrapperPass>();<br class="">
>     AU.addRequired<<wbr class="">PostDominatorTreeWrapperPass>(<wbr class="">);<br class="">
>     if (!RemoveControlFlowFlag)<br class="">
>       AU.setPreservesCFG();<br class="">
> +    else {<br class="">
> +      AU.addPreserved<<wbr class="">DominatorTreeWrapperPass>();<br class="">
> +      AU.addPreserved<<wbr class="">PostDominatorTreeWrapperPass>(<wbr class="">);<br class="">
> +    }<br class="">
>     AU.addPreserved<<wbr class="">GlobalsAAWrapperPass>();<br class="">
>   }<br class="">
> };<br class="">
> @@ -653,6 +694,7 @@ struct ADCELegacyPass : public FunctionP<br class="">
> char ADCELegacyPass::ID = 0;<br class="">
> INITIALIZE_PASS_BEGIN(<wbr class="">ADCELegacyPass, "adce",<br class="">
>                       "Aggressive Dead Code Elimination", false, false)<br class="">
> +INITIALIZE_PASS_DEPENDENCY(<wbr class="">DominatorTreeWrapperPass)<br class="">
> INITIALIZE_PASS_DEPENDENCY(<wbr class="">PostDominatorTreeWrapperPass)<br class="">
> INITIALIZE_PASS_END(<wbr class="">ADCELegacyPass, "adce", "Aggressive Dead Code Elimination",<br class="">
>                     false, false)<br class="">
><br class="">
> Added: llvm/trunk/test/Transforms/<wbr class="">ADCE/2017-08-21-DomTree-<wbr class="">deletions.ll<br class="">
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ADCE/2017-08-21-DomTree-deletions.ll?rev=311467&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/llvm/trunk/test/<wbr class="">Transforms/ADCE/2017-08-21-<wbr class="">DomTree-deletions.ll?rev=<wbr class="">311467&view=auto</a><br class="">
> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
> --- llvm/trunk/test/Transforms/<wbr class="">ADCE/2017-08-21-DomTree-<wbr class="">deletions.ll (added)<br class="">
> +++ llvm/trunk/test/Transforms/<wbr class="">ADCE/2017-08-21-DomTree-<wbr class="">deletions.ll Tue Aug 22 09:30:21 2017<br class="">
> @@ -0,0 +1,24 @@<br class="">
> +; RUN: opt < %s -adce | llvm-dis<br class="">
> +; RUN: opt < %s -adce -verify-dom-info | llvm-dis<br class="">
> +<br class="">
> +define void @foo() {<br class="">
> +entry:<br class="">
> +  br label %switch<br class="">
> +switch:                    ; preds = %entry<br class="">
> +  switch i32 undef, label %default [<br class="">
> +    i32 2, label %two<br class="">
> +    i32 5, label %five<br class="">
> +    i32 4, label %four<br class="">
> +  ]<br class="">
> +four:                      ; preds = %switch<br class="">
> +  br label %exit<br class="">
> +five:                      ; preds = %switch<br class="">
> +  br label %exit<br class="">
> +two:                       ; preds = %switch<br class="">
> +  br label %exit<br class="">
> +default:                   ; preds = %switch<br class="">
> +  br label %exit<br class="">
> +exit:                      ; preds = %default, %two, %five, %four<br class="">
> +  ret void<br class="">
> +}<br class="">
> +<br class="">
><br class="">
> Added: llvm/trunk/test/Transforms/<wbr class="">ADCE/domtree-DoubleDeletion.ll<br class="">
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ADCE/domtree-DoubleDeletion.ll?rev=311467&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/llvm/trunk/test/<wbr class="">Transforms/ADCE/domtree-<wbr class="">DoubleDeletion.ll?rev=311467&<wbr class="">view=auto</a><br class="">
> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
> --- llvm/trunk/test/Transforms/<wbr class="">ADCE/domtree-DoubleDeletion.ll (added)<br class="">
> +++ llvm/trunk/test/Transforms/<wbr class="">ADCE/domtree-DoubleDeletion.ll Tue Aug 22 09:30:21 2017<br class="">
> @@ -0,0 +1,39 @@<br class="">
> +; RUN: opt < %s -gvn -simplifycfg -adce | llvm-dis<br class="">
> +; RUN: opt < %s -gvn -simplifycfg -adce -verify-dom-info | llvm-dis<br class="">
> +<br class="">
> +; This test makes sure that the DominatorTree properly handles<br class="">
> +; deletion of edges that go to forward-unreachable regions.<br class="">
> +; In this case, %land.end is already forward unreachable when<br class="">
> +; the DT gets informed about the deletion of %entry -> %land.end.<br class="">
> +<br class="">
> +@a = common global i32 0, align 4<br class="">
> +<br class="">
> +define i32 @main() {<br class="">
> +entry:<br class="">
> +  %retval = alloca i32, align 4<br class="">
> +  store i32 0, i32* %retval, align 4<br class="">
> +  %0 = load i32, i32* @a, align 4<br class="">
> +  %cmp = icmp ne i32 %0, 1<br class="">
> +  br i1 %cmp, label %land.rhs, label %land.end4<br class="">
> +<br class="">
> +land.rhs:                                         ; preds = %entry<br class="">
> +  %1 = load i32, i32* @a, align 4<br class="">
> +  %tobool = icmp ne i32 %1, 0<br class="">
> +  br i1 %tobool, label %land.rhs1, label %land.end<br class="">
> +<br class="">
> +land.rhs1:                                        ; preds = %land.rhs<br class="">
> +  br label %land.end<br class="">
> +<br class="">
> +land.end:                                         ; preds = %land.rhs1, %land.rhs<br class="">
> +  %2 = phi i1 [ false, %land.rhs ], [ true, %land.rhs1 ]<br class="">
> +  %land.ext = zext i1 %2 to i32<br class="">
> +  %conv = trunc i32 %land.ext to i16<br class="">
> +  %conv2 = sext i16 %conv to i32<br class="">
> +  %tobool3 = icmp ne i32 %conv2, 0<br class="">
> +  br label %land.end4<br class="">
> +<br class="">
> +land.end4:                                        ; preds = %land.end, %entry<br class="">
> +  %3 = phi i1 [ false, %entry ], [ %tobool3, %land.end ]<br class="">
> +  %land.ext5 = zext i1 %3 to i32<br class="">
> +  ret i32 0<br class="">
> +}<br class="">
><br class="">
> Added: llvm/trunk/test/Transforms/<wbr class="">ADCE/unreachable.ll<br class="">
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ADCE/unreachable.ll?rev=311467&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/llvm/trunk/test/<wbr class="">Transforms/ADCE/unreachable.<wbr class="">ll?rev=311467&view=auto</a><br class="">
> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
> --- llvm/trunk/test/Transforms/<wbr class="">ADCE/unreachable.ll (added)<br class="">
> +++ llvm/trunk/test/Transforms/<wbr class="">ADCE/unreachable.ll Tue Aug 22 09:30:21 2017<br class="">
> @@ -0,0 +1,18 @@<br class="">
> +; RUN: opt < %s -adce -simplifycfg | llvm-dis<br class="">
> +; RUN: opt < %s -passes=adce | llvm-dis<br class="">
> +<br class="">
> +define i32 @Test(i32 %A, i32 %B) {<br class="">
> +BB1:<br class="">
> +        br label %BB4<br class="">
> +<br class="">
> +BB2:            ; No predecessors!<br class="">
> +        br label %BB3<br class="">
> +<br class="">
> +BB3:            ; preds = %BB4, %BB2<br class="">
> +        %ret = phi i32 [ %X, %BB4 ], [ %B, %BB2 ]               ; <i32> [#uses=1]<br class="">
> +        ret i32 %ret<br class="">
> +<br class="">
> +BB4:            ; preds = %BB1<br class="">
> +        %X = phi i32 [ %A, %BB1 ]               ; <i32> [#uses=1]<br class="">
> +        br label %BB3<br class="">
> +}<br class="">
><br class="">
><br class="">
> ______________________________<wbr class="">_________________<br class="">
> llvm-commits mailing list<br class="">
> <a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a><br class="">
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/<wbr class="">mailman/listinfo/llvm-commits</a><br class="">
<br class="">
</blockquote></div></div>
</div></blockquote></div><br class=""></body></html>