Analysis: Remove no-AssumptionCache path in getKnowledgeForValue (#139232)

As requested in https://github.com/llvm/llvm-project/pull/138961#discussion_r2078483175
This commit is contained in:
Matt Arsenault
2025-05-09 12:23:38 +02:00
committed by GitHub
parent e854c381c6
commit 89d13f87c7
5 changed files with 24 additions and 41 deletions

View File

@@ -152,18 +152,19 @@ RetainedKnowledge getKnowledgeFromUse(const Use *U,
/// in AttrKinds and it matches the Filter.
RetainedKnowledge getKnowledgeForValue(
const Value *V, ArrayRef<Attribute::AttrKind> AttrKinds,
AssumptionCache *AC = nullptr,
AssumptionCache &AC,
function_ref<bool(RetainedKnowledge, Instruction *,
const CallBase::BundleOpInfo *)>
const CallBase::BundleOpInfo *)>
Filter = [](auto...) { return true; });
/// Return a valid Knowledge associated to the Value V if its Attribute kind is
/// in AttrKinds and the knowledge is suitable to be used in the context of
/// CtxI.
RetainedKnowledge getKnowledgeValidInContext(
const Value *V, ArrayRef<Attribute::AttrKind> AttrKinds,
const Instruction *CtxI, const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr);
RetainedKnowledge
getKnowledgeValidInContext(const Value *V,
ArrayRef<Attribute::AttrKind> AttrKinds,
AssumptionCache &AC, const Instruction *CtxI,
const DominatorTree *DT = nullptr);
/// This extracts the Knowledge from an element of an operand bundle.
/// This is mostly for use in the assume builder.

View File

@@ -157,51 +157,33 @@ llvm::getKnowledgeFromUse(const Use *U,
RetainedKnowledge
llvm::getKnowledgeForValue(const Value *V,
ArrayRef<Attribute::AttrKind> AttrKinds,
AssumptionCache *AC,
AssumptionCache &AC,
function_ref<bool(RetainedKnowledge, Instruction *,
const CallBase::BundleOpInfo *)>
Filter) {
NumAssumeQueries++;
if (AC) {
for (AssumptionCache::ResultElem &Elem : AC->assumptionsFor(V)) {
auto *II = cast_or_null<AssumeInst>(Elem.Assume);
if (!II || Elem.Index == AssumptionCache::ExprResultIdx)
continue;
if (RetainedKnowledge RK = getKnowledgeFromBundle(
*II, II->bundle_op_info_begin()[Elem.Index])) {
if (V != RK.WasOn)
continue;
if (is_contained(AttrKinds, RK.AttrKind) &&
Filter(RK, II, &II->bundle_op_info_begin()[Elem.Index])) {
NumUsefullAssumeQueries++;
return RK;
}
}
}
return RetainedKnowledge::none();
}
if (!V->hasUseList())
return RetainedKnowledge::none();
for (const auto &U : V->uses()) {
CallInst::BundleOpInfo* Bundle = getBundleFromUse(&U);
if (!Bundle)
for (AssumptionCache::ResultElem &Elem : AC.assumptionsFor(V)) {
auto *II = cast_or_null<AssumeInst>(Elem.Assume);
if (!II || Elem.Index == AssumptionCache::ExprResultIdx)
continue;
if (RetainedKnowledge RK =
getKnowledgeFromBundle(*cast<AssumeInst>(U.getUser()), *Bundle))
if (RetainedKnowledge RK = getKnowledgeFromBundle(
*II, II->bundle_op_info_begin()[Elem.Index])) {
if (V != RK.WasOn)
continue;
if (is_contained(AttrKinds, RK.AttrKind) &&
Filter(RK, cast<Instruction>(U.getUser()), Bundle)) {
Filter(RK, II, &II->bundle_op_info_begin()[Elem.Index])) {
NumUsefullAssumeQueries++;
return RK;
}
}
}
return RetainedKnowledge::none();
}
RetainedKnowledge llvm::getKnowledgeValidInContext(
const Value *V, ArrayRef<Attribute::AttrKind> AttrKinds,
const Instruction *CtxI, const DominatorTree *DT, AssumptionCache *AC) {
AssumptionCache &AC, const Instruction *CtxI, const DominatorTree *DT) {
return getKnowledgeForValue(V, AttrKinds, AC,
[&](auto, Instruction *I, auto) {
return isValidAssumeForContext(I, CtxI, DT);

View File

@@ -174,14 +174,14 @@ static bool isDereferenceableAndAlignedPointer(
// information for values that cannot be freed in the function.
// TODO: More precisely check if the pointer can be freed between assumption
// and use.
if (CtxI && !V->canBeFreed()) {
if (CtxI && AC && !V->canBeFreed()) {
/// Look through assumes to see if both dereferencability and alignment can
/// be proven by an assume if needed.
RetainedKnowledge AlignRK;
RetainedKnowledge DerefRK;
bool IsAligned = V->getPointerAlignment(DL) >= Alignment;
if (getKnowledgeForValue(
V, {Attribute::Dereferenceable, Attribute::Alignment}, AC,
V, {Attribute::Dereferenceable, Attribute::Alignment}, *AC,
[&](RetainedKnowledge RK, Instruction *Assume, auto) {
if (!isValidAssumeForContext(Assume, CtxI, DT))
return false;

View File

@@ -8010,7 +8010,7 @@ static bool isGuaranteedNotToBeUndefOrPoison(
Dominator = Dominator->getIDom();
}
if (getKnowledgeValidInContext(V, {Attribute::NoUndef}, CtxI, DT, AC))
if (AC && getKnowledgeValidInContext(V, {Attribute::NoUndef}, *AC, CtxI, DT))
return true;
return false;

View File

@@ -114,12 +114,12 @@ struct AssumeBuilderState {
: M(M), InstBeingModified(I), AC(AC), DT(DT) {}
bool tryToPreserveWithoutAddingAssume(RetainedKnowledge RK) {
if (!InstBeingModified || !RK.WasOn)
if (!InstBeingModified || !RK.WasOn || !AC)
return false;
bool HasBeenPreserved = false;
Use* ToUpdate = nullptr;
getKnowledgeForValue(
RK.WasOn, {RK.AttrKind}, AC,
RK.WasOn, {RK.AttrKind}, *AC,
[&](RetainedKnowledge RKOther, Instruction *Assume,
const CallInst::BundleOpInfo *Bundle) {
if (!isValidAssumeForContext(Assume, InstBeingModified, DT))