[llvm] [SCEV] Add option to request use-specific SCEV for a GEP expr, (PR #190677)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 6 13:42:45 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Florian Hahn (fhahn)
<details>
<summary>Changes</summary>
---
Patch is 55.37 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/190677.diff
9 Files Affected:
- (modified) llvm/include/llvm/Analysis/ScalarEvolution.h (+27-18)
- (modified) llvm/lib/Analysis/IVDescriptors.cpp (+1-1)
- (modified) llvm/lib/Analysis/ScalarEvolution.cpp (+68-35)
- (modified) llvm/lib/Passes/PassRegistry.def (+10-1)
- (modified) llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp (+1-1)
- (modified) llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp (+1-1)
- (modified) llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp (+1-1)
- (added) llvm/test/Analysis/ScalarEvolution/use-specific-flags-cache.ll (+34)
- (added) llvm/test/Analysis/ScalarEvolution/use-specific-flags-gep.ll (+594)
``````````diff
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index 5c01da0855f66..fffe7e47c903a 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -145,6 +145,10 @@ struct SCEVUseT : private PointerIntPair<SCEVPtrT, 2> {
SCEVNoWrapFlags
getNoWrapFlags(SCEVNoWrapFlags Mask = SCEVNoWrapFlags::NoWrapMask) const;
+ bool hasNoUnsignedWrap() const {
+ return any(getNoWrapFlags() & SCEVNoWrapFlags::FlagNUW);
+ }
+
/// Return only the use-specific no-wrap flags (NUW/NSW) without the
/// underlying SCEV's flags.
SCEVNoWrapFlags getUseNoWrapFlags() const {
@@ -730,11 +734,12 @@ class ScalarEvolution {
LLVM_ABI bool containsErasedValue(const SCEV *S) const;
/// Return a SCEV expression for the full generality of the specified
- /// expression.
- LLVM_ABI const SCEV *getSCEV(Value *V);
+ /// expression. If \p UseCtx is true, returns a SCEV with use-specific flags
+ /// valid only for existing uses of \p V.
+ LLVM_ABI SCEVUse getSCEV(Value *V, bool UseCtx = false);
/// Return an existing SCEV for V if there is one, otherwise return nullptr.
- LLVM_ABI const SCEV *getExistingSCEV(Value *V);
+ LLVM_ABI SCEVUse getExistingSCEV(Value *V);
LLVM_ABI const SCEV *getConstant(ConstantInt *V);
LLVM_ABI const SCEV *getConstant(const APInt &Val);
@@ -816,12 +821,12 @@ class ScalarEvolution {
/// \p GEP The GEP. The indices contained in the GEP itself are ignored,
/// instead we use IndexExprs.
/// \p IndexExprs The expressions for the indices.
- LLVM_ABI const SCEV *getGEPExpr(GEPOperator *GEP,
- ArrayRef<SCEVUse> IndexExprs);
- LLVM_ABI const SCEV *getGEPExpr(SCEVUse BaseExpr,
- ArrayRef<SCEVUse> IndexExprs,
- Type *SrcElementTy,
- GEPNoWrapFlags NW = GEPNoWrapFlags::none());
+ LLVM_ABI SCEVUse getGEPExpr(GEPOperator *GEP, ArrayRef<SCEVUse> IndexExprs,
+ bool UseCtx = false);
+ LLVM_ABI SCEVUse
+ getGEPExpr(SCEVUse BaseExpr, ArrayRef<SCEVUse> IndexExprs, Type *SrcElementTy,
+ GEPNoWrapFlags NW = GEPNoWrapFlags::none(),
+ GEPNoWrapFlags UseSpecificNW = GEPNoWrapFlags::none());
LLVM_ABI const SCEV *getAbsExpr(const SCEV *Op, bool IsNSW);
LLVM_ABI const SCEV *getMinMaxExpr(SCEVTypes Kind,
SmallVectorImpl<SCEVUse> &Operands);
@@ -1483,7 +1488,7 @@ class ScalarEvolution {
/// Return the size of an element read or written by Inst.
LLVM_ABI const SCEV *getElementSize(Instruction *Inst);
- LLVM_ABI void print(raw_ostream &OS) const;
+ LLVM_ABI void print(raw_ostream &OS, bool UseCtx = false) const;
LLVM_ABI void verify() const;
LLVM_ABI bool invalidate(Function &F, const PreservedAnalyses &PA,
FunctionAnalysisManager::Invalidator &Inv);
@@ -1677,7 +1682,7 @@ class ScalarEvolution {
/// The type for ValueExprMap.
using ValueExprMapType =
- DenseMap<SCEVCallbackVH, const SCEV *, DenseMapInfo<Value *>>;
+ DenseMap<SCEVCallbackVH, SCEVUse, DenseMapInfo<Value *>>;
/// This is a cache of the values we have analyzed so far.
ValueExprMapType ValueExprMap;
@@ -1987,12 +1992,14 @@ class ScalarEvolution {
ConstantRange getRangeForUnknownRecurrence(const SCEVUnknown *U);
/// We know that there is no SCEV for the specified value. Analyze the
- /// expression recursively.
- const SCEV *createSCEV(Value *V);
+ /// expression recursively. If \p UseCtx is true, create a SCEV with
+ /// use-specific flags valid only for existing uses of \p V.
+ SCEVUse createSCEV(Value *V, bool UseCtx = false);
/// We know that there is no SCEV for the specified value. Create a new SCEV
- /// for \p V iteratively.
- const SCEV *createSCEVIter(Value *V);
+ /// for \p V iteratively. If \p UseCtx is true, create a SCEV with
+ /// use-specific flags valid only for existing uses of \p V.
+ SCEVUse createSCEVIter(Value *V, bool UseCtx = false);
/// Collect operands of \p V for which SCEV expressions should be constructed
/// first. Returns a SCEV directly if it can be constructed trivially for \p
/// V.
@@ -2036,7 +2043,7 @@ class ScalarEvolution {
Value *FalseVal);
/// Provide the special handling we need to analyze GEP SCEVs.
- const SCEV *createNodeForGEP(GEPOperator *GEP);
+ SCEVUse createNodeForGEP(GEPOperator *GEP, bool UseCtx = false);
/// Implementation code for getSCEVAtScope; called at most once for each
/// SCEV+Loop pair.
@@ -2349,7 +2356,7 @@ class ScalarEvolution {
void eraseValueFromMap(Value *V);
/// Insert V to S mapping into ValueExprMap and ExprValueMap.
- void insertValueToMap(Value *V, const SCEV *S);
+ void insertValueToMap(Value *V, SCEVUse S);
/// Return false iff given SCEV contains a SCEVUnknown with NULL value-
/// pointer.
@@ -2557,9 +2564,11 @@ class ScalarEvolutionVerifierPass
class ScalarEvolutionPrinterPass
: public PassInfoMixin<ScalarEvolutionPrinterPass> {
raw_ostream &OS;
+ bool UseCtx;
public:
- explicit ScalarEvolutionPrinterPass(raw_ostream &OS) : OS(OS) {}
+ explicit ScalarEvolutionPrinterPass(raw_ostream &OS, bool UseCtx = false)
+ : OS(OS), UseCtx(UseCtx) {}
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
diff --git a/llvm/lib/Analysis/IVDescriptors.cpp b/llvm/lib/Analysis/IVDescriptors.cpp
index 185943e0a9d2e..27bebfe9489ea 100644
--- a/llvm/lib/Analysis/IVDescriptors.cpp
+++ b/llvm/lib/Analysis/IVDescriptors.cpp
@@ -1606,7 +1606,7 @@ bool InductionDescriptor::isInductionPHI(
return false;
// Check that the PHI is consecutive.
- const SCEV *PhiScev = Expr ? Expr : SE->getSCEV(Phi);
+ const SCEV *PhiScev = Expr ? Expr : SE->getSCEV(Phi).getPointer();
const SCEV *Step;
// FIXME: We are currently matching the specific loop TheLoop; if it doesn't
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 2862acfedb91d..62d01ed758d68 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -3887,9 +3887,9 @@ const SCEV *ScalarEvolution::getAddRecExpr(SmallVectorImpl<SCEVUse> &Operands,
return getOrCreateAddRecExpr(Operands, L, Flags);
}
-const SCEV *ScalarEvolution::getGEPExpr(GEPOperator *GEP,
- ArrayRef<SCEVUse> IndexExprs) {
- const SCEV *BaseExpr = getSCEV(GEP->getPointerOperand());
+SCEVUse ScalarEvolution::getGEPExpr(GEPOperator *GEP,
+ ArrayRef<SCEVUse> IndexExprs, bool UseCtx) {
+ SCEVUse BaseExpr = getSCEV(GEP->getPointerOperand(), UseCtx);
// getSCEV(Base)->getType() has the same address space as Base->getType()
// because SCEV::getType() preserves the address space.
GEPNoWrapFlags NW = GEP->getNoWrapFlags();
@@ -3904,12 +3904,15 @@ const SCEV *ScalarEvolution::getGEPExpr(GEPOperator *GEP,
NW = GEPNoWrapFlags::none();
}
- return getGEPExpr(BaseExpr, IndexExprs, GEP->getSourceElementType(), NW);
+ return getGEPExpr(BaseExpr, IndexExprs, GEP->getSourceElementType(), NW,
+ /*UseSpecificNW=*/
+ UseCtx ? GEP->getNoWrapFlags() : GEPNoWrapFlags::none());
}
-const SCEV *ScalarEvolution::getGEPExpr(SCEVUse BaseExpr,
- ArrayRef<SCEVUse> IndexExprs,
- Type *SrcElementTy, GEPNoWrapFlags NW) {
+SCEVUse ScalarEvolution::getGEPExpr(SCEVUse BaseExpr,
+ ArrayRef<SCEVUse> IndexExprs,
+ Type *SrcElementTy, GEPNoWrapFlags NW,
+ GEPNoWrapFlags UseSpecificNW) {
SCEV::NoWrapFlags OffsetWrap = SCEV::FlagAnyWrap;
if (NW.hasNoUnsignedSignedWrap())
OffsetWrap = setFlags(OffsetWrap, SCEV::FlagNSW);
@@ -3967,6 +3970,30 @@ const SCEV *ScalarEvolution::getGEPExpr(SCEVUse BaseExpr,
auto *GEPExpr = getAddExpr(BaseExpr, Offset, BaseWrap);
assert(BaseExpr->getType() == GEPExpr->getType() &&
"GEP should not change type mid-flight.");
+ if (!NUW) {
+ if (UseSpecificNW.hasNoUnsignedWrap() ||
+ (UseSpecificNW.isInBounds() && isKnownNonNegative(Offset))) {
+ // Check if it is safe to annotate the expression with use-specific NUW.
+ // Don't apply it if Base or Offset contain potentially wrapping
+ // sub-expressions that could be flattened into a larger Add expression.
+ auto IsSafeForUseNUW = [](SCEVUse S) {
+ if (any(S.getUseNoWrapFlags() & SCEV::FlagNUW))
+ return true;
+ // Add and AddRec expressions could be flattened into a wider
+ // add, so they need NUW to be safe.
+ if (isa<SCEVAddExpr, SCEVAddRecExpr>(S))
+ return S.hasNoUnsignedWrap();
+ // Conservatively allow a small set of expression forms that are
+ // known safe: they won't be flattened into a wider add.
+ const SCEVUnknown *U;
+ return match(
+ S, m_CombineOr(m_scev_ZExt(m_SCEVUnknown(U)), m_SCEVUnknown(U)));
+ match(S, m_SCEVConstant());
+ };
+ if (IsSafeForUseNUW(BaseExpr) && IsSafeForUseNUW(Offset))
+ return SCEVUse(&*GEPExpr, SCEV::FlagNUW);
+ }
+ }
return GEPExpr;
}
@@ -4705,7 +4732,7 @@ void ScalarEvolution::eraseValueFromMap(Value *V) {
}
}
-void ScalarEvolution::insertValueToMap(Value *V, const SCEV *S) {
+void ScalarEvolution::insertValueToMap(Value *V, SCEVUse S) {
// A recursive query may have already computed the SCEV. It should be
// equivalent, but may not necessarily be exactly the same, e.g. due to lazily
// inferred nowrap flags.
@@ -4718,20 +4745,26 @@ void ScalarEvolution::insertValueToMap(Value *V, const SCEV *S) {
/// Return an existing SCEV if it exists, otherwise analyze the expression and
/// create a new one.
-const SCEV *ScalarEvolution::getSCEV(Value *V) {
+SCEVUse ScalarEvolution::getSCEV(Value *V, bool UseCtx) {
assert(isSCEVable(V->getType()) && "Value is not SCEVable!");
- if (const SCEV *S = getExistingSCEV(V))
+ if (SCEVUse S = getExistingSCEV(V)) {
+ // When not using context-specific flags, return the canonical SCEV
+ // without any use-specific flags.
+ if (!UseCtx)
+ return S.getPointer();
return S;
- return createSCEVIter(V);
+ }
+ // TODO: Should we always create use-specific SCEVs?
+ return createSCEVIter(V, UseCtx);
}
-const SCEV *ScalarEvolution::getExistingSCEV(Value *V) {
+SCEVUse ScalarEvolution::getExistingSCEV(Value *V) {
assert(isSCEVable(V->getType()) && "Value is not SCEVable!");
ValueExprMapType::iterator I = ValueExprMap.find_as(V);
if (I != ValueExprMap.end()) {
- const SCEV *S = I->second;
+ SCEVUse S = I->second;
assert(checkValidity(S) &&
"existing SCEV has not been properly invalidated");
return S;
@@ -6412,9 +6445,9 @@ createNodeForSelectViaUMinSeq(ScalarEvolution *SE, Value *Cond, Value *TrueVal,
if (!isa<ConstantInt>(TrueVal) && !isa<ConstantInt>(FalseVal))
return std::nullopt;
- const auto *SECond = SE->getSCEV(Cond);
- const auto *SETrue = SE->getSCEV(TrueVal);
- const auto *SEFalse = SE->getSCEV(FalseVal);
+ const SCEV *SECond = SE->getSCEV(Cond);
+ const SCEV *SETrue = SE->getSCEV(TrueVal);
+ const SCEV *SEFalse = SE->getSCEV(FalseVal);
return createNodeForSelectViaUMinSeq(SE, SECond, SETrue, SEFalse);
}
@@ -6458,14 +6491,14 @@ const SCEV *ScalarEvolution::createNodeForSelectOrPHI(Value *V, Value *Cond,
/// Expand GEP instructions into add and multiply operations. This allows them
/// to be analyzed by regular SCEV code.
-const SCEV *ScalarEvolution::createNodeForGEP(GEPOperator *GEP) {
+SCEVUse ScalarEvolution::createNodeForGEP(GEPOperator *GEP, bool UseCtx) {
assert(GEP->getSourceElementType()->isSized() &&
"GEP source element type must be sized");
SmallVector<SCEVUse, 4> IndexExprs;
for (Value *Index : GEP->indices())
IndexExprs.push_back(getSCEV(Index));
- return getGEPExpr(GEP, IndexExprs);
+ return getGEPExpr(GEP, IndexExprs, UseCtx);
}
APInt ScalarEvolution::getConstantMultipleImpl(const SCEV *S,
@@ -7689,7 +7722,7 @@ bool ScalarEvolution::loopIsFiniteByAssumption(const Loop *L) {
return isFinite(L) || (isMustProgress(L) && loopHasNoSideEffects(L));
}
-const SCEV *ScalarEvolution::createSCEVIter(Value *V) {
+SCEVUse ScalarEvolution::createSCEVIter(Value *V, bool UseCtx) {
// Worklist item with a Value and a bool indicating whether all operands have
// been visited already.
using PointerTy = PointerIntPair<Value *, 1, bool>;
@@ -7705,10 +7738,10 @@ const SCEV *ScalarEvolution::createSCEVIter(Value *V) {
continue;
SmallVector<Value *> Ops;
- const SCEV *CreatedSCEV = nullptr;
+ SCEVUse CreatedSCEV;
// If all operands have been visited already, create the SCEV.
if (E.getInt()) {
- CreatedSCEV = createSCEV(CurV);
+ CreatedSCEV = createSCEV(CurV, UseCtx);
} else {
// Otherwise get the operands we need to create SCEV's for before creating
// the SCEV for CurV. If the SCEV for CurV can be constructed trivially,
@@ -7964,7 +7997,7 @@ ScalarEvolution::getOperandsToCreate(Value *V, SmallVectorImpl<Value *> &Ops) {
return nullptr;
}
-const SCEV *ScalarEvolution::createSCEV(Value *V) {
+SCEVUse ScalarEvolution::createSCEV(Value *V, bool UseCtx) {
if (!isSCEVable(V->getType()))
return getUnknown(V);
@@ -7999,7 +8032,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
SmallVector<SCEVUse, 4> AddOps;
do {
if (BO->Op) {
- if (auto *OpSCEV = getExistingSCEV(BO->Op)) {
+ if (auto OpSCEV = getExistingSCEV(BO->Op)) {
AddOps.push_back(OpSCEV);
break;
}
@@ -8045,7 +8078,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
SmallVector<SCEVUse, 4> MulOps;
do {
if (BO->Op) {
- if (auto *OpSCEV = getExistingSCEV(BO->Op)) {
+ if (auto OpSCEV = getExistingSCEV(BO->Op)) {
MulOps.push_back(OpSCEV);
break;
}
@@ -8381,7 +8414,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
break;
case Instruction::GetElementPtr:
- return createNodeForGEP(cast<GEPOperator>(U));
+ return createNodeForGEP(cast<GEPOperator>(U), UseCtx);
case Instruction::PHI:
return createNodeForPHI(cast<PHINode>(U));
@@ -9342,7 +9375,7 @@ ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimitFromCondImpl(
NWR.getEquivalentICmp(Pred, NewRHSC, Offset);
if (!ExitIfTrue)
Pred = ICmpInst::getInversePredicate(Pred);
- auto *LHS = getSCEV(WO->getLHS());
+ const SCEV *LHS = getSCEV(WO->getLHS());
if (Offset != 0)
LHS = getAddExpr(LHS, getConstant(Offset));
auto EL = computeExitLimitFromICmp(L, Pred, LHS, getConstant(NewRHSC),
@@ -12783,7 +12816,7 @@ bool ScalarEvolution::isImpliedCondOperandsViaShift(CmpPredicate Pred,
using namespace PatternMatch;
if (match(SUFoundRHS->getValue(),
m_LShr(m_Value(Shiftee), m_Value(ShiftValue)))) {
- auto *ShifteeS = getSCEV(Shiftee);
+ const SCEV *ShifteeS = getSCEV(Shiftee);
// Prove one of the following:
// LHS <u (shiftee >> shiftvalue) && shiftee <=u RHS ---> LHS <u RHS
// LHS <=u (shiftee >> shiftvalue) && shiftee <=u RHS ---> LHS <=u RHS
@@ -13000,7 +13033,7 @@ bool ScalarEvolution::isImpliedViaOperations(CmpPredicate Pred, const SCEV *LHS,
// We want to make sure that LHS = FoundLHS / Denominator. If it is so,
// then a SCEV for the numerator already exists and matches with FoundLHS.
- auto *Numerator = getExistingSCEV(LL);
+ auto Numerator = getExistingSCEV(LL);
if (!Numerator || Numerator->getType() != FoundLHS->getType())
return false;
@@ -14258,7 +14291,7 @@ static raw_ostream &operator<<(raw_ostream &OS,
}
} // namespace llvm
-void ScalarEvolution::print(raw_ostream &OS) const {
+void ScalarEvolution::print(raw_ostream &OS, bool UseCtx) const {
// ScalarEvolution's implementation of the print method is to print
// out SCEV values of all instructions that are interesting. Doing
// this potentially causes it to create new SCEV objects though,
@@ -14275,8 +14308,8 @@ void ScalarEvolution::print(raw_ostream &OS) const {
if (isSCEVable(I.getType()) && !isa<CmpInst>(I)) {
OS << I << '\n';
OS << " --> ";
- const SCEV *SV = SE.getSCEV(&I);
- SV->print(OS);
+ SCEVUse SV = SE.getSCEV(&I, UseCtx);
+ SV.print(OS);
if (!isa<SCEVCouldNotCompute>(SV)) {
OS << " U: ";
SE.getUnsignedRange(SV).print(OS);
@@ -15010,7 +15043,7 @@ ScalarEvolutionPrinterPass::run(Function &F, FunctionAnalysisManager &AM) {
// update_analyze_test_checks.py working.
OS << "Printing analysis 'Scalar Evolution Analysis' for function '"
<< F.getName() << "':\n";
- AM.getResult<ScalarEvolutionAnalysis>(F).print(OS);
+ AM.getResult<ScalarEvolutionAnalysis>(F).print(OS, UseCtx);
return PreservedAnalyses::all();
}
@@ -15621,7 +15654,7 @@ void PredicatedScalarEvolution::print(raw_ostream &OS, unsigned Depth) const {
if (!SE.isSCEVable(I.getType()))
continue;
- auto *Expr = SE.getSCEV(&I);
+ const SCEV *Expr = SE.getSCEV(&I);
auto II = RewriteMap.find(Expr);
if (II == RewriteMap.end())
@@ -16104,8 +16137,8 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
if (auto *Cmp = dyn_cast<ICmpInst>(Cond)) {
auto Predicate =
EnterIfTrue ? Cmp->getPredicate() : Cmp->getInversePredicate();
- const auto *LHS = SE.getSCEV(Cmp->getOperand(0));
- const auto *RHS = SE.getSCEV(Cmp->getOperand(1));
+ const SCEV *LHS = SE.getSCEV(Cmp->getOperand(0));
+ const SCEV *RHS = SE.getSCEV(Cmp->getOperand(1));
// If LHS is a constant, apply information to the other expression.
// TODO: If LHS is not a constant, check if using CompareSCEVComplexity
// can improve results.
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index c92d93d7ae396..9479d9f1fd38c 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -522,7 +522,6 @@ FUNCTION_PASS("print<memoryssa-walker>", MemorySSAWalkerPrinterPass(errs()))
FUNCTION_PASS("print<phi-values>", PhiValuesPrinterPass(errs()))
FUNCTION_PASS("print<postdomtree>", PostDominatorTreePrinterPass(errs()))
FUNCTION_PASS("print<regions>", RegionInfoPrinterPass(errs()))
-FUNCTION_PASS("print<scalar-evolution>", ScalarEvolutionPrinterPass(errs()))
FUNCTION_PASS("print<scev-division>", SCEVDivisionPrinterPass(errs()))
FUNCTION_PASS("print<stack-safety-local>", StackSafetyPrinterPass(errs()))
FUNCTION_PASS("print<uniformity>", UniformityInfoPrinterPass(errs()))
@@ -671,6 +670,16 @@ FUNCTION_PASS_WITH_PARAMS(
return MemorySSAPrinterPass(errs(), !NoEnsureOptimizedUses);
},
parseMemorySSAPrinterPassOptions, "no-ensure-optimized-uses")
+FUNCTION_PASS_WITH_PARAMS(
+ "print<scalar-evolution>", "ScalarEvolutionPrinterPass",
+ [](bool UseCtx) {
+ return ScalarEvolutionPrinterPass(errs(), UseCtx);
+ },
+ [](StringRef Params) {
+ return PassBuilder::parseSinglePassOption(
+ Params, "use-context", "ScalarEvolutionPrinterPass");
+ },
+ "use-context")
FUNCTION_PASS_WITH_PARAMS(
"print<stack-lifetime>", "StackLifetimePrinterPass",
[](StackLifetime::LivenessType Type) {
diff --git a/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp
index ed43fb4b63f87..cd8f4436cb447 100644
--- a/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp
@@ -492,7 +492,7 @@ class StraightLineStrengthReduce {
} CandidateDict;
const SCEV *getAndRecordSCEV(Value *V) {
- auto *S = SE->getSCEV(V);
+ const SCEV *S = SE->getSCEV(V);
if (isa<Instruction>(V) && !(isa<SCEVCouldNotCompute>(S) ||
isa<SCEVUnknown>(S) || isa<SCEVConstant>(S)))
SCEVToInsts[S].insert(cast<Instruction>(V));
diff --git a/llvm/...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/190677
More information about the llvm-commits
mailing list