Skip to content

Commit 82d1d50

Browse files
committed
[ValueTracking] Merge cannotBeOrderedLessThanZeroImpl into computeKnownFPClass
1 parent a4098bc commit 82d1d50

File tree

7 files changed

+89
-242
lines changed

7 files changed

+89
-242
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,12 @@ struct KnownFPClass {
332332

333333
void knownNot(FPClassTest RuleOut) {
334334
KnownFPClasses = KnownFPClasses & ~RuleOut;
335+
if (isKnownNever(fcNan) && !SignBit) {
336+
if (isKnownNever(OrderedLessThanZeroMask | fcNegZero))
337+
SignBit = false;
338+
else if (isKnownNever(OrderedGreaterThanZeroMask | fcPosZero))
339+
SignBit = true;
340+
}
335341
}
336342

337343
void fneg() {
@@ -367,6 +373,12 @@ struct KnownFPClass {
367373
SignBit = false;
368374
}
369375

376+
/// Assume the sign bit is one.
377+
void signBitMustBeOne() {
378+
KnownFPClasses &= (fcNegative | fcNan);
379+
SignBit = true;
380+
}
381+
370382
void copysign(const KnownFPClass &Sign) {
371383
// Don't know anything about the sign of the source. Expand the possible set
372384
// to its opposite sign pair.
@@ -553,15 +565,18 @@ inline bool isKnownNeverNaN(const Value *V, const DataLayout &DL,
553565
return Known.isKnownNeverNaN();
554566
}
555567

556-
/// Return true if we can prove that the specified FP value's sign bit is 0.
557-
///
558-
/// NaN --> true/false (depending on the NaN's sign bit)
559-
/// +0 --> true
560-
/// -0 --> false
561-
/// x > +0 --> true
562-
/// x < -0 --> false
563-
bool SignBitMustBeZero(const Value *V, const DataLayout &DL,
564-
const TargetLibraryInfo *TLI);
568+
/// Return false if we can prove that the specified FP value's sign bit is 0.
569+
/// Return true if we can prove that the specified FP value's sign bit is 1.
570+
/// Otherwise return std::nullopt.
571+
inline std::optional<bool> computeKnownFPSignBit(
572+
const Value *V, const DataLayout &DL,
573+
const TargetLibraryInfo *TLI = nullptr, unsigned Depth = 0,
574+
AssumptionCache *AC = nullptr, const Instruction *CtxI = nullptr,
575+
const DominatorTree *DT = nullptr, bool UseInstrInfo = true) {
576+
KnownFPClass Known = computeKnownFPClass(V, DL, fcAllFlags, Depth, TLI, AC,
577+
CtxI, DT, UseInstrInfo);
578+
return Known.SignBit;
579+
}
565580

566581
/// If the specified value can be set by repeating the same byte in memory,
567582
/// return the i8 value that it is represented with. This is true for all i8

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5762,9 +5762,9 @@ static Value *simplifyFMAFMul(Value *Op0, Value *Op1, FastMathFlags FMF,
57625762
return ConstantFP::getZero(Op0->getType());
57635763

57645764
// +normal number * (-)0.0 --> (-)0.0
5765-
if (isKnownNeverInfOrNaN(Op0, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT) &&
5766-
// TODO: Check SignBit from computeKnownFPClass when it's more complete.
5767-
SignBitMustBeZero(Op0, Q.DL, Q.TLI))
5765+
KnownFPClass Known = computeKnownFPClass(
5766+
Op0, FMF, Q.DL, fcInf | fcNan, /*Depth=*/0, Q.TLI, Q.AC, Q.CxtI, Q.DT);
5767+
if (Known.SignBit == false && Known.isKnownNever(fcInf | fcNan))
57685768
return Op1;
57695769
}
57705770

@@ -6217,7 +6217,8 @@ static Value *simplifyUnaryIntrinsic(Function *F, Value *Op0,
62176217
Value *X;
62186218
switch (IID) {
62196219
case Intrinsic::fabs:
6220-
if (SignBitMustBeZero(Op0, Q.DL, Q.TLI))
6220+
if (computeKnownFPSignBit(Op0, Q.DL, Q.TLI, /*Depth=*/0, Q.AC, Q.CxtI,
6221+
Q.DT) == false)
62216222
return Op0;
62226223
break;
62236224
case Intrinsic::bswap:

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 39 additions & 207 deletions
Original file line numberDiff line numberDiff line change
@@ -3704,205 +3704,6 @@ Intrinsic::ID llvm::getIntrinsicForCallSite(const CallBase &CB,
37043704
return Intrinsic::not_intrinsic;
37053705
}
37063706

3707-
/// Deprecated, use computeKnownFPClass instead.
3708-
///
3709-
/// If \p SignBitOnly is true, test for a known 0 sign bit rather than a
3710-
/// standard ordered compare. e.g. make -0.0 olt 0.0 be true because of the sign
3711-
/// bit despite comparing equal.
3712-
static bool cannotBeOrderedLessThanZeroImpl(const Value *V,
3713-
const DataLayout &DL,
3714-
const TargetLibraryInfo *TLI,
3715-
bool SignBitOnly, unsigned Depth) {
3716-
// TODO: This function does not do the right thing when SignBitOnly is true
3717-
// and we're lowering to a hypothetical IEEE 754-compliant-but-evil platform
3718-
// which flips the sign bits of NaNs. See
3719-
// https://llvm.org/bugs/show_bug.cgi?id=31702.
3720-
3721-
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(V)) {
3722-
return !CFP->getValueAPF().isNegative() ||
3723-
(!SignBitOnly && CFP->getValueAPF().isZero());
3724-
}
3725-
3726-
// Handle vector of constants.
3727-
if (auto *CV = dyn_cast<Constant>(V)) {
3728-
if (auto *CVFVTy = dyn_cast<FixedVectorType>(CV->getType())) {
3729-
unsigned NumElts = CVFVTy->getNumElements();
3730-
for (unsigned i = 0; i != NumElts; ++i) {
3731-
auto *CFP = dyn_cast_or_null<ConstantFP>(CV->getAggregateElement(i));
3732-
if (!CFP)
3733-
return false;
3734-
if (CFP->getValueAPF().isNegative() &&
3735-
(SignBitOnly || !CFP->getValueAPF().isZero()))
3736-
return false;
3737-
}
3738-
3739-
// All non-negative ConstantFPs.
3740-
return true;
3741-
}
3742-
}
3743-
3744-
if (Depth == MaxAnalysisRecursionDepth)
3745-
return false;
3746-
3747-
const Operator *I = dyn_cast<Operator>(V);
3748-
if (!I)
3749-
return false;
3750-
3751-
switch (I->getOpcode()) {
3752-
default:
3753-
break;
3754-
// Unsigned integers are always nonnegative.
3755-
case Instruction::UIToFP:
3756-
return true;
3757-
case Instruction::FDiv:
3758-
// X / X is always exactly 1.0 or a NaN.
3759-
if (I->getOperand(0) == I->getOperand(1) &&
3760-
(!SignBitOnly || cast<FPMathOperator>(I)->hasNoNaNs()))
3761-
return true;
3762-
3763-
// Set SignBitOnly for RHS, because X / -0.0 is -Inf (or NaN).
3764-
return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), DL, TLI,
3765-
SignBitOnly, Depth + 1) &&
3766-
cannotBeOrderedLessThanZeroImpl(I->getOperand(1), DL, TLI,
3767-
/*SignBitOnly*/ true, Depth + 1);
3768-
case Instruction::FMul:
3769-
// X * X is always non-negative or a NaN.
3770-
if (I->getOperand(0) == I->getOperand(1) &&
3771-
(!SignBitOnly || cast<FPMathOperator>(I)->hasNoNaNs()))
3772-
return true;
3773-
3774-
[[fallthrough]];
3775-
case Instruction::FAdd:
3776-
case Instruction::FRem:
3777-
return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), DL, TLI,
3778-
SignBitOnly, Depth + 1) &&
3779-
cannotBeOrderedLessThanZeroImpl(I->getOperand(1), DL, TLI,
3780-
SignBitOnly, Depth + 1);
3781-
case Instruction::Select:
3782-
return cannotBeOrderedLessThanZeroImpl(I->getOperand(1), DL, TLI,
3783-
SignBitOnly, Depth + 1) &&
3784-
cannotBeOrderedLessThanZeroImpl(I->getOperand(2), DL, TLI,
3785-
SignBitOnly, Depth + 1);
3786-
case Instruction::FPExt:
3787-
case Instruction::FPTrunc:
3788-
// Widening/narrowing never change sign.
3789-
return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), DL, TLI,
3790-
SignBitOnly, Depth + 1);
3791-
case Instruction::ExtractElement:
3792-
// Look through extract element. At the moment we keep this simple and skip
3793-
// tracking the specific element. But at least we might find information
3794-
// valid for all elements of the vector.
3795-
return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), DL, TLI,
3796-
SignBitOnly, Depth + 1);
3797-
case Instruction::Call:
3798-
const auto *CI = cast<CallInst>(I);
3799-
Intrinsic::ID IID = getIntrinsicForCallSite(*CI, TLI);
3800-
switch (IID) {
3801-
default:
3802-
break;
3803-
case Intrinsic::canonicalize:
3804-
case Intrinsic::arithmetic_fence:
3805-
case Intrinsic::floor:
3806-
case Intrinsic::ceil:
3807-
case Intrinsic::trunc:
3808-
case Intrinsic::rint:
3809-
case Intrinsic::nearbyint:
3810-
case Intrinsic::round:
3811-
case Intrinsic::roundeven:
3812-
case Intrinsic::fptrunc_round:
3813-
return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), DL, TLI,
3814-
SignBitOnly, Depth + 1);
3815-
case Intrinsic::maxnum: {
3816-
Value *V0 = I->getOperand(0), *V1 = I->getOperand(1);
3817-
auto isPositiveNum = [&](Value *V) {
3818-
if (SignBitOnly) {
3819-
// With SignBitOnly, this is tricky because the result of
3820-
// maxnum(+0.0, -0.0) is unspecified. Just check if the operand is
3821-
// a constant strictly greater than 0.0.
3822-
const APFloat *C;
3823-
return match(V, m_APFloat(C)) &&
3824-
*C > APFloat::getZero(C->getSemantics());
3825-
}
3826-
3827-
// -0.0 compares equal to 0.0, so if this operand is at least -0.0,
3828-
// maxnum can't be ordered-less-than-zero.
3829-
return isKnownNeverNaN(V, DL, TLI) &&
3830-
cannotBeOrderedLessThanZeroImpl(V, DL, TLI, false, Depth + 1);
3831-
};
3832-
3833-
// TODO: This could be improved. We could also check that neither operand
3834-
// has its sign bit set (and at least 1 is not-NAN?).
3835-
return isPositiveNum(V0) || isPositiveNum(V1);
3836-
}
3837-
3838-
case Intrinsic::maximum:
3839-
return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), DL, TLI,
3840-
SignBitOnly, Depth + 1) ||
3841-
cannotBeOrderedLessThanZeroImpl(I->getOperand(1), DL, TLI,
3842-
SignBitOnly, Depth + 1);
3843-
case Intrinsic::minnum:
3844-
case Intrinsic::minimum:
3845-
return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), DL, TLI,
3846-
SignBitOnly, Depth + 1) &&
3847-
cannotBeOrderedLessThanZeroImpl(I->getOperand(1), DL, TLI,
3848-
SignBitOnly, Depth + 1);
3849-
case Intrinsic::exp:
3850-
case Intrinsic::exp2:
3851-
case Intrinsic::fabs:
3852-
return true;
3853-
case Intrinsic::copysign:
3854-
// Only the sign operand matters.
3855-
return cannotBeOrderedLessThanZeroImpl(I->getOperand(1), DL, TLI, true,
3856-
Depth + 1);
3857-
case Intrinsic::sqrt:
3858-
// sqrt(x) is always >= -0 or NaN. Moreover, sqrt(x) == -0 iff x == -0.
3859-
if (!SignBitOnly)
3860-
return true;
3861-
return CI->hasNoNaNs() &&
3862-
(CI->hasNoSignedZeros() ||
3863-
cannotBeNegativeZero(CI->getOperand(0), DL, TLI));
3864-
3865-
case Intrinsic::powi:
3866-
if (ConstantInt *Exponent = dyn_cast<ConstantInt>(I->getOperand(1))) {
3867-
// powi(x,n) is non-negative if n is even.
3868-
if (Exponent->getBitWidth() <= 64 && Exponent->getSExtValue() % 2u == 0)
3869-
return true;
3870-
}
3871-
// TODO: This is not correct. Given that exp is an integer, here are the
3872-
// ways that pow can return a negative value:
3873-
//
3874-
// pow(x, exp) --> negative if exp is odd and x is negative.
3875-
// pow(-0, exp) --> -inf if exp is negative odd.
3876-
// pow(-0, exp) --> -0 if exp is positive odd.
3877-
// pow(-inf, exp) --> -0 if exp is negative odd.
3878-
// pow(-inf, exp) --> -inf if exp is positive odd.
3879-
//
3880-
// Therefore, if !SignBitOnly, we can return true if x >= +0 or x is NaN,
3881-
// but we must return false if x == -0. Unfortunately we do not currently
3882-
// have a way of expressing this constraint. See details in
3883-
// https://llvm.org/bugs/show_bug.cgi?id=31702.
3884-
return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), DL, TLI,
3885-
SignBitOnly, Depth + 1);
3886-
3887-
case Intrinsic::fma:
3888-
case Intrinsic::fmuladd:
3889-
// x*x+y is non-negative if y is non-negative.
3890-
return I->getOperand(0) == I->getOperand(1) &&
3891-
(!SignBitOnly || cast<FPMathOperator>(I)->hasNoNaNs()) &&
3892-
cannotBeOrderedLessThanZeroImpl(I->getOperand(2), DL, TLI,
3893-
SignBitOnly, Depth + 1);
3894-
}
3895-
break;
3896-
}
3897-
return false;
3898-
}
3899-
3900-
bool llvm::SignBitMustBeZero(const Value *V, const DataLayout &DL,
3901-
const TargetLibraryInfo *TLI) {
3902-
// FIXME: Use computeKnownFPClass and pass all arguments
3903-
return cannotBeOrderedLessThanZeroImpl(V, DL, TLI, true, 0);
3904-
}
3905-
39063707
/// Return true if it's possible to assume IEEE treatment of input denormals in
39073708
/// \p F for \p Val.
39083709
static bool inputDenormalIsIEEE(const Function &F, const Type *Ty) {
@@ -4307,7 +4108,6 @@ static void computeKnownFPClassForFPTrunc(const Operator *Op,
43074108
// Infinity needs a range check.
43084109
}
43094110

4310-
// TODO: Merge implementation of cannotBeOrderedLessThanZero into here.
43114111
void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
43124112
FPClassTest InterestedClasses, KnownFPClass &Known,
43134113
unsigned Depth, const SimplifyQuery &Q) {
@@ -4332,6 +4132,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
43324132
const Constant *CV = dyn_cast<Constant>(V);
43334133
if (VFVTy && CV) {
43344134
Known.KnownFPClasses = fcNone;
4135+
bool SignBitAllZero = true;
4136+
bool SignBitAllOne = true;
43354137

43364138
// For vectors, verify that each element is not NaN.
43374139
unsigned NumElts = VFVTy->getNumElements();
@@ -4349,10 +4151,15 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
43494151
return;
43504152
}
43514153

4352-
KnownFPClass KnownElt{CElt->getValueAPF().classify(), CElt->isNegative()};
4353-
Known |= KnownElt;
4154+
const APFloat &C = CElt->getValueAPF();
4155+
Known.KnownFPClasses |= C.classify();
4156+
if (C.isNegative())
4157+
SignBitAllZero = false;
4158+
else
4159+
SignBitAllOne = false;
43544160
}
4355-
4161+
if (SignBitAllOne != SignBitAllZero)
4162+
Known.SignBit = SignBitAllOne;
43564163
return;
43574164
}
43584165

