Skip to content

Commit 0d0c229

Browse files
committed
Revert "Reapply "ValueTracking: Identify implied fp classes by general fcmp (#66505)""
This reverts commit d55692d. See discussion in #66505: assertion fires in OSS build of TensorFlow.
1 parent 1c55b22 commit 0d0c229

File tree

4 files changed

+422
-500
lines changed

4 files changed

+422
-500
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -214,27 +214,6 @@ std::pair<Value *, FPClassTest> fcmpToClassTest(CmpInst::Predicate Pred,
214214
const APFloat *ConstRHS,
215215
bool LookThroughSrc = true);
216216

217-
/// Compute the possible floating-point classes that \p LHS could be based on an
218-
/// fcmp returning true. Returns { TestedValue, ClassesIfTrue, ClassesIfFalse }
219-
///
220-
/// If the compare returns an exact class test, ClassesIfTrue == ~ClassesIfFalse
221-
///
222-
/// This is a less exact version of fcmpToClassTest (e.g. fcmpToClassTest will
223-
/// only succeed for a test of x > 0 implies positive, but not x > 1).
224-
///
225-
/// If \p LookThroughSrc is true, consider the input value when computing the
226-
/// mask. This may look through sign bit operations.
227-
///
228-
/// If \p LookThroughSrc is false, ignore the source value (i.e. the first pair
229-
/// element will always be LHS.
230-
///
231-
std::tuple<Value *, FPClassTest, FPClassTest>
232-
fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS,
233-
const APFloat *ConstRHS, bool LookThroughSrc = true);
234-
std::tuple<Value *, FPClassTest, FPClassTest>
235-
fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS,
236-
Value *RHS, bool LookThroughSrc = true);
237-
238217
struct KnownFPClass {
239218
/// Floating-point classes the value could be one of.
240219
FPClassTest KnownFPClasses = fcAllFlags;

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 19 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -4161,147 +4161,6 @@ llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS,
41614161
return {Src, Mask};
41624162
}
41634163

