@@ -4213,9 +4213,56 @@ llvm::fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS,
4213
4213
return fcmpImpliesClass (Pred, F, LHS, *ConstRHS, LookThroughSrc);
4214
4214
}
4215
4215
4216
- static FPClassTest computeKnownFPClassFromAssumes (const Value *V,
4217
- const SimplifyQuery &Q) {
4218
- FPClassTest KnownFromAssume = fcAllFlags;
4216
+ static void computeKnownFPClassFromCond (const Value *V, Value *Cond,
4217
+ bool CondIsTrue,
4218
+ const Instruction *CxtI,
4219
+ KnownFPClass &KnownFromContext) {
4220
+ CmpInst::Predicate Pred;
4221
+ Value *LHS;
4222
+ Value *RHS;
4223
+ uint64_t ClassVal = 0 ;
4224
+ // TODO: handle sign-bit check idiom
4225
+ if (match (Cond, m_FCmp (Pred, m_Value (LHS), m_Value (RHS)))) {
4226
+ const APFloat *CRHS;
4227
+ if (match (RHS, m_APFloat (CRHS))) {
4228
+ auto [CmpVal, MaskIfTrue, MaskIfFalse] = fcmpImpliesClass (
4229
+ Pred, *CxtI->getParent ()->getParent (), LHS, *CRHS, LHS != V);
4230
+ if (CmpVal == V)
4231
+ KnownFromContext.knownNot (~(CondIsTrue ? MaskIfTrue : MaskIfFalse));
4232
+ }
4233
+ } else if (match (Cond, m_Intrinsic<Intrinsic::is_fpclass>(
4234
+ m_Value (LHS), m_ConstantInt (ClassVal)))) {
4235
+ FPClassTest Mask = static_cast <FPClassTest>(ClassVal);
4236
+ KnownFromContext.knownNot (CondIsTrue ? ~Mask : Mask);
4237
+ }
4238
+ }
4239
+
4240
+ static KnownFPClass computeKnownFPClassFromContext (const Value *V,
4241
+ const SimplifyQuery &Q) {
4242
+ KnownFPClass KnownFromContext;
4243
+
4244
+ if (!Q.CxtI )
4245
+ return KnownFromContext;
4246
+
4247
+ if (Q.DC && Q.DT ) {
4248
+ // Handle dominating conditions.
4249
+ for (BranchInst *BI : Q.DC ->conditionsFor (V)) {
4250
+ Value *Cond = BI->getCondition ();
4251
+
4252
+ BasicBlockEdge Edge0 (BI->getParent (), BI->getSuccessor (0 ));
4253
+ if (Q.DT ->dominates (Edge0, Q.CxtI ->getParent ()))
4254
+ computeKnownFPClassFromCond (V, Cond, /* CondIsTrue=*/ true , Q.CxtI ,
4255
+ KnownFromContext);
4256
+
4257
+ BasicBlockEdge Edge1 (BI->getParent (), BI->getSuccessor (1 ));
4258
+ if (Q.DT ->dominates (Edge1, Q.CxtI ->getParent ()))
4259
+ computeKnownFPClassFromCond (V, Cond, /* CondIsTrue=*/ false , Q.CxtI ,
4260
+ KnownFromContext);
4261
+ }
4262
+ }
4263
+
4264
+ if (!Q.AC )
4265
+ return KnownFromContext;
4219
4266
4220
4267
// Try to restrict the floating-point classes based on information from
4221
4268
// assumptions.
@@ -4233,25 +4280,11 @@ static FPClassTest computeKnownFPClassFromAssumes(const Value *V,
4233
4280
if (!isValidAssumeForContext (I, Q.CxtI , Q.DT ))
4234
4281
continue ;
4235
4282
4236
- CmpInst::Predicate Pred;
4237
- Value *LHS, *RHS;
4238
- uint64_t ClassVal = 0 ;
4239
- if (match (I->getArgOperand (0 ), m_FCmp (Pred, m_Value (LHS), m_Value (RHS)))) {
4240
- const APFloat *CRHS;
4241
- if (match (RHS, m_APFloat (CRHS))) {
4242
- auto [CmpVal, MaskIfTrue, MaskIfFalse] =
4243
- fcmpImpliesClass (Pred, *F, LHS, *CRHS, LHS != V);
4244
- if (CmpVal == V)
4245
- KnownFromAssume &= MaskIfTrue;
4246
- }
4247
- } else if (match (I->getArgOperand (0 ),
4248
- m_Intrinsic<Intrinsic::is_fpclass>(
4249
- m_Value (LHS), m_ConstantInt (ClassVal)))) {
4250
- KnownFromAssume &= static_cast <FPClassTest>(ClassVal);
4251
- }
4283
+ computeKnownFPClassFromCond (V, I->getArgOperand (0 ), /* CondIsTrue=*/ true ,
4284
+ Q.CxtI , KnownFromContext);
4252
4285
}
4253
4286
4254
- return KnownFromAssume ;
4287
+ return KnownFromContext ;
4255
4288
}
4256
4289
4257
4290
void computeKnownFPClass (const Value *V, const APInt &DemandedElts,
@@ -4359,17 +4392,21 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
4359
4392
KnownNotFromFlags |= fcInf;
4360
4393
}
4361
4394
4362
- if (Q.AC ) {
4363
- FPClassTest AssumedClasses = computeKnownFPClassFromAssumes (V, Q);
4364
- KnownNotFromFlags |= ~AssumedClasses;
4365
- }
4395
+ KnownFPClass AssumedClasses = computeKnownFPClassFromContext (V, Q);
4396
+ KnownNotFromFlags |= ~AssumedClasses.KnownFPClasses ;
4366
4397
4367
4398
// We no longer need to find out about these bits from inputs if we can
4368
4399
// assume this from flags/attributes.
4369
4400
InterestedClasses &= ~KnownNotFromFlags;
4370
4401
4371
4402
auto ClearClassesFromFlags = make_scope_exit ([=, &Known] {
4372
4403
Known.knownNot (KnownNotFromFlags);
4404
+ if (!Known.SignBit && AssumedClasses.SignBit ) {
4405
+ if (*AssumedClasses.SignBit )
4406
+ Known.signBitMustBeOne ();
4407
+ else
4408
+ Known.signBitMustBeZero ();
4409
+ }
4373
4410
});
4374
4411
4375
4412
if (!Op)
@@ -5271,7 +5308,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
5271
5308
5272
5309
bool First = true ;
5273
5310
5274
- for (Value *IncValue : P->incoming_values ()) {
5311
+ for (const Use &U : P->operands ()) {
5312
+ Value *IncValue = U.get ();
5275
5313
// Skip direct self references.
5276
5314
if (IncValue == P)
5277
5315
continue ;
@@ -5280,8 +5318,10 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
5280
5318
// Recurse, but cap the recursion to two levels, because we don't want
5281
5319
// to waste time spinning around in loops. We need at least depth 2 to
5282
5320
// detect known sign bits.
5283
- computeKnownFPClass (IncValue, DemandedElts, InterestedClasses, KnownSrc,
5284
- PhiRecursionLimit, Q);
5321
+ computeKnownFPClass (
5322
+ IncValue, DemandedElts, InterestedClasses, KnownSrc,
5323
+ PhiRecursionLimit,
5324
+ Q.getWithInstruction (P->getIncomingBlock (U)->getTerminator ()));
5285
5325
5286
5326
if (First) {
5287
5327
Known = KnownSrc;
0 commit comments