@@ -4225,9 +4225,53 @@ llvm::fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS,
4225
4225
return fcmpImpliesClass (Pred, F, LHS, *ConstRHS, LookThroughSrc);
4226
4226
}
4227
4227
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;
4231
4275
4232
4276
// Try to restrict the floating-point classes based on information from
4233
4277
// assumptions.
@@ -4245,25 +4289,11 @@ static FPClassTest computeKnownFPClassFromAssumes(const Value *V,
4245
4289
if (!isValidAssumeForContext (I, Q.CxtI , Q.DT ))
4246
4290
continue ;
4247
4291
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);
4264
4294
}
4265
4295
4266
- return KnownFromAssume ;
4296
+ return KnownFromContext ;
4267
4297
}
4268
4298
4269
4299
void computeKnownFPClass (const Value *V, const APInt &DemandedElts,
@@ -4371,17 +4401,21 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
4371
4401
KnownNotFromFlags |= fcInf;
4372
4402
}
4373
4403
4374
- if (Q.AC ) {
4375
- FPClassTest AssumedClasses = computeKnownFPClassFromAssumes (V, Q);
4376
- KnownNotFromFlags |= ~AssumedClasses;
4377
- }
4404
+ KnownFPClass AssumedClasses = computeKnownFPClassFromContext (V, Q);
4405
+ KnownNotFromFlags |= ~AssumedClasses.KnownFPClasses ;
4378
4406
4379
4407
// We no longer need to find out about these bits from inputs if we can
4380
4408
// assume this from flags/attributes.
4381
4409
InterestedClasses &= ~KnownNotFromFlags;
4382
4410
4383
4411
auto ClearClassesFromFlags = make_scope_exit ([=, &Known] {
4384
4412
Known.knownNot (KnownNotFromFlags);
4413
+ if (!Known.SignBit && AssumedClasses.SignBit ) {
4414
+ if (*AssumedClasses.SignBit )
4415
+ Known.signBitMustBeOne ();
4416
+ else
4417
+ Known.signBitMustBeZero ();
4418
+ }
4385
4419
});
4386
4420
4387
4421
if (!Op)
@@ -5283,7 +5317,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
5283
5317
5284
5318
bool First = true ;
5285
5319
5286
- for (Value *IncValue : P->incoming_values ()) {
5320
+ for (const Use &U : P->operands ()) {
5321
+ Value *IncValue = U.get ();
5287
5322
// Skip direct self references.
5288
5323
if (IncValue == P)
5289
5324
continue ;
@@ -5292,8 +5327,10 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
5292
5327
// Recurse, but cap the recursion to two levels, because we don't want
5293
5328
// to waste time spinning around in loops. We need at least depth 2 to
5294
5329
// 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 ()));
5297
5334
5298
5335
if (First) {
5299
5336
Known = KnownSrc;
0 commit comments