@@ -470,4 +470,73 @@ TEST_F(ConstantFPRangeTest, makeAllowedFCmpRegion) {
470470 }
471471}
472472
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+
473542} // anonymous namespace
0 commit comments