@@ -470,4 +470,73 @@ TEST_F(ConstantFPRangeTest, makeAllowedFCmpRegion) {
470
470
}
471
471
}
472
472
473
+ TEST_F (ConstantFPRangeTest, makeSatisfyingFCmpRegion) {
474
+ for (auto Pred : FCmpInst::predicates ()) {
475
+ EnumerateConstantFPRanges (
476
+ [Pred](const ConstantFPRange &CR) {
477
+ ConstantFPRange Res =
478
+ ConstantFPRange::makeSatisfyingFCmpRegion (Pred, CR);
479
+ // Super set of the optimal set excluding NaNs
480
+ ConstantFPRange SuperSet (CR.getSemantics ());
481
+ bool ContainsSNaN = false ;
482
+ bool ContainsQNaN = false ;
483
+ unsigned NonNaNValsInOptimalSet = 0 ;
484
+ EnumerateValuesInConstantFPRange (
485
+ ConstantFPRange::getFull (CR.getSemantics ()),
486
+ [&](const APFloat &V) {
487
+ if (AnyOfValueInConstantFPRange (CR, [&](const APFloat &U) {
488
+ return !FCmpInst::compare (V, U, Pred);
489
+ })) {
490
+ EXPECT_FALSE (Res.contains (V))
491
+ << " Wrong result for makeSatisfyingFCmpRegion(" << Pred
492
+ << " , " << CR << " ). The result " << Res
493
+ << " should not contain " << V;
494
+ } else {
495
+ if (V.isNaN ()) {
496
+ if (V.isSignaling ())
497
+ ContainsSNaN = true ;
498
+ else
499
+ ContainsQNaN = true ;
500
+ } else {
501
+ SuperSet = SuperSet.unionWith (ConstantFPRange (V));
502
+ ++NonNaNValsInOptimalSet;
503
+ }
504
+ }
505
+ });
506
+
507
+ // Check optimality
508
+
509
+ // The usefullness of making the result optimal for one/une is
510
+ // questionable.
511
+ if (Pred == FCmpInst::FCMP_ONE || Pred == FCmpInst::FCMP_UNE)
512
+ return ;
513
+
514
+ EXPECT_FALSE (ContainsSNaN && !Res.containsSNaN ())
515
+ << " Suboptimal result for makeSatisfyingFCmpRegion(" << Pred
516
+ << " , " << CR << " ), should contain SNaN, but got " << Res;
517
+ EXPECT_FALSE (ContainsQNaN && !Res.containsQNaN ())
518
+ << " Suboptimal result for makeSatisfyingFCmpRegion(" << Pred
519
+ << " , " << CR << " ), should contain QNaN, but got " << Res;
520
+
521
+ // We only care about the cases where the result is representable by
522
+ // ConstantFPRange.
523
+ unsigned NonNaNValsInSuperSet = 0 ;
524
+ EnumerateValuesInConstantFPRange (SuperSet, [&](const APFloat &V) {
525
+ if (!V.isNaN ())
526
+ ++NonNaNValsInSuperSet;
527
+ });
528
+
529
+ if (NonNaNValsInSuperSet == NonNaNValsInOptimalSet) {
530
+ ConstantFPRange Optimal =
531
+ ConstantFPRange (SuperSet.getLower (), SuperSet.getUpper (),
532
+ ContainsQNaN, ContainsSNaN);
533
+ EXPECT_EQ (Res, Optimal)
534
+ << " Suboptimal result for makeSatisfyingFCmpRegion(" << Pred
535
+ << " , " << CR << " )" ;
536
+ }
537
+ },
538
+ /* Exhaustive=*/ false );
539
+ }
540
+ }
541
+
473
542
} // anonymous namespace
0 commit comments