<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Thank you.</p>
    <p>Philip<br>
    </p>
    <div class="moz-cite-prefix">On 2/27/20 6:11 PM, Juneyoung Lee
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAJOWn3i=6qPxq4-ROnuDGz8Lh9ivBD1h-Wf7_CNZMmbAsz6JGQ@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="ltr">
        <div dir="ltr">Hello Philip,
          <div><br>
          </div>
          <div>I reverted the patch: <a
href="https://github.com/llvm/llvm-project/commit/2b5a8976514de326bb84f0913d9d451089c11d22"
              moz-do-not-send="true">https://github.com/llvm/llvm-project/commit/2b5a8976514de326bb84f0913d9d451089c11d22</a></div>
          <div><br>
          </div>
          <div>I can work on CSE/LICM support for freeze. I'll make a
            patch for those.</div>
          <div><br>
          </div>
          <div>Juneyoung Lee</div>
        </div>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">2020년 2월 28일 (금) 오전 9:42,
          Philip Reames <<a href="mailto:listmail@philipreames.com"
            moz-do-not-send="true">listmail@philipreames.com</a>>님이
          작성:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Juneyong,<br>
          <br>
          Not entirely surprisingly, we're seeing some performance
          regressions <br>
          from these changes.  Looking at some of the IR, it looks like
          pretty <br>
          basic handling of freeze might be missing.  I'm seeing what
          looks to be <br>
          failures to speculate freezes outside of loops, and (possibly)
          failures <br>
          to CSE identical free instructions.<br>
          <br>
          Given that, I need to ask that this patch be reverted until
          that <br>
          infrastructure can be addressed.<br>
          <br>
          Philip<br>
          <br>
          p.s. Here's small test cases for some of the obvious cases. 
          -O3 doesn't <br>
          change them.<br>
          <br>
          <br>
          define i1 @cse(i1 %a) {<br>
             %b = freeze i1 %a<br>
             %c = freeze i1 %a<br>
             %and = and i1 %b, %c<br>
             ret i1 %and<br>
          }<br>
          <br>
          define void @licm(i1 %a) {<br>
          entry:<br>
             br label %loop<br>
          loop:<br>
             %b = freeze i1 %a<br>
             call void @use(i1 %b)<br>
             br label %loop<br>
          }<br>
          <br>
          declare void @use(i1)<br>
          <br>
          <br>
          On 2/25/20 8:47 PM, Juneyoung Lee via llvm-commits wrote:<br>
          > Author: Juneyoung Lee<br>
          > Date: 2020-02-26T13:47:33+09:00<br>
          > New Revision: 181628b52d390f2136fb5a63fe644d230a9b822d<br>
          ><br>
          > URL: <a
href="https://github.com/llvm/llvm-project/commit/181628b52d390f2136fb5a63fe644d230a9b822d"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://github.com/llvm/llvm-project/commit/181628b52d390f2136fb5a63fe644d230a9b822d</a><br>
          > DIFF: <a
