[LoopUnroll] UnrollRuntimeMultiExit takes precedence over TTI. (#134259)

Update UnrollRuntimeLoopRemainder to always give priority to the
UnrollRuntimeMultiExit option, if provided.

After ad9da92cf6 (https://github.com/llvm/llvm-project/pull/124462),
we would ignore the option if the backend indicates multi-exit is profitable.
This means it cannot be used to disable runtime unrolling.

To be consistent with canProfitablyRuntimeUnrollMultiExitLoop, always
respect the option.

This surfaced while discussing https://github.com/llvm/llvm-project/pull/131998.

PR: https://github.com/llvm/llvm-project/pull/134259
This commit is contained in:
Florian Hahn
2025-04-04 10:16:50 +01:00
committed by GitHub
parent 1302610f03
commit a4573ee38d
2 changed files with 15 additions and 12 deletions

View File

@@ -465,10 +465,6 @@ static bool canProfitablyRuntimeUnrollMultiExitLoop(
Loop *L, SmallVectorImpl<BasicBlock *> &OtherExits, BasicBlock *LatchExit,
bool UseEpilogRemainder) {
// Priority goes to UnrollRuntimeMultiExit if it's supplied.
if (UnrollRuntimeMultiExit.getNumOccurrences())
return UnrollRuntimeMultiExit;
// The main pain point with multi-exit loop unrolling is that once unrolled,
// we will not be able to merge all blocks into a straight line code.
// There are branches within the unrolled loop that go to the OtherExits.
@@ -633,14 +629,20 @@ bool llvm::UnrollRuntimeLoopRemainder(
if (!PreserveLCSSA)
return false;
if (!RuntimeUnrollMultiExit &&
!canProfitablyRuntimeUnrollMultiExitLoop(L, OtherExits, LatchExit,
UseEpilogRemainder)) {
LLVM_DEBUG(
dbgs()
<< "Multiple exit/exiting blocks in loop and multi-exit unrolling not "
"enabled!\n");
return false;
// Priority goes to UnrollRuntimeMultiExit if it's supplied.
if (UnrollRuntimeMultiExit.getNumOccurrences()) {
if (!UnrollRuntimeMultiExit)
return false;
} else {
// Otherwise perform multi-exit unrolling, if either the target indicates
// it is profitable or the general profitability heuristics apply.
if (!RuntimeUnrollMultiExit &&
!canProfitablyRuntimeUnrollMultiExitLoop(L, OtherExits, LatchExit,
UseEpilogRemainder)) {
LLVM_DEBUG(dbgs() << "Multiple exit/exiting blocks in loop and "
"multi-exit unrolling not enabled!\n");
return false;
}
}
}
// Use Scalar Evolution to compute the trip count. This allows more loops to

View File

@@ -3,6 +3,7 @@
; RUN: opt -p loop-unroll -mcpu=apple-m2 -S %s | FileCheck --check-prefix=APPLE %s
; RUN: opt -p loop-unroll -mcpu=apple-m3 -S %s | FileCheck --check-prefix=APPLE %s
; RUN: opt -p loop-unroll -mcpu=apple-m4 -S %s | FileCheck --check-prefix=APPLE %s
; RUN: opt -p loop-unroll -mcpu=apple-m1 -unroll-runtime-multi-exit=false -S %s | FileCheck --check-prefix=OTHER %s
; RUN: opt -p loop-unroll -mcpu=cortex-a57 -S %s | FileCheck --check-prefix=OTHER %s
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"