@@ -564,4 +564,73 @@ TEST_F(ConstantFPRangeTest, makeAllowedFCmpRegion) {
564564#endif
565565}
566566
567+ TEST_F (ConstantFPRangeTest, makeSatisfyingFCmpRegion) {
568+ for (auto Pred : FCmpInst::predicates ()) {
569+ EnumerateConstantFPRanges (
570+ [Pred](const ConstantFPRange &CR) {
571+ ConstantFPRange Res =
572+ ConstantFPRange::makeSatisfyingFCmpRegion (Pred, CR);
573+ // Super set of the optimal set excluding NaNs
574+ ConstantFPRange SuperSet (CR.getSemantics ());
575+ bool ContainsSNaN = false ;
576+ bool ContainsQNaN = false ;
577+ unsigned NonNaNValsInOptimalSet = 0 ;
578+ EnumerateValuesInConstantFPRange (
579+ ConstantFPRange::getFull (CR.getSemantics ()),
580+ [&](const APFloat &V) {
581+ if (AnyOfValueInConstantFPRange (CR, [&](const APFloat &U) {
582+ return !FCmpInst::compare (V, U, Pred);
583+ })) {
584+ EXPECT_FALSE (Res.contains (V))
585+ << " Wrong result for makeSatisfyingFCmpRegion(" << Pred
586+ << " , " << CR << " ). The result " << Res
587+ << " should not contain " << V;
588+ } else {
589+ if (V.isNaN ()) {
590+ if (V.isSignaling ())
591+ ContainsSNaN = true ;
592+ else
593+ ContainsQNaN = true ;
594+ } else {
595+ SuperSet = SuperSet.unionWith (ConstantFPRange (V));
596+ ++NonNaNValsInOptimalSet;
597+ }
598+ }
599+ });
600+
601+ // Check optimality
602+
603+ // The usefullness of making the result optimal for one/une is
604+ // questionable.
605+ if (Pred == FCmpInst::FCMP_ONE || Pred == FCmpInst::FCMP_UNE)
606+ return ;
607+
608+ EXPECT_FALSE (ContainsSNaN && !Res.containsSNaN ())
609+ << " Suboptimal result for makeSatisfyingFCmpRegion(" << Pred
610+ << " , " << CR << " ), should contain SNaN, but got " << Res;
611+ EXPECT_FALSE (ContainsQNaN && !Res.containsQNaN ())
612+ << " Suboptimal result for makeSatisfyingFCmpRegion(" << Pred
613+ << " , " << CR << " ), should contain QNaN, but got " << Res;
614+
615+ // We only care about the cases where the result is representable by
616+ // ConstantFPRange.
617+ unsigned NonNaNValsInSuperSet = 0 ;
618+ EnumerateValuesInConstantFPRange (SuperSet, [&](const APFloat &V) {
619+ if (!V.isNaN ())
620+ ++NonNaNValsInSuperSet;
621+ });
622+
623+ if (NonNaNValsInSuperSet == NonNaNValsInOptimalSet) {
624+ ConstantFPRange Optimal =
625+ ConstantFPRange (SuperSet.getLower (), SuperSet.getUpper (),
626+ ContainsQNaN, ContainsSNaN);
627+ EXPECT_EQ (Res, Optimal)
628+ << " Suboptimal result for makeSatisfyingFCmpRegion(" << Pred
629+ << " , " << CR << " )" ;
630+ }
631+ },
632+ /* Exhaustive=*/ false );
633+ }
634+ }
635+
567636} // anonymous namespace
0 commit comments