From 85969613f99b3c96d6d7d7f3d5e0b68e69b68600 Mon Sep 17 00:00:00 2001 From: Valery Pykhtin Date: Wed, 19 Mar 2025 11:05:18 +0000 Subject: [PATCH 1/6] [SSAUpdaterBulk] Add PHI simplification pass. --- .../llvm/Transforms/Utils/SSAUpdaterBulk.h | 24 ++++++++++ llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp | 47 +++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h b/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h index ad24cb454d5e7..6894e4fa0a357 100644 --- a/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h +++ b/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h @@ -79,6 +79,30 @@ class SSAUpdaterBulk { /// vector. void RewriteAllUses(DominatorTree *DT, SmallVectorImpl *InsertedPHIs = nullptr); + + /// Rewrite all uses and simplify the inserted PHI nodes. + /// Use this method to preserve behavior when replacing SSAUpdater. + void RewriteAndSimplifyAllUses(DominatorTree *DT) { + SmallVector NewPHIs; + RewriteAllUses(DT, &NewPHIs); + simplifyPass(NewPHIs); + } + + /// Same as previous, but return inserted PHI nodes in InsertedPHIs. + void RewriteAndSimplifyAllUses(DominatorTree *DT, + SmallVectorImpl &InsertedPHIs) { + RewriteAllUses(DT, &InsertedPHIs); + simplifyPass(InsertedPHIs); + // Remove nullptrs from the worklist + InsertedPHIs.erase( + std::remove(InsertedPHIs.begin(), InsertedPHIs.end(), nullptr), + InsertedPHIs.end()); + } + +private: + /// Perform a single pass of simplification over the worklist of PHIs. + /// Pointers to replaced phis are nulled out. + static bool simplifyPass(SmallVectorImpl &Worklist); }; } // end namespace llvm diff --git a/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp b/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp index cad7ff64c01fb..dac964b092ec5 100644 --- a/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp +++ b/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Utils/SSAUpdaterBulk.h" +#include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/IteratedDominanceFrontier.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Dominators.h" @@ -182,3 +183,49 @@ void SSAUpdaterBulk::RewriteAllUses(DominatorTree *DT, } } } + +static bool isEquivalentPHI(PHINode *PHI1, PHINode *PHI2) { + if (PHI1->getNumIncomingValues() != PHI2->getNumIncomingValues()) + return false; + + unsigned I = 0, NumValues = PHI1->getNumIncomingValues(); + for (; I != NumValues; ++I) { + if (PHI1->getIncomingBlock(I) != PHI2->getIncomingBlock(I)) + break; + if (PHI1->getIncomingValue(I) != PHI2->getIncomingValue(I)) + return false; + } + // TODO: add procesing if phis have different order of incoming values. + return I == NumValues; +} + +bool SSAUpdaterBulk::simplifyPass(SmallVectorImpl &Worklist) { + if (Worklist.empty()) + return false; + + auto findEquivalentPHI = [](PHINode *PHI) -> Value * { + BasicBlock *BB = PHI->getParent(); + for (auto &OtherPHI : BB->phis()) { + if (PHI != &OtherPHI && isEquivalentPHI(PHI, &OtherPHI)) { + return &OtherPHI; + } + } + return nullptr; + }; + + const DataLayout &DL = Worklist.front()->getParent()->getDataLayout(); + bool Change = false; + for (PHINode *&PHI : Worklist) { + Value *Replacement = simplifyInstruction(PHI, DL); + if (!Replacement) + Replacement = findEquivalentPHI(PHI); + + if (Replacement) { + PHI->replaceAllUsesWith(Replacement); + PHI->eraseFromParent(); + PHI = nullptr; // Mark as removed + Change = true; + } + } + return Change; +} From 10e99d6f5b9529cd8c2f2861441047b84dbb9518 Mon Sep 17 00:00:00 2001 From: Valery Pykhtin Date: Wed, 19 Mar 2025 17:36:59 +0000 Subject: [PATCH 2/6] add test. --- .../Transforms/Utils/SSAUpdaterBulkTest.cpp | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp b/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp index cfd7fbb445840..9d490dc4c6694 100644 --- a/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp +++ b/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp @@ -311,3 +311,69 @@ TEST(SSAUpdaterBulk, TwoBBLoop) { EXPECT_EQ(Phi->getIncomingValueForBlock(Entry), ConstantInt::get(I32Ty, 0)); EXPECT_EQ(Phi->getIncomingValueForBlock(Loop), I); } + +TEST(SSAUpdaterBulk, SimplifyPHIs) { + const char *IR = R"( + define void @main(i32 %val, i1 %cond) { + entry: + br i1 %cond, label %left, label %right + left: + %add = add i32 %val, 1 + br label %exit + right: + %sub = sub i32 %val, 1 + br label %exit + exit: + %phi = phi i32 [ %sub, %right ], [ %add, %left ] + %cmp = icmp slt i32 0, 42 + ret void + } + )"; + + llvm::LLVMContext Context; + llvm::SMDiagnostic Err; + std::unique_ptr M = llvm::parseAssemblyString(IR, Err, Context); + ASSERT_NE(M, nullptr) << "Failed to parse IR: " << Err.getMessage(); + + Function *F = M->getFunction("main"); + auto *Entry = &F->getEntryBlock(); + auto *Left = Entry->getTerminator()->getSuccessor(0); + auto *Right = Entry->getTerminator()->getSuccessor(1); + auto *Exit = Left->getSingleSuccessor(); + auto *Val = &*F->arg_begin(); + auto *Phi = &Exit->front(); + auto *Cmp = &*std::next(Exit->begin()); + auto *Add = &Left->front(); + auto *Sub = &Right->front(); + + SSAUpdaterBulk Updater; + Type *I32Ty = Type::getInt32Ty(Context); + + // Use %val directly instead of creating a phi. + unsigned ValVar = Updater.AddVariable("Val", I32Ty); + Updater.AddAvailableValue(ValVar, Left, Val); + Updater.AddAvailableValue(ValVar, Right, Val); + Updater.AddUse(ValVar, &Cmp->getOperandUse(0)); + + // Use existing %phi for %add and %sub values. + unsigned AddSubVar = Updater.AddVariable("AddSub", I32Ty); + Updater.AddAvailableValue(AddSubVar, Left, Add); + Updater.AddAvailableValue(AddSubVar, Right, Sub); + Updater.AddUse(AddSubVar, &Cmp->getOperandUse(1)); + + SmallVector Inserted; + DominatorTree DT(*F); + Updater.RewriteAndSimplifyAllUses(&DT, Inserted); + +#if 0 // Enable for debugging. + Exit->dump(); + // Output: + // exit: ; preds = %right, %left + // %phi = phi i32 [ %sub, %right ], [ %add, %left ] + // %cmp = icmp slt i32 %val, %phi + // ret void +#endif + EXPECT_EQ(Inserted.size(), 0u); + EXPECT_EQ(Val, Cmp->getOperand(0)); + EXPECT_EQ(Phi, Cmp->getOperand(1)); +} From 241b30001722f984cd6a3e8aefd0233fc0afbc83 Mon Sep 17 00:00:00 2001 From: Valery Pykhtin Date: Fri, 21 Mar 2025 10:09:08 +0000 Subject: [PATCH 3/6] Use isIdenticalToWhenDefined --- llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp b/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp index b24ef4dae43fc..7edfa3940895e 100644 --- a/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp +++ b/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp @@ -225,21 +225,6 @@ void SSAUpdaterBulk::RewriteAllUses(DominatorTree *DT, } } -static bool isEquivalentPHI(PHINode *PHI1, PHINode *PHI2) { - if (PHI1->getNumIncomingValues() != PHI2->getNumIncomingValues()) - return false; - - unsigned I = 0, NumValues = PHI1->getNumIncomingValues(); - for (; I != NumValues; ++I) { - if (PHI1->getIncomingBlock(I) != PHI2->getIncomingBlock(I)) - break; - if (PHI1->getIncomingValue(I) != PHI2->getIncomingValue(I)) - return false; - } - // TODO: add procesing if phis have different order of incoming values. - return I == NumValues; -} - bool SSAUpdaterBulk::simplifyPass(SmallVectorImpl &Worklist) { if (Worklist.empty()) return false; @@ -247,9 +232,8 @@ bool SSAUpdaterBulk::simplifyPass(SmallVectorImpl &Worklist) { auto findEquivalentPHI = [](PHINode *PHI) -> Value * { BasicBlock *BB = PHI->getParent(); for (auto &OtherPHI : BB->phis()) { - if (PHI != &OtherPHI && isEquivalentPHI(PHI, &OtherPHI)) { + if (PHI != &OtherPHI && PHI->isIdenticalToWhenDefined(&OtherPHI)) return &OtherPHI; - } } return nullptr; }; From fba85b40dfadec9b05e4648bc72d99609492dcde Mon Sep 17 00:00:00 2001 From: Valery Pykhtin Date: Fri, 21 Mar 2025 11:07:21 +0000 Subject: [PATCH 4/6] formatting --- llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp b/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp index 7edfa3940895e..4e59555068288 100644 --- a/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp +++ b/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp @@ -232,7 +232,7 @@ bool SSAUpdaterBulk::simplifyPass(SmallVectorImpl &Worklist) { auto findEquivalentPHI = [](PHINode *PHI) -> Value * { BasicBlock *BB = PHI->getParent(); for (auto &OtherPHI : BB->phis()) { - if (PHI != &OtherPHI && PHI->isIdenticalToWhenDefined(&OtherPHI)) + if (PHI != &OtherPHI && PHI->isIdenticalToWhenDefined(&OtherPHI)) return &OtherPHI; } return nullptr; From 6264060eede5c2575c349eff4d8b5d52f9f4e4a5 Mon Sep 17 00:00:00 2001 From: Valery Pykhtin Date: Tue, 25 Mar 2025 12:24:33 +0000 Subject: [PATCH 5/6] Use EliminateDuplicatePHINodes. Make optimizations by default. --- .../llvm/Transforms/Utils/SSAUpdaterBulk.h | 25 +----- llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp | 81 ++++++++++++++----- .../Transforms/Utils/SSAUpdaterBulkTest.cpp | 2 +- 3 files changed, 68 insertions(+), 40 deletions(-) diff --git a/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h b/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h index 5f98933f24d65..85b47523a0458 100644 --- a/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h +++ b/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h @@ -78,29 +78,12 @@ class SSAUpdaterBulk { void RewriteAllUses(DominatorTree *DT, SmallVectorImpl *InsertedPHIs = nullptr); - /// Rewrite all uses and simplify the inserted PHI nodes. - /// Use this method to preserve behavior when replacing SSAUpdater. - void RewriteAndSimplifyAllUses(DominatorTree *DT) { - SmallVector NewPHIs; - RewriteAllUses(DT, &NewPHIs); - simplifyPass(NewPHIs); - } - - /// Same as previous, but return inserted PHI nodes in InsertedPHIs. - void RewriteAndSimplifyAllUses(DominatorTree *DT, - SmallVectorImpl &InsertedPHIs) { - RewriteAllUses(DT, &InsertedPHIs); - simplifyPass(InsertedPHIs); - // Remove nullptrs from the worklist - InsertedPHIs.erase( - std::remove(InsertedPHIs.begin(), InsertedPHIs.end(), nullptr), - InsertedPHIs.end()); - } - private: - /// Perform a single pass of simplification over the worklist of PHIs. - /// Pointers to replaced phis are nulled out. + void createPHIsAndRewrite(DominatorTree *DT, + SmallVectorImpl &InsertedPHIs); static bool simplifyPass(SmallVectorImpl &Worklist); + static bool deduplicatePass(const SmallVectorImpl &Worklist, + SmallPtrSetImpl &PHIToRemove); }; } // end namespace llvm diff --git a/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp b/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp index 4e59555068288..ffedab7a10fa6 100644 --- a/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp +++ b/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp @@ -19,6 +19,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Use.h" #include "llvm/IR/Value.h" +#include "llvm/Transforms/Utils/Local.h" using namespace llvm; @@ -110,8 +111,8 @@ struct BBValueInfo { /// Perform all the necessary updates, including new PHI-nodes insertion and the /// requested uses update. -void SSAUpdaterBulk::RewriteAllUses(DominatorTree *DT, - SmallVectorImpl *InsertedPHIs) { +void SSAUpdaterBulk::createPHIsAndRewrite( + DominatorTree *DT, SmallVectorImpl &InsertedPHIs) { DenseMap BBInfos; for (auto &R : Rewrites) { BBInfos.clear(); @@ -151,8 +152,7 @@ void SSAUpdaterBulk::RewriteAllUses(DominatorTree *DT, IRBuilder<> B(FrontierBB, FrontierBB->begin()); PHINode *PN = B.CreatePHI(R.Ty, 0, R.Name); BBInfos[FrontierBB].LiveInValue = PN; - if (InsertedPHIs) - InsertedPHIs->push_back(PN); + InsertedPHIs.push_back(PN); } // IsLiveOut indicates whether we are computing live-out values (true) or @@ -229,23 +229,10 @@ bool SSAUpdaterBulk::simplifyPass(SmallVectorImpl &Worklist) { if (Worklist.empty()) return false; - auto findEquivalentPHI = [](PHINode *PHI) -> Value * { - BasicBlock *BB = PHI->getParent(); - for (auto &OtherPHI : BB->phis()) { - if (PHI != &OtherPHI && PHI->isIdenticalToWhenDefined(&OtherPHI)) - return &OtherPHI; - } - return nullptr; - }; - const DataLayout &DL = Worklist.front()->getParent()->getDataLayout(); bool Change = false; for (PHINode *&PHI : Worklist) { - Value *Replacement = simplifyInstruction(PHI, DL); - if (!Replacement) - Replacement = findEquivalentPHI(PHI); - - if (Replacement) { + if (Value *Replacement = simplifyInstruction(PHI, DL)) { PHI->replaceAllUsesWith(Replacement); PHI->eraseFromParent(); PHI = nullptr; // Mark as removed @@ -254,3 +241,61 @@ bool SSAUpdaterBulk::simplifyPass(SmallVectorImpl &Worklist) { } return Change; } + +bool SSAUpdaterBulk::deduplicatePass(const SmallVectorImpl &Worklist, + SmallPtrSetImpl &PHIToRemove) { + + auto FindFirstNonPHIIt = [](BasicBlock *BB) { + PHINode *LastPHI = nullptr; + for (auto &PHI : BB->phis()) + LastPHI = &PHI; + assert(LastPHI); + return std::next(LastPHI->getIterator()); + }; + + // BB -> First BB's Non-PHI iterator map + SmallDenseMap Blocks; + // Reverse Worklist to preserve the order of new phis. + for (PHINode *PHI : reverse(Worklist)) { + if (!PHI) + continue; + auto *BB = PHI->getParent(); + auto [I, Inserted] = Blocks.try_emplace(BB); + if (Inserted) + I->second = FindFirstNonPHIIt(BB); + + // Move newly inserted PHIs to the end to ensure that + // EliminateDuplicatePHINodes prioritizes removing the newly created PHIs + // over the existing ones, preserving the original PHI nodes. + PHI->moveBefore(I->second); + } + + for (auto [BB, I] : Blocks) + EliminateDuplicatePHINodes(BB, PHIToRemove); + + for (PHINode *PHI : PHIToRemove) + PHI->eraseFromParent(); + + return !PHIToRemove.empty(); +} + +void SSAUpdaterBulk::RewriteAllUses(DominatorTree *DT, + SmallVectorImpl *InsertedPHIs) { + SmallVector PHIs; + createPHIsAndRewrite(DT, PHIs); + simplifyPass(PHIs); + + SmallPtrSet PHIToRemove; + deduplicatePass(PHIs, PHIToRemove); + + if (!InsertedPHIs) + return; + + for (auto *&PHI : PHIs) + if (PHI && PHIToRemove.count(PHI)) + PHI = nullptr; // Mark as removed. + + InsertedPHIs->reserve(PHIs.size() - PHIToRemove.size()); + std::copy_if(PHIs.begin(), PHIs.end(), std::back_inserter(*InsertedPHIs), + [](PHINode *PHI) { return PHI != nullptr; }); +} diff --git a/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp b/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp index e7b80d65882c9..4ac74d27b709c 100644 --- a/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp +++ b/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp @@ -360,7 +360,7 @@ TEST(SSAUpdaterBulk, SimplifyPHIs) { SmallVector Inserted; DominatorTree DT(*F); - Updater.RewriteAndSimplifyAllUses(&DT, Inserted); + Updater.RewriteAllUses(&DT, &Inserted); #if 0 // Enable for debugging. Exit->dump(); From 23f244e0b044e29ca024226a14de7802d2e432f9 Mon Sep 17 00:00:00 2001 From: Valery Pykhtin Date: Wed, 26 Mar 2025 06:46:25 +0000 Subject: [PATCH 6/6] Update tests. --- llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll | 4 ++-- .../dfa-jump-threading-transform.ll | 4 ++-- .../DFAJumpThreading/dfa-unfold-select.ll | 14 +++++++------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll index 82c04e24b72f1..ad7b4cbd8dec8 100644 --- a/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll @@ -29,9 +29,9 @@ entry: ; CHECK-NEXT: br label %setjmp.dispatch ; CHECK: setjmp.dispatch: +; CHECK-NEXT: %label.phi = phi i32 [ %label, %if.end ], [ -1, %entry ] ; CHECK-NEXT: %[[VAL2:.*]] = phi i32 [ %val, %if.end ], [ undef, %entry ] ; CHECK-NEXT: %[[BUF:.*]] = phi ptr [ %[[BUF2:.*]], %if.end ], [ undef, %entry ] -; CHECK-NEXT: %label.phi = phi i32 [ %label, %if.end ], [ -1, %entry ] ; CHECK-NEXT: switch i32 %label.phi, label %entry.split [ ; CHECK-NEXT: i32 1, label %entry.split.split ; CHECK-NEXT: ] @@ -42,8 +42,8 @@ entry: ; CHECK-NEXT: br label %entry.split.split ; CHECK: entry.split.split: -; CHECK-NEXT: %[[BUF2]] = phi ptr [ %[[BUF]], %setjmp.dispatch ], [ %buf, %entry.split ] ; CHECK-NEXT: %setjmp.ret = phi i32 [ 0, %entry.split ], [ %[[VAL2]], %setjmp.dispatch ] +; CHECK-NEXT: %[[BUF2]] = phi ptr [ %[[BUF]], %setjmp.dispatch ], [ %buf, %entry.split ] ; CHECK-NEXT: invoke void @__wasm_longjmp(ptr %[[BUF2]], i32 1) ; CHECK-NEXT: to label %.noexc unwind label %catch.dispatch.longjmp diff --git a/llvm/test/Transforms/DFAJumpThreading/dfa-jump-threading-transform.ll b/llvm/test/Transforms/DFAJumpThreading/dfa-jump-threading-transform.ll index cba1ba8dde768..15bf1f1074977 100644 --- a/llvm/test/Transforms/DFAJumpThreading/dfa-jump-threading-transform.ll +++ b/llvm/test/Transforms/DFAJumpThreading/dfa-jump-threading-transform.ll @@ -41,14 +41,14 @@ define i32 @test1(i32 %num) { ; CHECK-NEXT: [[CMP_EXIT:%.*]] = icmp slt i32 [[INC]], [[NUM:%.*]] ; CHECK-NEXT: br i1 [[CMP_EXIT]], label [[FOR_BODY]], label [[FOR_END:%.*]] ; CHECK: for.inc.jt2: -; CHECK-NEXT: [[COUNT4:%.*]] = phi i32 [ [[COUNT1]], [[SEL_SI_UNFOLD_FALSE_JT2]] ], [ [[COUNT2]], [[CASE1]] ] ; CHECK-NEXT: [[STATE_NEXT_JT2]] = phi i32 [ 2, [[CASE1]] ], [ [[DOTSI_UNFOLD_PHI_JT2]], [[SEL_SI_UNFOLD_FALSE_JT2]] ] +; CHECK-NEXT: [[COUNT4:%.*]] = phi i32 [ [[COUNT1]], [[SEL_SI_UNFOLD_FALSE_JT2]] ], [ [[COUNT2]], [[CASE1]] ] ; CHECK-NEXT: [[INC_JT2]] = add nsw i32 [[COUNT4]], 1 ; CHECK-NEXT: [[CMP_EXIT_JT2:%.*]] = icmp slt i32 [[INC_JT2]], [[NUM]] ; CHECK-NEXT: br i1 [[CMP_EXIT_JT2]], label [[FOR_BODY_JT2]], label [[FOR_END]] ; CHECK: for.inc.jt1: -; CHECK-NEXT: [[COUNT3:%.*]] = phi i32 [ [[COUNT]], [[FOR_BODY]] ], [ [[COUNT1]], [[CASE2]] ] ; CHECK-NEXT: [[STATE_NEXT_JT1]] = phi i32 [ 1, [[CASE2]] ], [ 1, [[FOR_BODY]] ] +; CHECK-NEXT: [[COUNT3:%.*]] = phi i32 [ [[COUNT]], [[FOR_BODY]] ], [ [[COUNT1]], [[CASE2]] ] ; CHECK-NEXT: [[INC_JT1]] = add nsw i32 [[COUNT3]], 1 ; CHECK-NEXT: [[CMP_EXIT_JT1:%.*]] = icmp slt i32 [[INC_JT1]], [[NUM]] ; CHECK-NEXT: br i1 [[CMP_EXIT_JT1]], label [[FOR_BODY_JT1]], label [[FOR_END]] diff --git a/llvm/test/Transforms/DFAJumpThreading/dfa-unfold-select.ll b/llvm/test/Transforms/DFAJumpThreading/dfa-unfold-select.ll index 93872c3938768..1670d00648e45 100644 --- a/llvm/test/Transforms/DFAJumpThreading/dfa-unfold-select.ll +++ b/llvm/test/Transforms/DFAJumpThreading/dfa-unfold-select.ll @@ -44,14 +44,14 @@ define i32 @test1(i32 %num) { ; CHECK-NEXT: [[CMP_EXIT:%.*]] = icmp slt i32 [[INC]], [[NUM:%.*]] ; CHECK-NEXT: br i1 [[CMP_EXIT]], label [[FOR_BODY]], label [[FOR_END:%.*]] ; CHECK: for.inc.jt2: -; CHECK-NEXT: [[COUNT4:%.*]] = phi i32 [ [[COUNT1]], [[SEL_SI_UNFOLD_FALSE_JT2]] ], [ [[COUNT2]], [[CASE1]] ] ; CHECK-NEXT: [[STATE_NEXT_JT2]] = phi i32 [ 2, [[CASE1]] ], [ [[DOTSI_UNFOLD_PHI_JT2]], [[SEL_SI_UNFOLD_FALSE_JT2]] ] +; CHECK-NEXT: [[COUNT4:%.*]] = phi i32 [ [[COUNT1]], [[SEL_SI_UNFOLD_FALSE_JT2]] ], [ [[COUNT2]], [[CASE1]] ] ; CHECK-NEXT: [[INC_JT2]] = add nsw i32 [[COUNT4]], 1 ; CHECK-NEXT: [[CMP_EXIT_JT2:%.*]] = icmp slt i32 [[INC_JT2]], [[NUM]] ; CHECK-NEXT: br i1 [[CMP_EXIT_JT2]], label [[FOR_BODY_JT2]], label [[FOR_END]] ; CHECK: for.inc.jt1: -; CHECK-NEXT: [[COUNT3:%.*]] = phi i32 [ [[COUNT]], [[FOR_BODY]] ], [ [[COUNT1]], [[CASE2]] ] ; CHECK-NEXT: [[STATE_NEXT_JT1]] = phi i32 [ 1, [[CASE2]] ], [ 1, [[FOR_BODY]] ] +; CHECK-NEXT: [[COUNT3:%.*]] = phi i32 [ [[COUNT]], [[FOR_BODY]] ], [ [[COUNT1]], [[CASE2]] ] ; CHECK-NEXT: [[INC_JT1]] = add nsw i32 [[COUNT3]], 1 ; CHECK-NEXT: [[CMP_EXIT_JT1:%.*]] = icmp slt i32 [[INC_JT1]], [[NUM]] ; CHECK-NEXT: br i1 [[CMP_EXIT_JT1]], label [[FOR_BODY_JT1]], label [[FOR_END]] @@ -156,8 +156,8 @@ define i32 @test2(i32 %num) { ; CHECK-NEXT: [[DOTSI_UNFOLD_PHI4_JT2:%.*]] = phi i32 [ 2, [[STATE1_1_SI_UNFOLD_TRUE:%.*]] ] ; CHECK-NEXT: br label [[FOR_INC_JT2]] ; CHECK: for.inc: -; CHECK-NEXT: [[COUNT5:%.*]] = phi i32 [ [[COUNT_JT3]], [[FOR_BODY_JT3:%.*]] ], [ undef, [[STATE1_1_SI_UNFOLD_TRUE]] ], [ [[COUNT6]], [[STATE1_1_SI_UNFOLD_FALSE]] ], [ undef, [[STATE1_2_SI_UNFOLD_FALSE:%.*]] ], [ [[COUNT]], [[STATE2_2_SI_UNFOLD_FALSE]] ] -; CHECK-NEXT: [[STATE_NEXT]] = phi i32 [ [[STATE2_1_SI_UNFOLD_PHI]], [[STATE2_2_SI_UNFOLD_FALSE]] ], [ poison, [[STATE1_2_SI_UNFOLD_FALSE]] ], [ poison, [[STATE1_1_SI_UNFOLD_TRUE]] ], [ [[DOTSI_UNFOLD_PHI4]], [[STATE1_1_SI_UNFOLD_FALSE]] ], [ 1, [[FOR_BODY_JT3]] ] +; CHECK-NEXT: [[STATE_NEXT]] = phi i32 [ [[STATE2_1_SI_UNFOLD_PHI]], [[STATE2_2_SI_UNFOLD_FALSE]] ], [ poison, [[STATE1_2_SI_UNFOLD_FALSE:%.*]] ], [ poison, [[STATE1_1_SI_UNFOLD_TRUE]] ], [ [[DOTSI_UNFOLD_PHI4]], [[STATE1_1_SI_UNFOLD_FALSE]] ], [ 1, [[FOR_BODY_JT3:%.*]] ] +; CHECK-NEXT: [[COUNT5:%.*]] = phi i32 [ [[COUNT_JT3]], [[FOR_BODY_JT3]] ], [ undef, [[STATE1_1_SI_UNFOLD_TRUE]] ], [ [[COUNT6]], [[STATE1_1_SI_UNFOLD_FALSE]] ], [ undef, [[STATE1_2_SI_UNFOLD_FALSE]] ], [ [[COUNT]], [[STATE2_2_SI_UNFOLD_FALSE]] ] ; CHECK-NEXT: [[INC]] = add nsw i32 [[COUNT5]], 1 ; CHECK-NEXT: [[CMP_EXIT:%.*]] = icmp slt i32 [[INC]], [[NUM:%.*]] ; CHECK-NEXT: br i1 [[CMP_EXIT]], label [[FOR_BODY]], label [[FOR_END:%.*]] @@ -167,14 +167,14 @@ define i32 @test2(i32 %num) { ; CHECK-NEXT: [[CMP_EXIT_JT2:%.*]] = icmp slt i32 [[INC_JT2]], [[NUM]] ; CHECK-NEXT: br i1 [[CMP_EXIT_JT2]], label [[FOR_BODY_JT2:%.*]], label [[FOR_END]] ; CHECK: for.inc.jt1: -; CHECK-NEXT: [[COUNT7:%.*]] = phi i32 [ [[COUNT6]], [[STATE1_1_SI_UNFOLD_TRUE_JT1]] ], [ [[COUNT]], [[STATE2_2_SI_UNFOLD_FALSE_JT1]] ], [ [[COUNT]], [[FOR_BODY]] ] ; CHECK-NEXT: [[STATE_NEXT_JT1]] = phi i32 [ 1, [[FOR_BODY]] ], [ [[STATE2_1_SI_UNFOLD_PHI_JT1]], [[STATE2_2_SI_UNFOLD_FALSE_JT1]] ], [ [[DOTSI_UNFOLD_PHI3_JT1]], [[STATE1_1_SI_UNFOLD_TRUE_JT1]] ] +; CHECK-NEXT: [[COUNT7:%.*]] = phi i32 [ [[COUNT6]], [[STATE1_1_SI_UNFOLD_TRUE_JT1]] ], [ [[COUNT]], [[STATE2_2_SI_UNFOLD_FALSE_JT1]] ], [ [[COUNT]], [[FOR_BODY]] ] ; CHECK-NEXT: [[INC_JT1]] = add nsw i32 [[COUNT7]], 1 ; CHECK-NEXT: [[CMP_EXIT_JT1:%.*]] = icmp slt i32 [[INC_JT1]], [[NUM]] ; CHECK-NEXT: br i1 [[CMP_EXIT_JT1]], label [[FOR_BODY_JT1]], label [[FOR_END]] ; CHECK: for.inc.jt3: -; CHECK-NEXT: [[COUNT8:%.*]] = phi i32 [ [[COUNT6]], [[STATE1_2_SI_UNFOLD_FALSE_JT3]] ], [ [[COUNT]], [[CASE2]] ] ; CHECK-NEXT: [[STATE_NEXT_JT3]] = phi i32 [ 3, [[CASE2]] ], [ [[DOTSI_UNFOLD_PHI2_JT3]], [[STATE1_2_SI_UNFOLD_FALSE_JT3]] ] +; CHECK-NEXT: [[COUNT8:%.*]] = phi i32 [ [[COUNT6]], [[STATE1_2_SI_UNFOLD_FALSE_JT3]] ], [ [[COUNT]], [[CASE2]] ] ; CHECK-NEXT: [[INC_JT3]] = add nsw i32 [[COUNT8]], 1 ; CHECK-NEXT: [[CMP_EXIT_JT3:%.*]] = icmp slt i32 [[INC_JT3]], [[NUM]] ; CHECK-NEXT: br i1 [[CMP_EXIT_JT3]], label [[FOR_BODY_JT3]], label [[FOR_END]] @@ -305,8 +305,8 @@ define i32 @test3(i32 %num) { ; CHECK-NEXT: [[CMP_EXIT_JT2:%.*]] = icmp slt i32 [[INC_JT2]], [[NUM]] ; CHECK-NEXT: br i1 [[CMP_EXIT_JT2]], label [[FOR_BODY_JT2]], label [[FOR_END]] ; CHECK: for.inc.jt1: -; CHECK-NEXT: [[COUNT4:%.*]] = phi i32 [ [[COUNT_JT4]], [[FOR_BODY_JT4]] ], [ [[COUNT_JT3]], [[FOR_BODY_JT3]] ], [ [[COUNT5]], [[SEL_1_SI_UNFOLD_TRUE_JT1]] ], [ [[COUNT]], [[FOR_BODY]] ] ; CHECK-NEXT: [[STATE_NEXT_JT1]] = phi i32 [ 1, [[FOR_BODY]] ], [ 1, [[FOR_BODY_JT3]] ], [ 1, [[FOR_BODY_JT4]] ], [ [[DOTSI_UNFOLD_PHI2_JT1]], [[SEL_1_SI_UNFOLD_TRUE_JT1]] ] +; CHECK-NEXT: [[COUNT4:%.*]] = phi i32 [ [[COUNT_JT4]], [[FOR_BODY_JT4]] ], [ [[COUNT_JT3]], [[FOR_BODY_JT3]] ], [ [[COUNT5]], [[SEL_1_SI_UNFOLD_TRUE_JT1]] ], [ [[COUNT]], [[FOR_BODY]] ] ; CHECK-NEXT: [[INC_JT1]] = add nsw i32 [[COUNT4]], 1 ; CHECK-NEXT: [[CMP_EXIT_JT1:%.*]] = icmp slt i32 [[INC_JT1]], [[NUM]] ; CHECK-NEXT: br i1 [[CMP_EXIT_JT1]], label [[FOR_BODY_JT1]], label [[FOR_END]]