@@ -4488,7 +4295,6 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
44884295
computeKnownFPClass(II->getArgOperand(2), DemandedElts, InterestedClasses,
44894296
KnownAddend, Depth + 1, Q);
44904297

4491-
// TODO: Known sign bit with no nans
44924298
if (KnownAddend.cannotBeOrderedLessThanZero())
44934299
Known.knownNot(fcNegative);
44944300
break;
@@ -4522,7 +4328,7 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
45224328
(F && KnownSrc.isKnownNeverLogicalNegZero(*F, II->getType()))) {
45234329
Known.knownNot(fcNegZero);
45244330
if (KnownSrc.isKnownNeverNaN())
4525-
Known.SignBit = false;
4331+
Known.signBitMustBeZero();
45264332
}
45274333

45284334
break;
@@ -4592,7 +4398,6 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
45924398
// subtargets on AMDGPU the min/max instructions would not flush the
45934399
// output and return the original value.
45944400
//
4595-
// TODO: This could be refined based on the sign
45964401
if ((Known.KnownFPClasses & fcZero) != fcNone &&
45974402
!Known.isKnownNeverSubnormal()) {
45984403
const Function *Parent = II->getFunction();
@@ -4605,6 +4410,26 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
46054410
Known.KnownFPClasses |= fcZero;
46064411
}
46074412

4413+
if (Known.isKnownNeverNaN()) {
4414+
if (KnownLHS.SignBit && KnownRHS.SignBit &&
4415+
*KnownLHS.SignBit == *KnownRHS.SignBit) {
4416+
if (*KnownLHS.SignBit)
4417+
Known.signBitMustBeOne();
4418+
else
4419+
Known.signBitMustBeZero();
4420+
} else if ((IID == Intrinsic::maximum || IID == Intrinsic::minimum) ||
4421+
((KnownLHS.isKnownNeverNegZero() ||
4422+
KnownRHS.isKnownNeverPosZero()) &&
4423+
(KnownLHS.isKnownNeverPosZero() ||
4424+
KnownRHS.isKnownNeverNegZero()))) {
4425+
if ((IID == Intrinsic::maximum || IID == Intrinsic::maxnum) &&
4426+
(KnownLHS.SignBit == false || KnownRHS.SignBit == false))
4427+
Known.signBitMustBeZero();
4428+
else if ((IID == Intrinsic::minimum || IID == Intrinsic::minnum) &&
4429+
(KnownLHS.SignBit == true || KnownRHS.SignBit == true))
4430+
Known.signBitMustBeOne();
4431+
}
4432+
}
46084433
break;
46094434
}
46104435
case Intrinsic::canonicalize: {
@@ -4704,7 +4529,7 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
47044529
KnownSrc, Depth + 1, Q);
47054530
if (KnownSrc.isKnownNeverNaN()) {
47064531
Known.knownNot(fcNan);
4707-
Known.SignBit = false;
4532+
Known.signBitMustBeZero();
47084533
}
47094534

47104535
break;
@@ -4954,6 +4779,13 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
49544779
if (!KnownLHS.isKnownNeverNaN())
49554780
break;
49564781

4782+
if (KnownLHS.SignBit && KnownRHS.SignBit) {
4783+
if (*KnownLHS.SignBit == *KnownRHS.SignBit)
4784+
Known.signBitMustBeZero();
4785+
else
4786+
Known.signBitMustBeOne();
4787+
}
4788+
49574789
// If 0 * +/-inf produces NaN.
49584790
if (KnownLHS.isKnownNeverInfinity() && KnownRHS.isKnownNeverInfinity()) {
49594791
Known.knownNot(fcNan);

0 commit comments

Comments
 (0)