4164-
std::tuple<Value *, FPClassTest, FPClassTest>
4165-
llvm::fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS,
4166-
const APFloat *ConstRHS, bool LookThroughSrc) {
4167-
auto [Val, ClassMask] =
4168-
fcmpToClassTest(Pred, F, LHS, ConstRHS, LookThroughSrc);
4169-
if (Val)
4170-
return {Val, ClassMask, ~ClassMask};
4171-
4172-
FPClassTest RHSClass = ConstRHS->classify();
4173-
4174-
// If we see a zero here, we are using dynamic denormal-fp-math, and can't
4175-
// treat comparisons to 0 as an exact class test.
4176-
//
4177-
// TODO: We could do better and still recognize non-equality cases.
4178-
if (RHSClass == fcPosZero || RHSClass == fcNegZero)
4179-
return {nullptr, fcAllFlags, fcAllFlags};
4180-
4181-
assert((RHSClass == fcPosNormal || RHSClass == fcNegNormal ||
4182-
RHSClass == fcPosSubnormal || RHSClass == fcNegSubnormal) &&
4183-
"should have been recognized as an exact class test");
4184-
4185-
const bool IsNegativeRHS = (RHSClass & fcNegative) == RHSClass;
4186-
const bool IsPositiveRHS = (RHSClass & fcPositive) == RHSClass;
4187-
4188-
assert(IsNegativeRHS == ConstRHS->isNegative());
4189-
assert(IsPositiveRHS == !ConstRHS->isNegative());
4190-
4191-
Value *Src = LHS;
4192-
const bool IsFabs = LookThroughSrc && match(LHS, m_FAbs(m_Value(Src)));
4193-
4194-
if (IsFabs)
4195-
RHSClass = llvm::inverse_fabs(RHSClass);
4196-
4197-
if (Pred == FCmpInst::FCMP_OEQ)
4198-
return {Src, RHSClass, fcAllFlags};
4199-
4200-
if (Pred == FCmpInst::FCMP_UEQ) {
4201-
FPClassTest Class = RHSClass | fcNan;
4202-
return {Src, Class, ~fcNan};
4203-
}
4204-
4205-
if (Pred == FCmpInst::FCMP_ONE)
4206-
return {Src, ~fcNan, RHSClass};
4207-
4208-
if (Pred == FCmpInst::FCMP_UNE)
4209-
return {Src, fcAllFlags, RHSClass};
4210-
4211-
if (IsNegativeRHS) {
4212-
// TODO: Handle fneg(fabs)
4213-
if (IsFabs) {
4214-
// fabs(x) o> -k -> fcmp ord x, x
4215-
// fabs(x) u> -k -> true
4216-
// fabs(x) o< -k -> false
4217-
// fabs(x) u< -k -> fcmp uno x, x
4218-
switch (Pred) {
4219-
case FCmpInst::FCMP_OGT:
4220-
case FCmpInst::FCMP_OGE:
4221-
return {Src, ~fcNan, fcNan};
4222-
case FCmpInst::FCMP_UGT:
4223-
case FCmpInst::FCMP_UGE:
4224-
return {Src, fcAllFlags, fcNone};
4225-
case FCmpInst::FCMP_OLT:
4226-
case FCmpInst::FCMP_OLE:
4227-
return {Src, fcNone, fcAllFlags};
4228-
case FCmpInst::FCMP_ULT:
4229-
case FCmpInst::FCMP_ULE:
4230-
return {Src, fcNan, ~fcNan};
4231-
default:
4232-
break;
4233-
}
4234-
4235-
return {nullptr, fcAllFlags, fcAllFlags};
4236-
}
4237-
4238-
FPClassTest ClassesLE = fcNegInf | fcNegNormal;
4239-
FPClassTest ClassesGE = fcPositive | fcNegZero | fcNegSubnormal;
4240-
4241-
if (ConstRHS->isDenormal())
4242-
ClassesLE |= fcNegSubnormal;
4243-
else
4244-
ClassesGE |= fcNegNormal;
4245-
4246-
switch (Pred) {
4247-
case FCmpInst::FCMP_OGT:
4248-
case FCmpInst::FCMP_OGE:
4249-
return {Src, ClassesGE, ~ClassesGE | RHSClass};
4250-
case FCmpInst::FCMP_UGT:
4251-
case FCmpInst::FCMP_UGE:
4252-
return {Src, ClassesGE | fcNan, ~(ClassesGE | fcNan) | RHSClass};
4253-
case FCmpInst::FCMP_OLT:
4254-
case FCmpInst::FCMP_OLE:
4255-
return {Src, ClassesLE, ~ClassesLE | RHSClass};
4256-
case FCmpInst::FCMP_ULT:
4257-
case FCmpInst::FCMP_ULE:
4258-
return {Src, ClassesLE | fcNan, ~(ClassesLE | fcNan) | RHSClass};
4259-
default:
4260-
break;
4261-
}
4262-
} else if (IsPositiveRHS) {
4263-
FPClassTest ClassesGE = fcPosNormal | fcPosInf;
4264-
FPClassTest ClassesLE = fcNegative | fcPosZero | fcPosNormal;
4265-
if (ConstRHS->isDenormal())
4266-
ClassesGE |= fcPosNormal;
4267-
else
4268-
ClassesLE |= fcPosSubnormal;
4269-
4270-
if (IsFabs) {
4271-
ClassesGE = llvm::inverse_fabs(ClassesGE);
4272-
ClassesLE = llvm::inverse_fabs(ClassesLE);
4273-
}
4274-
4275-
switch (Pred) {
4276-
case FCmpInst::FCMP_OGT:
4277-
case FCmpInst::FCMP_OGE:
4278-
return {Src, ClassesGE, ~ClassesGE | RHSClass};
4279-
case FCmpInst::FCMP_UGT:
4280-
case FCmpInst::FCMP_UGE:
4281-
return {Src, ClassesGE | fcNan, ~(ClassesGE | fcNan) | RHSClass};
4282-
case FCmpInst::FCMP_OLT:
4283-
case FCmpInst::FCMP_OLE:
4284-
return {Src, ClassesLE, ~ClassesLE | RHSClass};
4285-
case FCmpInst::FCMP_ULT:
4286-
case FCmpInst::FCMP_ULE:
4287-
return {Src, ClassesLE | fcNan, ~(ClassesLE | fcNan) | RHSClass};
4288-
default:
4289-
break;
4290-
}
4291-
}
4292-
4293-
return {nullptr, fcAllFlags, fcAllFlags};
4294-
}
4295-
4296-
std::tuple<Value *, FPClassTest, FPClassTest>
4297-
llvm::fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS,
4298-
Value *RHS, bool LookThroughSrc) {
4299-
const APFloat *ConstRHS;
4300-
if (!match(RHS, m_APFloatAllowUndef(ConstRHS)))
4301-
return {nullptr, fcAllFlags, fcNone};
4302-
return fcmpImpliesClass(Pred, F, LHS, ConstRHS, LookThroughSrc);
4303-
}
4304-
43054164
static FPClassTest computeKnownFPClassFromAssumes(const Value *V,
43064165
const SimplifyQuery &Q) {
43074166
FPClassTest KnownFromAssume = fcAllFlags;
@@ -4326,21 +4185,18 @@ static FPClassTest computeKnownFPClassFromAssumes(const Value *V,
43264185
Value *LHS, *RHS;
43274186
uint64_t ClassVal = 0;
43284187
if (match(I->getArgOperand(0), m_FCmp(Pred, m_Value(LHS), m_Value(RHS)))) {
4329-
const APFloat *CRHS;
4330-
if (match(RHS, m_APFloat(CRHS))) {
4331-
// First see if we can fold in fabs/fneg into the test.
4332-
auto [CmpVal, MaskIfTrue, MaskIfFalse] =
4333-
fcmpImpliesClass(Pred, *F, LHS, CRHS, true);
4334-
if (CmpVal == V)
4335-
KnownFromAssume &= MaskIfTrue;
4336-
else {
4337-
// Try again without the lookthrough if we found a different source
4338-
// value.
4339-
auto [CmpVal, MaskIfTrue, MaskIfFalse] =
4340-
fcmpImpliesClass(Pred, *F, LHS, CRHS, false);
4341-
if (CmpVal == V)
4342-
KnownFromAssume &= MaskIfTrue;
4343-
}
4188+
auto [TestedValue, TestedMask] =
4189+
fcmpToClassTest(Pred, *F, LHS, RHS, true);
4190+
// First see if we can fold in fabs/fneg into the test.
4191+
if (TestedValue == V)
4192+
KnownFromAssume &= TestedMask;
4193+
else {
4194+
// Try again without the lookthrough if we found a different source
4195+
// value.
4196+
auto [TestedValue, TestedMask] =
4197+
fcmpToClassTest(Pred, *F, LHS, RHS, false);
4198+
if (TestedValue == V)
4199+
KnownFromAssume &= TestedMask;
43444200
}
43454201
} else if (match(I->getArgOperand(0),
43464202
m_Intrinsic<Intrinsic::is_fpclass>(
@@ -4488,8 +4344,7 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
44884344
FPClassTest FilterRHS = fcAllFlags;
44894345

44904346
Value *TestedValue = nullptr;
4491-
FPClassTest MaskIfTrue = fcAllFlags;
4492-
FPClassTest MaskIfFalse = fcAllFlags;
4347+
FPClassTest TestedMask = fcNone;
44934348
uint64_t ClassVal = 0;
44944349
const Function *F = cast<Instruction>(Op)->getFunction();
44954350
CmpInst::Predicate Pred;
@@ -4501,22 +4356,20 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
45014356
// TODO: In some degenerate cases we can infer something if we try again
45024357
// without looking through sign operations.
45034358
bool LookThroughFAbsFNeg = CmpLHS != LHS && CmpLHS != RHS;
4504-
std::tie(TestedValue, MaskIfTrue, MaskIfFalse) =
4505-
fcmpImpliesClass(Pred, *F, CmpLHS, CmpRHS, LookThroughFAbsFNeg);
4359+
std::tie(TestedValue, TestedMask) =
4360+
fcmpToClassTest(Pred, *F, CmpLHS, CmpRHS, LookThroughFAbsFNeg);
45064361
} else if (match(Cond,
45074362
m_Intrinsic<Intrinsic::is_fpclass>(
45084363
m_Value(TestedValue), m_ConstantInt(ClassVal)))) {
4509-
FPClassTest TestedMask = static_cast<FPClassTest>(ClassVal);
4510-
MaskIfTrue = TestedMask;
4511-
MaskIfFalse = ~TestedMask;
4364+
TestedMask = static_cast<FPClassTest>(ClassVal);
45124365
}
45134366

45144367
if (TestedValue == LHS) {
45154368
// match !isnan(x) ? x : y
4516-
FilterLHS = MaskIfTrue;
4517-
} else if (TestedValue == RHS) { // && IsExactClass
4369+
FilterLHS = TestedMask;
4370+
} else if (TestedValue == RHS) {
45184371
// match !isnan(x) ? y : x
4519-
FilterRHS = MaskIfFalse;
4372+
FilterRHS = ~TestedMask;
45204373
}
45214374

45224375
KnownFPClass Known2;

0 commit comments

Comments
 (0)