Skip to content

Wrapping test need to be done only if runtime checks present #149856

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions llvm/include/llvm/Analysis/Loads.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,15 @@ LLVM_ABI bool isSafeToLoadUnconditionally(
LLVM_ABI bool isDereferenceableAndAlignedInLoop(
LoadInst *LI, Loop *L, ScalarEvolution &SE, DominatorTree &DT,
AssumptionCache *AC = nullptr,
SmallVectorImpl<const SCEVPredicate *> *Predicates = nullptr);
SmallVectorImpl<const SCEVPredicate *> *Predicates = nullptr,
bool ShouldCheckWrapping = true);

/// Return true if the loop \p L cannot fault on any iteration and only
/// contains read-only memory accesses.
LLVM_ABI bool isDereferenceableReadOnlyLoop(
Loop *L, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC,
SmallVectorImpl<const SCEVPredicate *> *Predicates = nullptr);
SmallVectorImpl<const SCEVPredicate *> *Predicates = nullptr,
bool ShouldCheckWrapping = true);

/// Return true if we know that executing a load from this value cannot trap.
///
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/Analysis/LoopAccessAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -922,7 +922,7 @@ LLVM_ABI std::pair<const SCEV *, const SCEV *> getStartAndEndForAccess(
const Loop *Lp, const SCEV *PtrExpr, Type *AccessTy, const SCEV *BTC,
const SCEV *MaxBTC, ScalarEvolution *SE,
DenseMap<std::pair<const SCEV *, Type *>,
std::pair<const SCEV *, const SCEV *>> *PointerBounds);
std::pair<const SCEV *, const SCEV *>> *PointerBounds, bool ShouldCheckWrapping = true);

