@@ -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
42694299void 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