diff options
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 278bdd0..5931032 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4741,14 +4741,30 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts, case Instruction::FAdd: case Instruction::FSub: { KnownFPClass KnownLHS, KnownRHS; - computeKnownFPClass(Op->getOperand(1), DemandedElts, fcNan | fcInf, + bool WantNegative = + Op->getOpcode() == Instruction::FAdd && + (InterestedClasses & KnownFPClass::OrderedLessThanZeroMask) != fcNone; + bool WantNaN = (InterestedClasses & fcNan) != fcNone; + bool WantNegZero = (InterestedClasses & fcNegZero) != fcNone; + + if (!WantNaN && !WantNegative && !WantNegZero) + break; + + FPClassTest InterestedSrcs = InterestedClasses; + if (WantNegative) + InterestedSrcs |= KnownFPClass::OrderedLessThanZeroMask; + if (InterestedClasses & fcNan) + InterestedSrcs |= fcInf; + computeKnownFPClass(Op->getOperand(1), DemandedElts, InterestedSrcs, KnownRHS, Depth + 1, Q); - if (KnownRHS.isKnownNeverNaN() || KnownRHS.isKnownNeverNegZero() || - (Opc == Instruction::FSub && KnownRHS.isKnownNeverPosZero())) { + if ((WantNaN && KnownRHS.isKnownNeverNaN()) || + (WantNegative && KnownRHS.cannotBeOrderedLessThanZero()) || + WantNegZero || Opc == Instruction::FSub) { + // RHS is canonically cheaper to compute. Skip inspecting the LHS if // there's no point. - computeKnownFPClass(Op->getOperand(0), DemandedElts, fcNan | fcInf, + computeKnownFPClass(Op->getOperand(0), DemandedElts, InterestedSrcs, KnownLHS, Depth + 1, Q); // Adding positive and negative infinity produces NaN. // TODO: Check sign of infinities. @@ -4758,10 +4774,14 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts, // FIXME: Context function should always be passed in separately const Function *F = cast<Instruction>(Op)->getFunction(); - if (!F) - break; if (Op->getOpcode() == Instruction::FAdd) { + if (KnownLHS.cannotBeOrderedLessThanZero() && + KnownRHS.cannotBeOrderedLessThanZero()) + Known.knownNot(KnownFPClass::OrderedLessThanZeroMask); + if (!F) + break; + // (fadd x, 0.0) is guaranteed to return +0.0, not -0.0. if ((KnownLHS.isKnownNeverLogicalNegZero(*F, Op->getType()) || KnownRHS.isKnownNeverLogicalNegZero(*F, Op->getType())) && @@ -4769,6 +4789,9 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts, outputDenormalIsIEEEOrPosZero(*F, Op->getType())) Known.knownNot(fcNegZero); } else { + if (!F) + break; + // Only fsub -0, +0 can return -0 if ((KnownLHS.isKnownNeverLogicalNegZero(*F, Op->getType()) || KnownRHS.isKnownNeverLogicalPosZero(*F, Op->getType())) && |