Index: include/llvm/ADT/APFloat.h =================================================================== --- include/llvm/ADT/APFloat.h +++ include/llvm/ADT/APFloat.h @@ -336,6 +336,9 @@ return Result; } + const APFloat &minnum(const APFloat &) const; + const APFloat &maxnum(const APFloat &) const; + /// @} /// \name Sign operations. Index: lib/Support/APFloat.cpp =================================================================== --- lib/Support/APFloat.cpp +++ lib/Support/APFloat.cpp @@ -3891,6 +3891,22 @@ return result; } +const APFloat &APFloat::minnum(const APFloat &Other) const { + if (isNaN()) + return Other; + if (Other.isNaN()) + return *this; + return (Other.compare(*this) == cmpLessThan) ? Other : *this; +} + +const APFloat &APFloat::maxnum(const APFloat &Other) const { + if (isNaN()) + return Other; + if (Other.isNaN()) + return *this; + return (compare(Other) == cmpLessThan) ? Other : *this; +} + void APFloat::makeInf(bool Negative) { category = fcInfinity; Index: unittests/ADT/APFloatTest.cpp =================================================================== --- unittests/ADT/APFloatTest.cpp +++ unittests/ADT/APFloatTest.cpp @@ -476,6 +476,28 @@ } } +TEST(APFloatTest, MinNum) { + APFloat f1(1.0); + APFloat f2(2.0); + APFloat nan = APFloat::getNaN(APFloat::IEEEdouble); + + EXPECT_EQ(1.0, f1.minnum(f2).convertToDouble()); + EXPECT_EQ(1.0, f2.minnum(f1).convertToDouble()); + EXPECT_EQ(1.0, f1.minnum(nan).convertToDouble()); + EXPECT_EQ(1.0, nan.minnum(f1).convertToDouble()); +} + +TEST(APFloatTest, MaxNum) { + APFloat f1(1.0); + APFloat f2(2.0); + APFloat nan = APFloat::getNaN(APFloat::IEEEdouble); + + EXPECT_EQ(2.0, f1.maxnum(f2).convertToDouble()); + EXPECT_EQ(2.0, f2.maxnum(f1).convertToDouble()); + EXPECT_EQ(1.0, f1.maxnum(nan).convertToDouble()); + EXPECT_EQ(1.0, nan.minnum(f1).convertToDouble()); +} + TEST(APFloatTest, Denormal) { APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven;