<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>