@@ -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 KnownFPClass computeKnownFPClassFromContext (const Value *V,
4217
+ const SimplifyQuery &Q) {
4218
+ KnownFPClass KnownFromContext;
4219
+
4220
+ if (!Q.CxtI )
4221
+ return KnownFromContext;
4222
+
4223
+ if (Q.DC && Q.DT ) {
4224
+ auto computeKnownFPClassFromCmp = [&](CmpInst::Predicate Pred, Value *LHS,
4225
+ Value *RHS) {
4226
+ if (match (LHS, m_BitCast (m_Specific (V)))) {
4227
+ Type *SrcType = V->getType ();
4228
+ Type *DstType = LHS->getType ();
4229
+
4230
+ // Make sure the bitcast doesn't change between scalar and vector and
4231
+ // doesn't change the number of vector elements.
4232
+ if (SrcType->isVectorTy () == DstType->isVectorTy () &&
4233
+ SrcType->getScalarSizeInBits () == DstType->getScalarSizeInBits ()) {
4234
+ // TODO: move IsSignBitCheck to ValueTracking
4235
+ if ((Pred == ICmpInst::ICMP_SLT && match (RHS, m_Zero ())) ||
4236
+ (Pred == ICmpInst::ICMP_SLE && match (RHS, m_AllOnes ())))
4237
+ KnownFromContext.signBitMustBeOne ();
4238
+ else if (Pred == ICmpInst::ICMP_SGT && match (RHS, m_AllOnes ()) ||
4239
+ (Pred == ICmpInst::ICMP_SGE && match (RHS, m_Zero ())))
4240
+ KnownFromContext.signBitMustBeZero ();
4241
+ }
4242
+ }
4243
+ };
4244
+
4245
+ // Handle dominating conditions.
4246
+ for (BranchInst *BI : Q.DC ->conditionsFor (V)) {
4247
+ // TODO: handle fcmps
4248
+ auto *Cmp = dyn_cast<ICmpInst>(BI->getCondition ());
4249
+ if (!Cmp)
4250
+ continue ;
4251
+
4252
+ BasicBlockEdge Edge0 (BI->getParent (), BI->getSuccessor (0 ));
4253
+ if (Q.DT ->dominates (Edge0, Q.CxtI ->getParent ()))
4254
+ computeKnownFPClassFromCmp (Cmp->getPredicate (), Cmp->getOperand (0 ),
4255
+ Cmp->getOperand (1 ));
4256
+
4257
+ BasicBlockEdge Edge1 (BI->getParent (), BI->getSuccessor (1 ));
4258
+ if (Q.DT ->dominates (Edge1, Q.CxtI ->getParent ()))
4259
+ computeKnownFPClassFromCmp (Cmp->getInversePredicate (),
4260
+ Cmp->getOperand (0 ), Cmp->getOperand (1 ));
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.
@@ -4242,16 +4289,16 @@ static FPClassTest computeKnownFPClassFromAssumes(const Value *V,
4242
4289
auto [CmpVal, MaskIfTrue, MaskIfFalse] =
4243
4290
fcmpImpliesClass (Pred, *F, LHS, *CRHS, LHS != V);
4244
4291
if (CmpVal == V)
4245
- KnownFromAssume &= MaskIfTrue;
4292
+ KnownFromContext. knownNot (~ MaskIfTrue) ;
4246
4293
}
4247
4294
} else if (match (I->getArgOperand (0 ),
4248
4295
m_Intrinsic<Intrinsic::is_fpclass>(
4249
4296
m_Value (LHS), m_ConstantInt (ClassVal)))) {
4250
- KnownFromAssume &= static_cast <FPClassTest>(ClassVal);
4297
+ KnownFromContext. knownNot (~ static_cast <FPClassTest>(ClassVal) );
4251
4298
}
4252
4299
}
4253
4300
4254
- return KnownFromAssume ;
4301
+ return KnownFromContext ;
4255
4302
}
4256
4303
4257
4304
void computeKnownFPClass (const Value *V, const APInt &DemandedElts,
@@ -4359,17 +4406,21 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
4359
4406
KnownNotFromFlags |= fcInf;
4360
4407
}
4361
4408
4362
- if (Q.AC ) {
4363
- FPClassTest AssumedClasses = computeKnownFPClassFromAssumes (V, Q);
4364
- KnownNotFromFlags |= ~AssumedClasses;
4365
- }
4409
+ KnownFPClass AssumedClasses = computeKnownFPClassFromContext (V, Q);
4410
+ KnownNotFromFlags |= ~AssumedClasses.KnownFPClasses ;
4366
4411
4367
4412
// We no longer need to find out about these bits from inputs if we can
4368
4413
// assume this from flags/attributes.
4369
4414
InterestedClasses &= ~KnownNotFromFlags;
4370
4415
4371
4416
auto ClearClassesFromFlags = make_scope_exit ([=, &Known] {
4372
4417
Known.knownNot (KnownNotFromFlags);
4418
+ if (!Known.SignBit && AssumedClasses.SignBit ) {
4419
+ if (*AssumedClasses.SignBit )
4420
+ Known.signBitMustBeOne ();
4421
+ else
4422
+ Known.signBitMustBeZero ();
4423
+ }
4373
4424
});
4374
4425
4375
4426
if (!Op)
@@ -5271,7 +5322,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
5271
5322
5272
5323
bool First = true ;
5273
5324
5274
- for (Value *IncValue : P->incoming_values ()) {
5325
+ for (const Use &U : P->operands ()) {
5326
+ Value *IncValue = U.get ();
5275
5327
// Skip direct self references.
5276
5328
if (IncValue == P)
5277
5329
continue ;
@@ -5280,8 +5332,10 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
5280
5332
// Recurse, but cap the recursion to two levels, because we don't want
5281
5333
// to waste time spinning around in loops. We need at least depth 2 to
5282
5334
// detect known sign bits.
5283
- computeKnownFPClass (IncValue, DemandedElts, InterestedClasses, KnownSrc,
5284
- PhiRecursionLimit, Q);
5335
+ computeKnownFPClass (
5336
+ IncValue, DemandedElts, InterestedClasses, KnownSrc,
5337
+ PhiRecursionLimit,
5338
+ Q.getWithInstruction (P->getIncomingBlock (U)->getTerminator ()));
5285
5339
5286
5340
if (First) {
5287
5341
Known = KnownSrc;
0 commit comments