@@ -4213,9 +4213,82 @@ 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
+ if (match (Cond, m_Cmp (Pred, m_Value (LHS), m_Value (RHS)))) {
4225
+ if (CmpInst::isIntPredicate (Pred)) {
4226
+ if (!match (LHS, m_BitCast (m_Specific (V))))
4227
+ return ;
4228
+ Type *SrcType = V->getType ();
4229
+ Type *DstType = LHS->getType ();
4230
+
4231
+ // Make sure the bitcast doesn't change between scalar and vector and
4232
+ // doesn't change the number of vector elements.
4233
+ if (SrcType->isVectorTy () == DstType->isVectorTy () &&
4234
+ SrcType->getScalarSizeInBits () == DstType->getScalarSizeInBits ()) {
4235
+ // TODO: move IsSignBitCheck to ValueTracking
4236
+ bool TrueIfSigned;
4237
+ if ((Pred == ICmpInst::ICMP_SLT && match (RHS, m_Zero ())) ||
4238
+ (Pred == ICmpInst::ICMP_SLE && match (RHS, m_AllOnes ())))
4239
+ TrueIfSigned = true ;
4240
+ else if (Pred == ICmpInst::ICMP_SGT && match (RHS, m_AllOnes ()) ||
4241
+ (Pred == ICmpInst::ICMP_SGE && match (RHS, m_Zero ())))
4242
+ TrueIfSigned = false ;
4243
+ else
4244
+ return ;
4245
+ if (TrueIfSigned == CondIsTrue)
4246
+ KnownFromContext.signBitMustBeOne ();
4247
+ else
4248
+ KnownFromContext.signBitMustBeZero ();
4249
+ }
4250
+ } else {
4251
+ const APFloat *CRHS;
4252
+ if (match (RHS, m_APFloat (CRHS))) {
4253
+ auto [CmpVal, MaskIfTrue, MaskIfFalse] = fcmpImpliesClass (
4254
+ Pred, *CxtI->getParent ()->getParent (), LHS, *CRHS, LHS != V);
4255
+ if (CmpVal == V)
4256
+ KnownFromContext.knownNot (~(CondIsTrue ? MaskIfTrue : MaskIfFalse));
4257
+ }
4258
+ }
4259
+ } else if (match (Cond, m_Intrinsic<Intrinsic::is_fpclass>(
4260
+ m_Value (LHS), m_ConstantInt (ClassVal)))) {
4261
+ FPClassTest Mask = static_cast <FPClassTest>(ClassVal);
4262
+ KnownFromContext.knownNot (CondIsTrue ? ~Mask : Mask);
4263
+ }
4264
+ }
4265
+
4266
+ static KnownFPClass computeKnownFPClassFromContext (const Value *V,
4267
+ const SimplifyQuery &Q) {
4268
+ KnownFPClass KnownFromContext;
4269
+
4270
+ if (!Q.CxtI )
4271
+ return KnownFromContext;
4272
+
4273
+ if (Q.DC && Q.DT ) {
4274
+ // Handle dominating conditions.
4275
+ for (BranchInst *BI : Q.DC ->conditionsFor (V)) {
4276
+ Value *Cond = BI->getCondition ();
4277
+
4278
+ BasicBlockEdge Edge0 (BI->getParent (), BI->getSuccessor (0 ));
4279
+ if (Q.DT ->dominates (Edge0, Q.CxtI ->getParent ()))
4280
+ computeKnownFPClassFromCond (V, Cond, /* CondIsTrue=*/ true , Q.CxtI ,
4281
+ KnownFromContext);
4282
+
4283
+ BasicBlockEdge Edge1 (BI->getParent (), BI->getSuccessor (1 ));
4284
+ if (Q.DT ->dominates (Edge1, Q.CxtI ->getParent ()))
4285
+ computeKnownFPClassFromCond (V, Cond, /* CondIsTrue=*/ false , Q.CxtI ,
4286
+ KnownFromContext);
4287
+ }
4288
+ }
4289
+
4290
+ if (!Q.AC )
4291
+ return KnownFromContext;
4219
4292
4220
4293
// Try to restrict the floating-point classes based on information from
4221
4294
// assumptions.
@@ -4233,25 +4306,11 @@ static FPClassTest computeKnownFPClassFromAssumes(const Value *V,
4233
4306
if (!isValidAssumeForContext (I, Q.CxtI , Q.DT ))
4234
4307
continue ;
4235
4308
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
- }
4309
+ computeKnownFPClassFromCond (V, I->getArgOperand (0 ), /* CondIsTrue=*/ true ,
4310
+ Q.CxtI , KnownFromContext);
4252
4311
}
4253
4312
4254
- return KnownFromAssume ;
4313
+ return KnownFromContext ;
4255
4314
}
4256
4315
4257
4316
void computeKnownFPClass (const Value *V, const APInt &DemandedElts,
@@ -4359,17 +4418,21 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
4359
4418
KnownNotFromFlags |= fcInf;
4360
4419
}
4361
4420
4362
- if (Q.AC ) {
4363
- FPClassTest AssumedClasses = computeKnownFPClassFromAssumes (V, Q);
4364
- KnownNotFromFlags |= ~AssumedClasses;
4365
- }
4421
+ KnownFPClass AssumedClasses = computeKnownFPClassFromContext (V, Q);
4422
+ KnownNotFromFlags |= ~AssumedClasses.KnownFPClasses ;
4366
4423
4367
4424
// We no longer need to find out about these bits from inputs if we can
4368
4425
// assume this from flags/attributes.
4369
4426
InterestedClasses &= ~KnownNotFromFlags;
4370
4427
4371
4428
auto ClearClassesFromFlags = make_scope_exit ([=, &Known] {
4372
4429
Known.knownNot (KnownNotFromFlags);
4430
+ if (!Known.SignBit && AssumedClasses.SignBit ) {
4431
+ if (*AssumedClasses.SignBit )
4432
+ Known.signBitMustBeOne ();
4433
+ else
4434
+ Known.signBitMustBeZero ();
4435
+ }
4373
4436
});
4374
4437
4375
4438
if (!Op)
@@ -5271,7 +5334,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
5271
5334
5272
5335
bool First = true ;
5273
5336
5274
- for (Value *IncValue : P->incoming_values ()) {
5337
+ for (const Use &U : P->operands ()) {
5338
+ Value *IncValue = U.get ();
5275
5339
// Skip direct self references.
5276
5340
if (IncValue == P)
5277
5341
continue ;
@@ -5280,8 +5344,10 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
5280
5344
// Recurse, but cap the recursion to two levels, because we don't want
5281
5345
// to waste time spinning around in loops. We need at least depth 2 to
5282
5346
// detect known sign bits.
5283
- computeKnownFPClass (IncValue, DemandedElts, InterestedClasses, KnownSrc,
5284
- PhiRecursionLimit, Q);
5347
+ computeKnownFPClass (
5348
+ IncValue, DemandedElts, InterestedClasses, KnownSrc,
5349
+ PhiRecursionLimit,
5350
+ Q.getWithInstruction (P->getIncomingBlock (U)->getTerminator ()));
5285
5351
5286
5352
if (First) {
5287
5353
Known = KnownSrc;
0 commit comments