diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp --- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp @@ -570,8 +570,12 @@ assert(match(BI.getCondition(), m_LogicalAnd()) && "Must have an `and` of `i1`s or `select i1 X, Y, false`s for the" " condition!"); - buildPartialUnswitchConditionalBranch(*OldPH, Invariants, ExitDirection, - *UnswitchedBB, *NewPH, false); + buildPartialUnswitchConditionalBranch( + *OldPH, Invariants, ExitDirection, *UnswitchedBB, *NewPH, + FreezeLoopUnswitchCond && any_of(Invariants, [&](Value *C) { + return !isGuaranteedNotToBeUndefOrPoison(C, nullptr, + OldPH->getTerminator(), &DT); + })); } // Update the dominator tree with the added edge. diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/LIV-loop-condtion.ll b/llvm/test/Transforms/SimpleLoopUnswitch/LIV-loop-condtion.ll --- a/llvm/test/Transforms/SimpleLoopUnswitch/LIV-loop-condtion.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/LIV-loop-condtion.ll @@ -8,7 +8,8 @@ entry: br label %loop_begin ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 %cond1, label %entry.split, label %loop_exit.split +; CHECK-NEXT: [[FROZEN:%.+]] = freeze i1 %cond1 +; CHECK-NEXT: br i1 [[FROZEN]], label %entry.split, label %loop_exit.split ; ; CHECK: entry.split: ; CHECK-NEXT: br label %loop_begin diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-freeze-individual-conditions.ll b/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-freeze-individual-conditions.ll --- a/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-freeze-individual-conditions.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-freeze-individual-conditions.ll @@ -7,10 +7,12 @@ ; CHECK-LABEL: @need_freeze_of_individual_or_conditions1( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[COND4:%.*]], [[COND1:%.*]] -; CHECK-NEXT: br i1 [[TMP0]], label [[ENTRY_SPLIT:%.*]], label [[EXIT_SPLIT:%.*]] +; CHECK-NEXT: [[DOTFR:%.*]] = freeze i1 [[TMP0]] +; CHECK-NEXT: br i1 [[DOTFR]], label [[ENTRY_SPLIT:%.*]], label [[EXIT_SPLIT:%.*]] ; CHECK: entry.split: ; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[COND2:%.*]], [[COND3:%.*]] -; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_SPLIT:%.*]], label [[EXIT_SPLIT1:%.*]] +; CHECK-NEXT: [[DOTFR2:%.*]] = freeze i1 [[TMP1]] +; CHECK-NEXT: br i1 [[DOTFR2]], label [[ENTRY_SPLIT_SPLIT:%.*]], label [[EXIT_SPLIT1:%.*]] ; CHECK: entry.split.split: ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] ; CHECK: loop.header: @@ -49,10 +51,12 @@ ; CHECK-LABEL: @need_freeze_of_individual_or_conditions2( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[COND4:%.*]], [[COND1:%.*]] -; CHECK-NEXT: br i1 [[TMP0]], label [[ENTRY_SPLIT:%.*]], label [[EXIT_SPLIT:%.*]] +; CHECK-NEXT: [[DOTFR:%.*]] = freeze i1 [[TMP0]] +; CHECK-NEXT: br i1 [[DOTFR]], label [[ENTRY_SPLIT:%.*]], label [[EXIT_SPLIT:%.*]] ; CHECK: entry.split: ; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[COND2:%.*]], [[COND3:%.*]] -; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_SPLIT:%.*]], label [[EXIT_SPLIT1:%.*]] +; CHECK-NEXT: [[DOTFR2:%.*]] = freeze i1 [[TMP1]] +; CHECK-NEXT: br i1 [[DOTFR2]], label [[ENTRY_SPLIT_SPLIT:%.*]], label [[EXIT_SPLIT1:%.*]] ; CHECK: entry.split.split: ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] ; CHECK: loop.header: @@ -91,10 +95,12 @@ ; CHECK-LABEL: @need_freeze_of_individual_or_conditions3( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[COND4:%.*]], [[COND1:%.*]] -; CHECK-NEXT: br i1 [[TMP0]], label [[ENTRY_SPLIT:%.*]], label [[EXIT_SPLIT:%.*]] +; CHECK-NEXT: [[DOTFR:%.*]] = freeze i1 [[TMP0]] +; CHECK-NEXT: br i1 [[DOTFR]], label [[ENTRY_SPLIT:%.*]], label [[EXIT_SPLIT:%.*]] ; CHECK: entry.split: ; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[COND2:%.*]], [[COND3:%.*]] -; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_SPLIT:%.*]], label [[EXIT_SPLIT1:%.*]] +; CHECK-NEXT: [[DOTFR2:%.*]] = freeze i1 [[TMP1]] +; CHECK-NEXT: br i1 [[DOTFR2]], label [[ENTRY_SPLIT_SPLIT:%.*]], label [[EXIT_SPLIT1:%.*]] ; CHECK: entry.split.split: ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] ; CHECK: loop.header: @@ -133,7 +139,8 @@ ; CHECK-LABEL: @need_freeze_of_individual_and_conditions1( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[COND4:%.*]], [[COND1:%.*]] -; CHECK-NEXT: br i1 [[TMP0]], label [[EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]] +; CHECK-NEXT: [[DOTFR:%.*]] = freeze i1 [[TMP0]] +; CHECK-NEXT: br i1 [[DOTFR]], label [[EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]] ; CHECK: entry.split: ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] ; CHECK: loop.header: @@ -166,7 +173,8 @@ ; CHECK-LABEL: @need_freeze_of_individual_and_conditions2( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[COND4:%.*]], [[COND1:%.*]] -; CHECK-NEXT: br i1 [[TMP0]], label [[EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]] +; CHECK-NEXT: [[DOTFR:%.*]] = freeze i1 [[TMP0]] +; CHECK-NEXT: br i1 [[DOTFR]], label [[EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]] ; CHECK: entry.split: ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] ; CHECK: loop.header: @@ -199,7 +207,8 @@ ; CHECK-LABEL: @need_freeze_of_individual_and_conditions3( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[COND4:%.*]], [[COND1:%.*]] -; CHECK-NEXT: br i1 [[TMP0]], label [[EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]] +; CHECK-NEXT: [[DOTFR:%.*]] = freeze i1 [[TMP0]] +; CHECK-NEXT: br i1 [[DOTFR]], label [[EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]] ; CHECK: entry.split: ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] ; CHECK: loop.header: diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-logical-and-or.ll b/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-logical-and-or.ll --- a/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-logical-and-or.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-logical-and-or.ll @@ -155,9 +155,11 @@ ; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[COND4:%.*]], [[COND2:%.*]] ; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[TMP0]], [[COND3:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = or i1 [[TMP1]], [[COND1:%.*]] -; CHECK-NEXT: br i1 [[TMP2]], label [[LOOP_EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]] +; CHECK-NEXT: [[DOTFR:%.*]] = freeze i1 [[TMP2]] +; CHECK-NEXT: br i1 [[DOTFR]], label [[LOOP_EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]] ; CHECK: entry.split: -; CHECK-NEXT: br i1 [[COND6:%.*]], label [[LOOP_EXIT_SPLIT1:%.*]], label [[ENTRY_SPLIT_SPLIT:%.*]] +; CHECK-NEXT: [[COND6_FR:%.*]] = freeze i1 [[COND6:%.*]] +; CHECK-NEXT: br i1 [[COND6_FR]], label [[LOOP_EXIT_SPLIT1:%.*]], label [[ENTRY_SPLIT_SPLIT:%.*]] ; CHECK: entry.split.split: ; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] ; CHECK: loop_begin: diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll b/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll --- a/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll @@ -453,7 +453,8 @@ ; CHECK-NEXT: br i1 %cond1, label %entry.split, label %loop_exit.split ; ; CHECK: entry.split: -; CHECK-NEXT: br i1 %cond2, label %entry.split.split, label %loop_exit +; CHECK-NEXT: [[FROZEN:%.+]] = freeze i1 %cond2 +; CHECK-NEXT: br i1 [[FROZEN]], label %entry.split.split, label %loop_exit ; ; CHECK: entry.split.split: ; CHECK-NEXT: br label %loop_begin @@ -498,7 +499,8 @@ ; CHECK-NEXT: br i1 %cond1, label %entry.split, label %loop_exit.split ; ; CHECK: entry.split: -; CHECK-NEXT: br i1 %cond2, label %entry.split.split, label %loop_exit +; CHECK-NEXT: [[FROZEN:%.+]] = freeze i1 %cond2 +; CHECK-NEXT: br i1 [[FROZEN]], label %entry.split.split, label %loop_exit ; ; CHECK: entry.split.split: ; CHECK-NEXT: br label %loop_begin @@ -543,7 +545,8 @@ ; CHECK-NEXT: br i1 %cond1, label %entry.split, label %loop_exit.split ; ; CHECK: entry.split: -; CHECK-NEXT: br i1 %cond2, label %loop_exit.split1, label %entry.split.split +; CHECK-NEXT: [[FROZEN:%.+]] = freeze i1 %cond2 +; CHECK-NEXT: br i1 [[FROZEN]], label %loop_exit.split1, label %entry.split.split ; ; CHECK: entry.split.split: ; CHECK-NEXT: br label %loop_begin @@ -591,7 +594,8 @@ ; CHECK-NEXT: %[[INV_OR1:.*]] = or i1 %cond4, %cond2 ; CHECK-NEXT: %[[INV_OR2:.*]] = or i1 %[[INV_OR1]], %cond3 ; CHECK-NEXT: %[[INV_OR3:.*]] = or i1 %[[INV_OR2]], %cond1 -; CHECK-NEXT: br i1 %[[INV_OR3]], label %loop_exit.split, label %entry.split +; CHECK-NEXT: [[FROZEN:%.+]] = freeze i1 %[[INV_OR3]] +; CHECK-NEXT: br i1 [[FROZEN]], label %loop_exit.split, label %entry.split ; ; CHECK: entry.split: ; CHECK-NEXT: br label %loop_begin @@ -639,7 +643,8 @@ entry: br label %loop_begin ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 %cond, label %entry.split, label %loop_exit.split +; CHECK-NEXT: [[FROZEN:%.+]] = freeze i1 %cond +; CHECK-NEXT: br i1 [[FROZEN]], label %entry.split, label %loop_exit.split ; ; CHECK: entry.split: ; CHECK-NEXT: br label %loop_begin @@ -679,7 +684,8 @@ entry: br label %loop_begin ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 %cond, label %entry.split, label %loop_exit.split +; CHECK-NEXT: [[FROZEN:%.+]] = freeze i1 %cond +; CHECK-NEXT: br i1 [[FROZEN]], label %entry.split, label %loop_exit.split ; ; CHECK: entry.split: ; CHECK-NEXT: br label %loop_begin