class LoopAccessInfoManager {
/// The cache.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ class LoopVectorizationLegality {
/// The list above is not based on theoretical limitations of vectorization,
/// but simply a statement that more work is needed to support these
/// additional cases safely.
bool isVectorizableEarlyExitLoop();
bool isVectorizableEarlyExitLoop(const bool NeedRuntimeChecks);

/// Return true if all of the instructions in the block can be speculatively
/// executed, and record the loads/stores that require masking.
Expand Down
14 changes: 9 additions & 5 deletions llvm/lib/Analysis/Loads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,8 @@ static bool AreEquivalentAddressValues(const Value *A, const Value *B) {

bool llvm::isDereferenceableAndAlignedInLoop(
LoadInst *LI, Loop *L, ScalarEvolution &SE, DominatorTree &DT,
AssumptionCache *AC, SmallVectorImpl<const SCEVPredicate *> *Predicates) {
AssumptionCache *AC, SmallVectorImpl<const SCEVPredicate *> *Predicates,
bool ShouldCheckWrapping) {
const Align Alignment = LI->getAlign();
auto &DL = LI->getDataLayout();
Value *Ptr = LI->getPointerOperand();
Expand Down Expand Up @@ -341,8 +342,9 @@ bool llvm::isDereferenceableAndAlignedInLoop(
? SE.getPredicatedConstantMaxBackedgeTakenCount(L, *Predicates)
: SE.getConstantMaxBackedgeTakenCount(L);
}
const auto &[AccessStart, AccessEnd] = getStartAndEndForAccess(
L, PtrScev, LI->getType(), BECount, MaxBECount, &SE, nullptr);
const auto &[AccessStart, AccessEnd] =
getStartAndEndForAccess(L, PtrScev, LI->getType(), BECount, MaxBECount,
&SE, nullptr, ShouldCheckWrapping);
if (isa<SCEVCouldNotCompute>(AccessStart) ||
isa<SCEVCouldNotCompute>(AccessEnd))
return false;
Expand Down Expand Up @@ -850,11 +852,13 @@ bool llvm::canReplacePointersIfEqual(const Value *From, const Value *To,

bool llvm::isDereferenceableReadOnlyLoop(
Loop *L, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC,
SmallVectorImpl<const SCEVPredicate *> *Predicates) {
SmallVectorImpl<const SCEVPredicate *> *Predicates,
bool ShouldCheckWrapping) {
for (BasicBlock *BB : L->blocks()) {
for (Instruction &I : *BB) {
if (auto *LI = dyn_cast<LoadInst>(&I)) {
if (!isDereferenceableAndAlignedInLoop(LI, L, *SE, *DT, AC, Predicates))
if (!isDereferenceableAndAlignedInLoop(LI, L, *SE, *DT, AC, Predicates,
ShouldCheckWrapping))
return false;
} else if (I.mayReadFromMemory() || I.mayWriteToMemory() || I.mayThrow())
return false;
Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/Analysis/LoopAccessAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ std::pair<const SCEV *, const SCEV *> llvm::getStartAndEndForAccess(
const Loop *Lp, const SCEV *PtrExpr, Type *AccessTy, const SCEV *BTC,
const SCEV *MaxBTC, ScalarEvolution *SE,
DenseMap<std::pair<const SCEV *, Type *>,
std::pair<const SCEV *, const SCEV *>> *PointerBounds) {
std::pair<const SCEV *, const SCEV *>> *PointerBounds,
bool ShouldCheckWrapping) {
std::pair<const SCEV *, const SCEV *> *PtrBoundsPair;
if (PointerBounds) {
auto [Iter, Ins] = PointerBounds->insert(
Expand Down Expand Up @@ -308,8 +309,8 @@ std::pair<const SCEV *, const SCEV *> llvm::getStartAndEndForAccess(
// sets ScEnd to the maximum unsigned value for the type. Note that LAA
// separately checks that accesses cannot not wrap, so unsigned max
// represents an upper bound.
if (evaluatePtrAddRecAtMaxBTCWillNotWrap(AR, MaxBTC, EltSizeSCEV, *SE,
DL)) {
if (!ShouldCheckWrapping || evaluatePtrAddRecAtMaxBTCWillNotWrap(
AR, MaxBTC, EltSizeSCEV, *SE, DL)) {
ScEnd = AR->evaluateAtIteration(MaxBTC, *SE);
} else {
ScEnd = SE->getAddExpr(
Expand Down
23 changes: 13 additions & 10 deletions llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1643,7 +1643,8 @@ bool LoopVectorizationLegality::canVectorizeLoopNestCFG(
return Result;
}

bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
bool LoopVectorizationLegality::isVectorizableEarlyExitLoop(
const bool NeedRuntimeChecks) {
BasicBlock *LatchBB = TheLoop->getLoopLatch();
if (!LatchBB) {
reportVectorizationFailure("Loop does not have a latch",
Expand Down Expand Up @@ -1851,6 +1852,16 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
return false;
}

// Go over each instruction and look at memory deps.
if (!canVectorizeMemory()) {
LLVM_DEBUG(dbgs() << "LV: Can't vectorize due to memory conflicts\n");
if (DoExtraAnalysis)
Result = false;
else
return false;
}

auto NeedRuntimeChecks = LAI->getRuntimePointerChecking()->Need;
if (isa<SCEVCouldNotCompute>(PSE.getBackedgeTakenCount())) {
if (TheLoop->getExitingBlock()) {
reportVectorizationFailure("Cannot vectorize uncountable loop",
Expand All @@ -1860,7 +1871,7 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
else
return false;
} else {
if (!isVectorizableEarlyExitLoop()) {
if (!isVectorizableEarlyExitLoop(NeedRuntimeChecks)) {
UncountableEdge = std::nullopt;
if (DoExtraAnalysis)
Result = false;
Expand All @@ -1870,14 +1881,6 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
}
}

// Go over each instruction and look at memory deps.
if (!canVectorizeMemory()) {
LLVM_DEBUG(dbgs() << "LV: Can't vectorize due to memory conflicts\n");
if (DoExtraAnalysis)
Result = false;
else
return false;
}

if (Result) {
LLVM_DEBUG(dbgs() << "LV: We can vectorize this loop"
Expand Down
Loading