Skip to content

Commit 542a3cb

Browse files
authored
[ValueTracking] Compute known FPClass from dominating condition (#80941)
This patch improves `computeKnownFPClass` by using context-sensitive information from `DomConditionCache`.
1 parent 95a204c commit 542a3cb

File tree

3 files changed

+392
-28
lines changed

3 files changed

+392
-28
lines changed

llvm/lib/Analysis/DomConditionCache.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static void findAffectedValues(Value *Cond,
4343
if (!Visited.insert(V).second)
4444
continue;
4545

46-
ICmpInst::Predicate Pred;
46+
CmpInst::Predicate Pred;
4747
Value *A, *B;
4848
// Only recurse into and/or if it matches the top-level and/or type.
4949
if (TopLevelIsAnd ? match(V, m_LogicalAnd(m_Value(A), m_Value(B)))
@@ -67,6 +67,11 @@ static void findAffectedValues(Value *Cond,
6767
if (match(A, m_Add(m_Value(X), m_ConstantInt())))
6868
AddAffected(X);
6969
}
70+
} else if (match(Cond, m_CombineOr(m_FCmp(Pred, m_Value(A), m_Constant()),
71+
m_Intrinsic<Intrinsic::is_fpclass>(
72+
m_Value(A), m_Constant())))) {
73+
// Handle patterns that computeKnownFPClass() support.
74+
AddAffected(A);
7075
}
7176
}
7277
}

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4225,9 +4225,53 @@ llvm::fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS,
42254225
return fcmpImpliesClass(Pred, F, LHS, *ConstRHS, LookThroughSrc);
42264226
}
42274227

4228-
static FPClassTest computeKnownFPClassFromAssumes(const Value *V,
4229-
const SimplifyQuery &Q) {
4230-
FPClassTest KnownFromAssume = fcAllFlags;
4228+
static void computeKnownFPClassFromCond(const Value *V, Value *Cond,
4229+
bool CondIsTrue,
4230+
const Instruction *CxtI,
4231+
KnownFPClass &KnownFromContext) {
4232+
CmpInst::Predicate Pred;
4233+
Value *LHS;
4234+
uint64_t ClassVal = 0;
4235+
const APFloat *CRHS;
4236+
// TODO: handle sign-bit check idiom
4237+
if (match(Cond, m_FCmp(Pred, m_Value(LHS), m_APFloat(CRHS)))) {
4238+
auto [CmpVal, MaskIfTrue, MaskIfFalse] = fcmpImpliesClass(
4239+
Pred, *CxtI->getParent()->getParent(), LHS, *CRHS, LHS != V);
4240+
if (CmpVal == V)
4241+
KnownFromContext.knownNot(~(CondIsTrue ? MaskIfTrue : MaskIfFalse));
4242+
} else if (match(Cond, m_Intrinsic<Intrinsic::is_fpclass>(
4243+
m_Value(LHS), m_ConstantInt(ClassVal)))) {
4244+
FPClassTest Mask = static_cast<FPClassTest>(ClassVal);
4245+
KnownFromContext.knownNot(CondIsTrue ? ~Mask : Mask);
4246+
}
4247+
}
4248+
4249+
static KnownFPClass computeKnownFPClassFromContext(const Value *V,
4250+
const SimplifyQuery &Q) {
4251+
KnownFPClass KnownFromContext;
4252+
4253+
if (!Q.CxtI)
4254+
return KnownFromContext;
4255+
4256+
if (Q.DC && Q.DT) {
4257+
// Handle dominating conditions.
4258+
for (BranchInst *BI : Q.DC->conditionsFor(V)) {
4259+
Value *Cond = BI->getCondition();
4260+
4261+
BasicBlockEdge Edge0(BI->getParent(), BI->getSuccessor(0));
4262+
if (Q.DT->dominates(Edge0, Q.CxtI->getParent()))
4263+
computeKnownFPClassFromCond(V, Cond, /*CondIsTrue=*/true, Q.CxtI,
4264+
KnownFromContext);
4265+
4266+
BasicBlockEdge Edge1(BI->getParent(), BI->getSuccessor(1));
4267+
if (Q.DT->dominates(Edge1, Q.CxtI->getParent()))
4268+
computeKnownFPClassFromCond(V, Cond, /*CondIsTrue=*/false, Q.CxtI,
4269+
KnownFromContext);
4270+
}
4271+
}
4272+
4273+
if (!Q.AC)
4274+
return KnownFromContext;
42314275

42324276
// Try to restrict the floating-point classes based on information from
42334277
// assumptions.
@@ -4245,25 +4289,11 @@ static FPClassTest computeKnownFPClassFromAssumes(const Value *V,
42454289
if (!isValidAssumeForContext(I, Q.CxtI, Q.DT))
42464290
continue;
42474291

4248-
CmpInst::Predicate Pred;
4249-
Value *LHS, *RHS;
4250-
uint64_t ClassVal = 0;
4251-
if (match(I->getArgOperand(0), m_FCmp(Pred, m_Value(LHS), m_Value(RHS)))) {
4252-
const APFloat *CRHS;
4253-
if (match(RHS, m_APFloat(CRHS))) {
4254-
auto [CmpVal, MaskIfTrue, MaskIfFalse] =
4255-
fcmpImpliesClass(Pred, *F, LHS, *CRHS, LHS != V);
4256-
if (CmpVal == V)
4257-
KnownFromAssume &= MaskIfTrue;
4258-
}
4259-
} else if (match(I->getArgOperand(0),
4260-
m_Intrinsic<Intrinsic::is_fpclass>(
4261-
m_Value(LHS), m_ConstantInt(ClassVal)))) {
4262-
KnownFromAssume &= static_cast<FPClassTest>(ClassVal);
4263-
}
4292+
computeKnownFPClassFromCond(V, I->getArgOperand(0), /*CondIsTrue=*/true,
4293+
Q.CxtI, KnownFromContext);
42644294
}
42654295

4266-
return KnownFromAssume;
4296+
return KnownFromContext;
42674297
}
42684298

42694299
void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
@@ -4371,17 +4401,21 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
43714401
KnownNotFromFlags |= fcInf;
43724402
}
43734403

