diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 125005128dccaf..a79d82d01f1145 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -7065,8 +7065,7 @@ class Compiler bool optIsLoopTestEvalIntoTemp(Statement* testStmt, Statement** newTestStmt); unsigned optIsLoopIncrTree(GenTree* incr); - bool optExtractTestIncr( - BasicBlock* bottom, BasicBlock* top, GenTree** ppTest, GenTree** ppIncr); + bool optExtractTestIncr(BasicBlock* cond, GenTree** ppTest, GenTree** ppIncr); void optSetMappedBlockTargets(BasicBlock* blk, BasicBlock* newBlk, diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp index eeee96575ccfa0..dc7e334b309b0f 100644 --- a/src/coreclr/jit/flowgraph.cpp +++ b/src/coreclr/jit/flowgraph.cpp @@ -5519,7 +5519,7 @@ bool FlowGraphNaturalLoop::AnalyzeIteration(NaturalLoopIterInfo* info) } GenTree* iterTree = nullptr; - if (!comp->optExtractTestIncr(cond, m_header, &test, &iterTree)) + if (!comp->optExtractTestIncr(cond, &test, &iterTree)) { JITDUMP(" Could not extract an IV\n"); continue; diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp index f3bafc6dcfcc63..d538ca44b2413d 100644 --- a/src/coreclr/jit/optimizer.cpp +++ b/src/coreclr/jit/optimizer.cpp @@ -336,7 +336,6 @@ bool Compiler::optIsLoopTestEvalIntoTemp(Statement* testStmt, Statement** newTes // // Arguments: // cond - A BBJ_COND block that exits the loop -// header - Loop header block // ppTest - [out] The test stmt of the loop if found. // ppIncr - [out] The incr stmt of the loop if found. // @@ -352,7 +351,7 @@ bool Compiler::optIsLoopTestEvalIntoTemp(Statement* testStmt, Statement** newTes // This method just retrieves what it thinks is the "test" node, // the callers are expected to verify that "iterVar" is used in the test. // -bool Compiler::optExtractTestIncr(BasicBlock* cond, BasicBlock* header, GenTree** ppTest, GenTree** ppIncr) +bool Compiler::optExtractTestIncr(BasicBlock* cond, GenTree** ppTest, GenTree** ppIncr) { assert(ppTest != nullptr); assert(ppIncr != nullptr); @@ -1839,6 +1838,18 @@ bool Compiler::optTryInvertWhileLoop(FlowGraphNaturalLoop* loop) return false; } + // There may be multiple exits, and one of the other exits may also be a + // latch. That latch could be preferable to leave (for example because it + // is an IV test). + NaturalLoopIterInfo iterInfo; + if (loop->AnalyzeIteration(&iterInfo) && + (iterInfo.TestBlock->TrueTargetIs(loop->GetHeader()) != iterInfo.TestBlock->FalseTargetIs(loop->GetHeader()))) + { + // Test block is both a latch and exit, so the loop is already inverted in a preferable way. + JITDUMP("No loop-inversion for " FMT_LP " since it is already inverted (with an IV test)\n", loop->GetIndex()); + return false; + } + JITDUMP("Condition in block " FMT_BB " of loop " FMT_LP " is a candidate for duplication to invert the loop\n", condBlock->bbNum, loop->GetIndex());