href="https://github.com/llvm/llvm-project/commit/181628b52d390f2136fb5a63fe644d230a9b822d.diff"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://github.com/llvm/llvm-project/commit/181628b52d390f2136fb5a63fe644d230a9b822d.diff</a><br>
          ><br>
          > LOG: [SimpleLoopUnswitch] Fix introduction of UB when
          hoisted condition may be undef or poison<br>
          ><br>
          > Summary:<br>
          > Loop unswitch hoists branches on loop-invariant
          conditions. However, if this<br>
          > condition is poison/undef and the branch wasn't
          originally reachable, loop<br>
          > unswitch introduces UB (since the optimized code will
          branch on poison/undef and<br>
          > the original one didn't)).<br>
          > We fix this problem by freezing the condition to ensure
          we don't introduce UB.<br>
          ><br>
          > We will now transform the following:<br>
          >    while (...) {<br>
          >      if (C) { A }<br>
          >      else   { B }<br>
          >    }<br>
          ><br>
          > Into:<br>
          >    C' = freeze(C)<br>
          >    if (C') {<br>
          >      while (...) { A }<br>
          >    } else {<br>
          >      while (...) { B }<br>
          >    }<br>
          ><br>
          > This patch fixes the root cause of the following bug
          reports (which use the old loop unswitch, but can be
          reproduced with minor changes in the code and
          -enable-nontrivial-unswitch):<br>
          > - <a href="https://llvm.org/bugs/show_bug.cgi?id=27506"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://llvm.org/bugs/show_bug.cgi?id=27506</a><br>
          > - <a href="https://llvm.org/bugs/show_bug.cgi?id=31652"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://llvm.org/bugs/show_bug.cgi?id=31652</a><br>
          ><br>
          > Reviewers: reames, majnemer, chenli, sanjoy, hfinkel<br>
          ><br>
          > Reviewed By: reames<br>
          ><br>
          > Subscribers: hiraditya, jvesely, nhaehnle, filcab,
          regehr, trentxintong, nlopes, llvm-commits, mzolotukhin<br>
          ><br>
          > Tags: #llvm<br>
          ><br>
          > Differential Revision: <a
            href="https://reviews.llvm.org/D29015" rel="noreferrer"
            target="_blank" moz-do-not-send="true">https://reviews.llvm.org/D29015</a><br>
          ><br>
          > Added:<br>
          >      <br>
          ><br>
          > Modified:<br>
          >      llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp<br>
          >     
llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested.ll<br>
          >     
llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested2.ll<br>
          >     
          llvm/test/Transforms/SimpleLoopUnswitch/exponential-switch-unswitch.ll<br>
          >      llvm/test/Transforms/SimpleLoopUnswitch/guards.ll<br>
          >     
          llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll<br>
          >     
          llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll<br>
          ><br>
          > Removed:<br>
          >      <br>
          ><br>
          ><br>
          >
################################################################################<br>
          > diff  --git
          a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
          b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp<br>
          > index 8f9db3db26c4..4a82fd939dae 100644<br>
          > --- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp<br>
          > +++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp<br>
          > @@ -26,7 +26,9 @@<br>
          >   #include "llvm/Analysis/LoopPass.h"<br>
          >   #include "llvm/Analysis/MemorySSA.h"<br>
          >   #include "llvm/Analysis/MemorySSAUpdater.h"<br>
          > +#include "llvm/Analysis/MustExecute.h"<br>
          >   #include "llvm/Analysis/Utils/Local.h"<br>
          > +#include "llvm/Analysis/ValueTracking.h"<br>
          >   #include "llvm/IR/BasicBlock.h"<br>
          >   #include "llvm/IR/Constant.h"<br>
          >   #include "llvm/IR/Constants.h"<br>
          > @@ -180,11 +182,14 @@ static void
          buildPartialUnswitchConditionalBranch(BasicBlock &BB,<br>
          >                                                   
           ArrayRef<Value *> Invariants,<br>
          >                                                     bool
          Direction,<br>
          >                                                   
           BasicBlock &UnswitchedSucc,<br>
          > -                                                 
          BasicBlock &NormalSucc) {<br>
          > +                                                 
          BasicBlock &NormalSucc,<br>
          > +                                                  bool
          insertFreeze) {<br>
          >     IRBuilder<> IRB(&BB);<br>
          > -<br>
          > +<br>
          >     Value *Cond = Direction ? IRB.CreateOr(Invariants) :<br>
          >       IRB.CreateAnd(Invariants);<br>
          > +  if (insertFreeze)<br>
          > +    Cond = IRB.CreateFreeze(Cond, Cond->getName() +
          ".fr");<br>
          >     IRB.CreateCondBr(Cond, Direction ?
          &UnswitchedSucc : &NormalSucc,<br>
          >                      Direction ? &NormalSucc :
          &UnswitchedSucc);<br>
          >   }<br>
          > @@ -498,7 +503,7 @@ static bool
          unswitchTrivialBranch(Loop &L, BranchInst &BI,
          DominatorTree &DT,<br>
          >                    Instruction::And &&<br>
          >                "Must have an `and` of `i1`s for the
          condition!");<br>
          >       buildPartialUnswitchConditionalBranch(*OldPH,
          Invariants, ExitDirection,<br>
          > -                                          *UnswitchedBB,
          *NewPH);<br>
          > +                                          *UnswitchedBB,
          *NewPH, false);<br>
          >     }<br>
          >   <br>
          >     // Update the dominator tree with the added edge.<br>
          > @@ -2009,6 +2014,10 @@ static void
          unswitchNontrivialInvariants(<br>
          >         SE->forgetTopmostLoop(&L);<br>
          >     }<br>
          >   <br>
          > +  ICFLoopSafetyInfo SafetyInfo(&DT);<br>
          > +  SafetyInfo.computeLoopSafetyInfo(&L);<br>
          > +  bool insertFreeze =
          !SafetyInfo.isGuaranteedToExecute(TI, &DT, &L);<br>
          > +<br>
          >     // If the edge from this terminator to a successor
          dominates that successor,<br>
          >     // store a map from each block in its dominator
          subtree to it. This lets us<br>
          >     // tell when cloning for a particular successor if a
          block is dominated by<br>
          > @@ -2066,6 +2075,12 @@ static void
          unswitchNontrivialInvariants(<br>
          >         BasicBlock *ClonedPH =
          ClonedPHs.begin()->second;<br>
          >         BI->setSuccessor(ClonedSucc, ClonedPH);<br>
          >         BI->setSuccessor(1 - ClonedSucc, LoopPH);<br>
          > +      if (insertFreeze) {<br>
          > +        auto Cond = BI->getCondition();<br>
          > +        if (!isGuaranteedNotToBeUndefOrPoison(Cond))<br>
          > +          BI->setCondition(new FreezeInst(Cond,
          Cond->getName() + ".fr", BI));<br>
          > +      }<br>
          > +<br>
          >         DTUpdates.push_back({DominatorTree::Insert,
          SplitBB, ClonedPH});<br>
          >       } else {<br>
          >         assert(SI && "Must either be a branch or
          switch!");<br>
          > @@ -2080,6 +2095,12 @@ static void
          unswitchNontrivialInvariants(<br>
          >           else<br>
          >           
           Case.setSuccessor(ClonedPHs.find(Case.getCaseSuccessor())->second);<br>
          >   <br>
          > +      if (insertFreeze) {<br>
          > +        auto Cond = SI->getCondition();<br>
          > +        if (!isGuaranteedNotToBeUndefOrPoison(Cond))<br>
          > +          SI->setCondition(new FreezeInst(Cond,
          Cond->getName() + ".fr", SI));<br>
          > +      }<br>
          > +<br>
          >         // We need to use the set to populate domtree
          updates as even when there<br>
          >         // are multiple cases pointing at the same
          successor we only want to<br>
          >         // remove and insert one edge in the domtree.<br>
          > @@ -2156,7 +2177,7 @@ static void
          unswitchNontrivialInvariants(<br>
          >       // When doing a partial unswitch, we have to do a
          bit more work to build up<br>
          >       // the branch in the split block.<br>
          >       buildPartialUnswitchConditionalBranch(*SplitBB,
          Invariants, Direction,<br>
          > -                                          *ClonedPH,
          *LoopPH);<br>
          > +                                          *ClonedPH,
          *LoopPH, insertFreeze);<br>
          >       DTUpdates.push_back({DominatorTree::Insert,
          SplitBB, ClonedPH});<br>
          >   <br>
          >       if (MSSAU) {<br>
          ><br>
          > diff  --git
a/llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested.ll
b/llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested.ll<br>
          > index d2ca06357cfe..04d027cd502c 100644<br>
          > ---
a/llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested.ll<br>
          > +++
b/llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested.ll<br>
          > @@ -85,8 +85,14 @@<br>
          >   <br>
          >   declare void @bar()<br>
          >   <br>
          > -define void @loop_nested3_conds5(i32* %addr, i1 %c1, i1
          %c2, i1 %c3, i1 %c4, i1 %c5) {<br>
          > +define void @loop_nested3_conds5(i32* %addr, i1 %c1i, i1
          %c2i, i1 %c3i, i1 %c4i, i1 %c5i) {<br>
          >   entry:<br>
          > +  ; c1 ~ c5 are guaranteed to be never undef or poison.<br>
          > +  %c1 = freeze i1 %c1i<br>
          > +  %c2 = freeze i1 %c2i<br>
          > +  %c3 = freeze i1 %c3i<br>
          > +  %c4 = freeze i1 %c4i<br>
          > +  %c5 = freeze i1 %c5i<br>
          >     %addr1 = getelementptr i32, i32* %addr, i64 0<br>
          >     %addr2 = getelementptr i32, i32* %addr, i64 1<br>
          >     %addr3 = getelementptr i32, i32* %addr, i64 2<br>
          ><br>
          > diff  --git
a/llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested2.ll
b/llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested2.ll<br>
          > index e8879e79c53f..26179ad9068e 100644<br>
          > ---
a/llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested2.ll<br>
          > +++
b/llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested2.ll<br>
          > @@ -97,8 +97,14 @@<br>
          >   <br>
          >   declare void @bar()<br>
          >   <br>
          > -define void @loop_nested3_conds5(i32* %addr, i1 %c1, i1
          %c2, i1 %c3, i1 %c4, i1 %c5) {<br>
          > +define void @loop_nested3_conds5(i32* %addr, i1 %c1i, i1
          %c2i, i1 %c3i, i1 %c4i, i1 %c5i) {<br>
          >   entry:<br>
          > +  ; c1 ~ c5 are guaranteed to be never undef or poison.<br>
          > +  %c1 = freeze i1 %c1i<br>
          > +  %c2 = freeze i1 %c2i<br>
          > +  %c3 = freeze i1 %c3i<br>
          > +  %c4 = freeze i1 %c4i<br>
          > +  %c5 = freeze i1 %c5i<br>
          >     %addr1 = getelementptr i32, i32* %addr, i64 0<br>
          >     %addr2 = getelementptr i32, i32* %addr, i64 1<br>
          >     %addr3 = getelementptr i32, i32* %addr, i64 2<br>
          ><br>
          > diff  --git
          a/llvm/test/Transforms/SimpleLoopUnswitch/exponential-switch-unswitch.ll
b/llvm/test/Transforms/SimpleLoopUnswitch/exponential-switch-unswitch.ll<br>
          > index 35d431e5ee26..6606a1931d4d 100644<br>
          > ---
          a/llvm/test/Transforms/SimpleLoopUnswitch/exponential-switch-unswitch.ll<br>
          > +++
          b/llvm/test/Transforms/SimpleLoopUnswitch/exponential-switch-unswitch.ll<br>
          > @@ -86,8 +86,11 @@<br>
          >   ; LOOP-MAX-COUNT-111:     Loop at depth 2 containing:<br>
          >   ; LOOP-MAX-NOT: Loop at depth 2 containing:<br>
          >   <br>
          > -define i32 @loop_switch(i32* %addr, i32 %c1, i32 %c2) {<br>
          > +define i32 @loop_switch(i32* %addr, i32 %c1i, i32 %c2i)
          {<br>
          >   entry:<br>
          > +  ; c1, c2 are guaranteed to be never undef or poison.<br>
          > +  %c1 = freeze i32 %c1i<br>
          > +  %c2 = freeze i32 %c2i<br>
          >     %addr1 = getelementptr i32, i32* %addr, i64 0<br>
          >     %addr2 = getelementptr i32, i32* %addr, i64 1<br>
          >     %check0 = icmp eq i32 %c2, 0<br>
          ><br>
          > diff  --git
          a/llvm/test/Transforms/SimpleLoopUnswitch/guards.ll
          b/llvm/test/Transforms/SimpleLoopUnswitch/guards.ll<br>
          > index de57075b6222..9365829f976a 100644<br>
          > --- a/llvm/test/Transforms/SimpleLoopUnswitch/guards.ll<br>
          > +++ b/llvm/test/Transforms/SimpleLoopUnswitch/guards.ll<br>
          > @@ -81,7 +81,8 @@ exit:<br>
          >   define void @test_conditional_guards(i1 %cond, i32 %N)
          {<br>
          >   ; CHECK-LABEL: @test_conditional_guards(<br>
          >   ; CHECK-NEXT:  entry:<br>
          > -; CHECK-NEXT:    br i1 [[COND:%.*]], label
          [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]<br>
          > +; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1
          [[COND:%.*]]<br>
          > +; CHECK-NEXT:    br i1 [[COND_FR]], label
          [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]<br>
          >   ; CHECK:       <a href="http://entry.split.us"
            rel="noreferrer" target="_blank" moz-do-not-send="true">entry.split.us</a>:<br>
          >   ; CHECK-NEXT:    br label [[LOOP_US:%.*]]<br>
          >   ; CHECK:       <a href="http://loop.us"
            rel="noreferrer" target="_blank" moz-do-not-send="true">loop.us</a>:<br>
          ><br>
          > diff  --git
          a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll
b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll<br>
          > index 692799db1c60..7b2c8280e7a3 100644<br>
          > ---
          a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll<br>
          > +++
          b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll<br>
          > @@ -57,7 +57,8 @@ define void @test_unswitch(i1* %ptr, i1
          %cond) {<br>
          >   entry:<br>
          >     br label %loop_begin<br>
          >   ; CHECK-NEXT:  entry:<br>
          > -; CHECK-NEXT:    br i1 %cond, label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %cond<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          >   <br>
          >   loop_begin:<br>
          >     call void @x()<br>
          > @@ -127,7 +128,8 @@ define void
          @test_unswitch_non_dup_code(i1* %ptr, i1 %cond) {<br>
          >   entry:<br>
          >     br label %loop_begin<br>
          >   ; CHECK-NEXT:  entry:<br>
          > -; CHECK-NEXT:    br i1 %cond, label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %cond<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          >   <br>
          >   loop_begin:<br>
          >     call void @x()<br>
          > @@ -208,7 +210,8 @@ define void
          @test_unswitch_non_dup_code_in_cfg(i1* %ptr, i1 %cond) {<br>
          >   entry:<br>
          >     br label %loop_begin<br>
          >   ; CHECK-NEXT:  entry:<br>
          > -; CHECK-NEXT:    br i1 %cond, label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %cond<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          >   <br>
          >   loop_begin:<br>
          >     call void @x()<br>
          > @@ -364,7 +367,8 @@ define void
          @test_unswitch_large_exit(i1* %ptr, i1 %cond) {<br>
          >   entry:<br>
          >     br label %loop_begin<br>
          >   ; CHECK-NEXT:  entry:<br>
          > -; CHECK-NEXT:    br i1 %cond, label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %cond<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          >   <br>
          >   loop_begin:<br>
          >     call void @x()<br>
          > @@ -441,7 +445,8 @@ define void
          @test_unswitch_dedicated_exiting(i1* %ptr, i1 %cond) {<br>
          >   entry:<br>
          >     br label %loop_begin<br>
          >   ; CHECK-NEXT:  entry:<br>
          > -; CHECK-NEXT:    br i1 %cond, label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %cond<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          >   <br>
          >   loop_begin:<br>
          >     call void @x()<br>
          ><br>
          > diff  --git
          a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll
b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll<br>
          > index 0aec52d447d5..02b3bd5b4c3d 100644<br>
          > ---
          a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll<br>
          > +++
          b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll<br>
          > @@ -814,7 +814,8 @@ inner_loop_begin:<br>
          >   ; CHECK-NEXT:    %[[A_INNER_PHI:.*]] = phi i32 [
          %[[A]], %loop_begin ], [ %[[A2:.*]], %inner_inner_loop_exit ]<br>
          >   ; CHECK-NEXT:    %[[COND:.*]] = load i1, i1* %cond.ptr<br>
          >   ; CHECK-NEXT:    %[[B:.*]] = load i32, i32* %b.ptr<br>
          > -; CHECK-NEXT:    br i1 %[[COND]], label %<a
            href="http://inner_loop_begin.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">inner_loop_begin.split.us</a>,
          label %inner_loop_begin.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %[[COND]]<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://inner_loop_begin.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">inner_loop_begin.split.us</a>,
          label %inner_loop_begin.split<br>
          >   <br>
          >   inner_inner_loop_begin:<br>
          >     %v1 = load i1, i1* %ptr<br>
          > @@ -967,7 +968,8 @@ inner_loop_begin:<br>
          >   ; CHECK-NEXT:    %[[A_INNER_PHI:.*]] = phi i32 [
          %[[A]], %loop_begin ], [ %[[A2:.*]], %inner_inner_loop_exit ]<br>
          >   ; CHECK-NEXT:    %[[COND:.*]] = load i1, i1* %cond.ptr<br>
          >   ; CHECK-NEXT:    %[[B:.*]] = load i32, i32* %b.ptr<br>
          > -; CHECK-NEXT:    br i1 %[[COND]], label %<a
            href="http://inner_loop_begin.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">inner_loop_begin.split.us</a>,
          label %inner_loop_begin.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %[[COND]]<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://inner_loop_begin.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">inner_loop_begin.split.us</a>,
          label %inner_loop_begin.split<br>
          >   <br>
          >   inner_inner_loop_begin:<br>
          >     %v1 = load i1, i1* %ptr<br>
          > @@ -1120,7 +1122,8 @@ inner_loop_begin:<br>
          >   ; CHECK-NEXT:    %[[A_INNER_PHI:.*]] = phi i32 [
          %[[A]], %loop_begin ], [ %[[A2:.*]], %inner_inner_loop_exit ]<br>
          >   ; CHECK-NEXT:    %[[COND:.*]] = load i1, i1* %cond.ptr<br>
          >   ; CHECK-NEXT:    %[[B:.*]] = load i32, i32* %b.ptr<br>
          > -; CHECK-NEXT:    br i1 %[[COND]], label %<a
            href="http://inner_loop_begin.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">inner_loop_begin.split.us</a>,
          label %inner_loop_begin.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %[[COND]]<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://inner_loop_begin.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">inner_loop_begin.split.us</a>,
          label %inner_loop_begin.split<br>
          >   <br>
          >   inner_inner_loop_begin:<br>
          >     %v1 = load i1, i1* %ptr<br>
          > @@ -1240,7 +1243,8 @@ inner_loop_begin:<br>
          >   ; CHECK-NEXT:    %[[A_INNER_PHI:.*]] = phi i32 [
          %[[A]], %loop_begin ], [ %[[A2:.*]], %inner_inner_loop_exit ]<br>
          >   ; CHECK-NEXT:    %[[COND:.*]] = load i1, i1* %cond.ptr<br>
          >   ; CHECK-NEXT:    %[[B:.*]] = load i32, i32* %b.ptr<br>
          > -; CHECK-NEXT:    br i1 %[[COND]], label %<a
            href="http://inner_loop_begin.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">inner_loop_begin.split.us</a>,
          label %inner_loop_begin.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %[[COND]]<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://inner_loop_begin.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">inner_loop_begin.split.us</a>,
          label %inner_loop_begin.split<br>
          >   <br>
          >   inner_inner_loop_begin:<br>
          >     %v1 = load i1, i1* %ptr<br>
          > @@ -1482,7 +1486,8 @@ define i32 @test10a(i1* %ptr, i1
          %cond, i32* %a.ptr) {<br>
          >   entry:<br>
          >     br label %loop_begin<br>
          >   ; CHECK-NEXT:  entry:<br>
          > -; CHECK-NEXT:    br i1 %cond, label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %cond<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          >   <br>
          >   loop_begin:<br>
          >     %a = load i32, i32* %a.ptr<br>
          > @@ -1562,7 +1567,8 @@ define i32 @test10b(i1* %ptr, i1
          %cond, i32* %a.ptr) {<br>
          >   entry:<br>
          >     br label %loop_begin<br>
          >   ; CHECK-NEXT:  entry:<br>
          > -; CHECK-NEXT:    br i1 %cond, label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %cond<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          >   <br>
          >   loop_begin:<br>
          >     %a = load i32, i32* %a.ptr<br>
          > @@ -1661,7 +1667,8 @@ inner_loop_ph:<br>
          >     br label %inner_loop_begin<br>
          >   ; CHECK:       inner_loop_ph:<br>
          >   ; CHECK-NEXT:    %[[COND:.*]] = load i1, i1* %cond.ptr<br>
          > -; CHECK-NEXT:    br i1 %[[COND]], label %<a
            href="http://inner_loop_ph.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">inner_loop_ph.split.us</a>,
          label %inner_loop_ph.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %[[COND]]<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://inner_loop_ph.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">inner_loop_ph.split.us</a>,
          label %inner_loop_ph.split<br>
          >   <br>
          >   inner_loop_begin:<br>
          >     call void @sink1(i32 %b)<br>
          > @@ -1755,7 +1762,8 @@ inner_loop_ph:<br>
          >     br label %inner_loop_begin<br>
          >   ; CHECK:       inner_loop_ph:<br>
          >   ; CHECK-NEXT:    %[[COND:.*]] = load i1, i1* %cond.ptr<br>
          > -; CHECK-NEXT:    br i1 %[[COND]], label %<a
            href="http://inner_loop_ph.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">inner_loop_ph.split.us</a>,
          label %inner_loop_ph.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %[[COND]]<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://inner_loop_ph.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">inner_loop_ph.split.us</a>,
          label %inner_loop_ph.split<br>
          >   <br>
          >   inner_loop_begin:<br>
          >     call void @sink1(i32 %b)<br>
          > @@ -1853,7 +1861,8 @@ inner_inner_loop_ph:<br>
          >     br label %inner_inner_loop_begin<br>
          >   ; CHECK:       inner_inner_loop_ph:<br>
          >   ; CHECK-NEXT:    %[[COND:.*]] = load i1, i1* %cond.ptr<br>
          > -; CHECK-NEXT:    br i1 %[[COND]], label %<a
            href="http://inner_inner_loop_ph.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">inner_inner_loop_ph.split.us</a>,
          label %inner_inner_loop_ph.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %[[COND]]<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://inner_inner_loop_ph.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">inner_inner_loop_ph.split.us</a>,
          label %inner_inner_loop_ph.split<br>
          >   <br>
          >   inner_inner_loop_begin:<br>
          >     call void @sink1(i32 %b)<br>
          > @@ -1961,7 +1970,8 @@ inner_inner_loop_ph:<br>
          >     br label %inner_inner_loop_begin<br>
          >   ; CHECK:       inner_inner_loop_ph:<br>
          >   ; CHECK-NEXT:    %[[COND:.*]] = load i1, i1* %cond.ptr<br>
          > -; CHECK-NEXT:    br i1 %[[COND]], label %<a
            href="http://inner_inner_loop_ph.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">inner_inner_loop_ph.split.us</a>,
          label %inner_inner_loop_ph.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %[[COND]]<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://inner_inner_loop_ph.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">inner_inner_loop_ph.split.us</a>,
          label %inner_inner_loop_ph.split<br>
          >   <br>
          >   inner_inner_loop_begin:<br>
          >     call void @sink1(i32 %b)<br>
          > @@ -2048,7 +2058,8 @@ define i32 @test13a(i1* %ptr, i1
          %cond, i32* %a.ptr, i32* %b.ptr) {<br>
          >   entry:<br>
          >     br label %loop_begin<br>
          >   ; CHECK-NEXT:  entry:<br>
          > -; CHECK-NEXT:    br i1 %cond, label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %cond<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          >   <br>
          >   loop_begin:<br>
          >     %a = load i32, i32* %a.ptr<br>
          > @@ -2172,7 +2183,8 @@ define i32 @test13b(i1* %ptr, i1
          %cond, i32* %a.ptr, i32* %b.ptr) {<br>
          >   entry:<br>
          >     br label %loop_begin<br>
          >   ; CHECK-NEXT:  entry:<br>
          > -; CHECK-NEXT:    br i1 %cond, label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          > +; CHECK-NEXT:    %[[COND_FR:.*]] = freeze i1 %cond<br>
          > +; CHECK-NEXT:    br i1 %[[COND_FR]], label %<a
            href="http://entry.split.us" rel="noreferrer"
            target="_blank" moz-do-not-send="true">entry.split.us</a>,
          label %entry.split<br>
          >   <br>
          >   loop_begin:<br>
          >     %a = load i32, i32* %a.ptr<br>
          > @@ -2420,9 +2432,10 @@ loop_exit:<br>
          >   ; paths to reach an inner loop after unswitching, and
          one of them is via the<br>
          >   ; predecessors of the unswitched loop header. That can
          allow us to find the loop<br>
          >   ; through multiple<br>
          > diff erent paths.<br>
          > -define void @test21(i1 %a, i1 %b) {<br>
          > +define void @test21(i1 %a0, i1 %b) {<br>
          >   ; CHECK-LABEL: @test21(<br>
          >   bb:<br>
          > +  %a = freeze i1 %a0<br>
          >     br label %bb3<br>
          >   ; CHECK-NOT:     br i1 %a<br>
          >   ;<br>
          > @@ -2553,7 +2566,8 @@ define void @test23(i1 %arg, i1*
          %ptr) {<br>
          >   entry:<br>
          >     br label %outer.header<br>
          >   ; CHECK:       entry:<br>
          > -; CHECK-NEXT:    br i1 %arg,<br>
          > +; CHECK-NEXT:    %[[ARG_FR:.*]] = freeze i1 %arg<br>
          > +; CHECK-NEXT:    br i1 %[[ARG_FR]],<br>
          >   ;<br>
          >   ; Just verify that we unswitched the correct bits. We
          should call `@f` twice in<br>
          >   ; one unswitch and `@f` and then `@g` in the other.<br>
          > @@ -3064,7 +3078,8 @@ define i32 @test29(i32 %arg) {<br>
          >   entry:<br>
          >     br label %header<br>
          >   ; CHECK-NEXT:  entry:<br>
          > -; CHECK-NEXT:    switch i32 %arg, label
          %[[ENTRY_SPLIT_C:.*]] [<br>
          > +; CHECK-NEXT:    %<a href="http://arg.fr"
            rel="noreferrer" target="_blank" moz-do-not-send="true">arg.fr</a>
          = freeze i32 %arg<br>
          > +; CHECK-NEXT:    switch i32 %<a href="http://arg.fr"
            rel="noreferrer" target="_blank" moz-do-not-send="true">arg.fr</a>,
          label %[[ENTRY_SPLIT_C:.*]] [<br>
          >   ; CHECK-NEXT:      i32 0, label %[[ENTRY_SPLIT_A:.*]]<br>
          >   ; CHECK-NEXT:      i32 1, label %[[ENTRY_SPLIT_A]]<br>
          >   ; CHECK-NEXT:      i32 2, label %[[ENTRY_SPLIT_B:.*]]<br>
          > @@ -3242,11 +3257,13 @@ exit:<br>
          >   ; a loop exit edge as those can in some cases be
          special. Among other things,<br>
          >   ; this includes an LCSSA phi with multiple entries
          despite being a dedicated<br>
          >   ; exit block.<br>
          > -define i32 @test30(i32 %arg) {<br>
          > +define i32 @test30(i32 %arg0) {<br>
          >   ; CHECK-LABEL: define i32 @test30(<br>
          >   entry:<br>
          > +  %arg = freeze i32 %arg0<br>
          >     br label %header<br>
          >   ; CHECK-NEXT:  entry:<br>
          > +; CHECK-NEXT:    %arg = freeze i32 %arg0<br>
          >   ; CHECK-NEXT:    switch i32 %arg, label
          %[[ENTRY_SPLIT_EXIT:.*]] [<br>
          >   ; CHECK-NEXT:      i32 -1, label %[[ENTRY_SPLIT_EXIT]]<br>
          >   ; CHECK-NEXT:      i32 0, label %[[ENTRY_SPLIT_A:.*]]<br>
          > @@ -3426,7 +3443,8 @@ b.header:<br>
          >     br label %c.header<br>
          >   ; CHECK:       b.header:<br>
          >   ; CHECK-NEXT:    %v1 = call i1 @cond()<br>
          > -; CHECK-NEXT:    br i1 %v1, label
          %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]]<br>
          > +; CHECK-NEXT:    %[[V1_FR:.*]] = freeze i1 %v1<br>
          > +; CHECK-NEXT:    br i1 %[[V1_FR]], label
          %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]]<br>
          >   ;<br>
          >   ; CHECK:       [[B_HEADER_SPLIT_US]]:<br>
          >   ; CHECK-NEXT:    br label %[[C_HEADER_US:.*]]<br>
          > @@ -3501,7 +3519,8 @@ b.header:<br>
          >   ; CHECK:       b.header:<br>
          >   ; CHECK-NEXT:    %x.b = load i32, i32* %ptr<br>
          >   ; CHECK-NEXT:    %v1 = call i1 @cond()<br>
          > -; CHECK-NEXT:    br i1 %v1, label
          %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]]<br>
          > +; CHECK-NEXT:    %[[V1_FR:.*]] = freeze i1 %v1<br>
          > +; CHECK-NEXT:    br i1 %[[V1_FR]], label
          %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]]<br>
          >   ;<br>
          >   ; CHECK:       [[B_HEADER_SPLIT_US]]:<br>
          >   ; CHECK-NEXT:    br label %[[C_HEADER_US:.*]]<br>
          > @@ -3589,7 +3608,8 @@ b.header:<br>
          >   ; CHECK:       b.header:<br>
          >   ; CHECK-NEXT:    %x.b = load i32, i32* %ptr<br>
          >   ; CHECK-NEXT:    %v1 = call i1 @cond()<br>
          > -; CHECK-NEXT:    br i1 %v1, label
          %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]]<br>
          > +; CHECK-NEXT:    %[[V1_FR:.*]] = freeze i1 %v1<br>
          > +; CHECK-NEXT:    br i1 %[[V1_FR]], label
          %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]]<br>
          >   ;<br>
          >   ; CHECK:       [[B_HEADER_SPLIT_US]]:<br>
          >   ; CHECK-NEXT:    br label %[[C_HEADER_US:.*]]<br>
          > @@ -3669,7 +3689,8 @@ b.header:<br>
          >   ; CHECK:       b.header:<br>
          >   ; CHECK-NEXT:    %x.b = load i32, i32* %ptr<br>
          >   ; CHECK-NEXT:    %v1 = call i1 @cond()<br>
          > -; CHECK-NEXT:    br i1 %v1, label
          %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]]<br>
          > +; CHECK-NEXT:    %[[V1_FR:.*]] = freeze i1 %v1<br>
          > +; CHECK-NEXT:    br i1 %[[V1_FR]], label
          %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]]<br>
          >   ;<br>
          >   ; CHECK:       [[B_HEADER_SPLIT_US]]:<br>
          >   ; CHECK-NEXT:    br label %[[C_HEADER_US:.*]]<br>
          > @@ -3767,7 +3788,8 @@ c.header:<br>
          >     br label %d.header<br>
          >   ; CHECK:       c.header:<br>
          >   ; CHECK-NEXT:    %v1 = call i1 @cond()<br>
          > -; CHECK-NEXT:    br i1 %v1, label
          %[[C_HEADER_SPLIT_US:.*]], label %[[C_HEADER_SPLIT:.*]]<br>
          > +; CHECK-NEXT:    %[[V1_FR:.*]] = freeze i1 %v1<br>
          > +; CHECK-NEXT:    br i1 %[[V1_FR]], label
          %[[C_HEADER_SPLIT_US:.*]], label %[[C_HEADER_SPLIT:.*]]<br>
          >   ;<br>
          >   ; CHECK:       [[C_HEADER_SPLIT_US]]:<br>
          >   ; CHECK-NEXT:    br label %[[D_HEADER_US:.*]]<br>
          > @@ -3880,7 +3902,8 @@ c.header:<br>
          >   ; CHECK:       c.header:<br>
          >   ; CHECK-NEXT:    %x.c = load i32, i32* %ptr<br>
          >   ; CHECK-NEXT:    %v1 = call i1 @cond()<br>
          > -; CHECK-NEXT:    br i1 %v1, label
          %[[C_HEADER_SPLIT_US:.*]], label %[[C_HEADER_SPLIT:.*]]<br>
          > +; CHECK-NEXT:    %[[V1_FR:.*]] = freeze i1 %v1<br>
          > +; CHECK-NEXT:    br i1 %[[V1_FR]], label
          %[[C_HEADER_SPLIT_US:.*]], label %[[C_HEADER_SPLIT:.*]]<br>
          >   ;<br>
          >   ; CHECK:       [[C_HEADER_SPLIT_US]]:<br>
          >   ; CHECK-NEXT:    br label %[[D_HEADER_US:.*]]<br>
          > @@ -3962,7 +3985,8 @@ b.header:<br>
          >   ; CHECK:       b.header:<br>
          >   ; CHECK-NEXT:    %x.b = load i32, i32* %ptr<br>
          >   ; CHECK-NEXT:    %v1 = call i32 @cond.i32()<br>
          > -; CHECK-NEXT:    switch i32 %v1, label
          %[[B_HEADER_SPLIT:.*]] [<br>
          > +; CHECK-NEXT:    %[[V1_FR]] = freeze i32 %v1<br>
          > +; CHECK-NEXT:    switch i32 %[[V1_FR]], label
          %[[B_HEADER_SPLIT:.*]] [<br>
          >   ; CHECK-NEXT:      i32 1, label
          %[[B_HEADER_SPLIT_US:.*]]<br>
          >   ; CHECK-NEXT:      i32 2, label %[[B_HEADER_SPLIT_US]]<br>
          >   ; CHECK-NEXT:      i32 3, label %[[B_HEADER_SPLIT_US]]<br>
          ><br>
          ><br>
          >          <br>
          > _______________________________________________<br>
          > llvm-commits mailing list<br>
          > <a href="mailto:llvm-commits@lists.llvm.org"
            target="_blank" moz-do-not-send="true">llvm-commits@lists.llvm.org</a><br>
          > <a
            href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
        </blockquote>
      </div>
    </blockquote>
  </body>
</html>