4374-
if (Q.AC) {
4375-
FPClassTest AssumedClasses = computeKnownFPClassFromAssumes(V, Q);
4376-
KnownNotFromFlags |= ~AssumedClasses;
4377-
}
4404+
KnownFPClass AssumedClasses = computeKnownFPClassFromContext(V, Q);
4405+
KnownNotFromFlags |= ~AssumedClasses.KnownFPClasses;
43784406

43794407
// We no longer need to find out about these bits from inputs if we can
43804408
// assume this from flags/attributes.
43814409
InterestedClasses &= ~KnownNotFromFlags;
43824410

43834411
auto ClearClassesFromFlags = make_scope_exit([=, &Known] {
43844412
Known.knownNot(KnownNotFromFlags);
4413+
if (!Known.SignBit && AssumedClasses.SignBit) {
4414+
if (*AssumedClasses.SignBit)
4415+
Known.signBitMustBeOne();
4416+
else
4417+
Known.signBitMustBeZero();
4418+
}
43854419
});
43864420

43874421
if (!Op)
@@ -5283,7 +5317,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
52835317

52845318
bool First = true;
52855319

5286-
for (Value *IncValue : P->incoming_values()) {
5320+
for (const Use &U : P->operands()) {
5321+
Value *IncValue = U.get();
52875322
// Skip direct self references.
52885323
if (IncValue == P)
52895324
continue;
@@ -5292,8 +5327,10 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
52925327
// Recurse, but cap the recursion to two levels, because we don't want
52935328
// to waste time spinning around in loops. We need at least depth 2 to
52945329
// detect known sign bits.
5295-
computeKnownFPClass(IncValue, DemandedElts, InterestedClasses, KnownSrc,
5296-
PhiRecursionLimit, Q);
5330+
computeKnownFPClass(
5331+
IncValue, DemandedElts, InterestedClasses, KnownSrc,
5332+
PhiRecursionLimit,
5333+
Q.getWithInstruction(P->getIncomingBlock(U)->getTerminator()));
52975334

52985335
if (First) {
52995336
Known = KnownSrc;

0 commit comments

Comments
 (0)