[llvm] 181628b - [SimpleLoopUnswitch] Fix introduction of UB when hoisted condition may be undef or poison

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 28 14:42:59 PST 2020


Thank you.

Philip

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


More information about the llvm-commits mailing list