summaryrefslogtreecommitdiff
path: root/unittests/ADT
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2013-12-22 00:04:03 +0000
committerDimitry Andric <dim@FreeBSD.org>2013-12-22 00:04:03 +0000
commitf8af5cf600354830d4ccf59732403f0f073eccb9 (patch)
tree2ba0398b4c42ad4f55561327538044fd2c925a8b /unittests/ADT
parent59d6cff90eecf31cb3dd860c4e786674cfdd42eb (diff)
Notes
Diffstat (limited to 'unittests/ADT')
-rw-r--r--unittests/ADT/APFloatTest.cpp1824
-rw-r--r--unittests/ADT/APIntTest.cpp65
-rw-r--r--unittests/ADT/BitVectorTest.cpp60
-rw-r--r--unittests/ADT/CMakeLists.txt2
-rw-r--r--unittests/ADT/IntrusiveRefCntPtrTest.cpp8
-rw-r--r--unittests/ADT/PointerUnionTest.cpp64
-rw-r--r--unittests/ADT/StringRefTest.cpp52
-rw-r--r--unittests/ADT/polymorphic_ptr_test.cpp129
8 files changed, 2196 insertions, 8 deletions
diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp
index 278983565ced7..e57c8d4b931f0 100644
--- a/unittests/ADT/APFloatTest.cpp
+++ b/unittests/ADT/APFloatTest.cpp
@@ -33,6 +33,449 @@ static std::string convertToString(double d, unsigned Prec, unsigned Pad) {
namespace {
+TEST(APFloatTest, isSignaling) {
+ // We test qNaN, -qNaN, +sNaN, -sNaN with and without payloads. *NOTE* The
+ // positive/negative distinction is included only since the getQNaN/getSNaN
+ // API provides the option.
+ APInt payload = APInt::getOneBitSet(4, 2);
+ EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle, false).isSignaling());
+ EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle, true).isSignaling());
+ EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle, false, &payload).isSignaling());
+ EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle, true, &payload).isSignaling());
+ EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, false).isSignaling());
+ EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, true).isSignaling());
+ EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, false, &payload).isSignaling());
+ EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, true, &payload).isSignaling());
+}
+
+TEST(APFloatTest, next) {
+
+ APFloat test(APFloat::IEEEquad, APFloat::uninitialized);
+ APFloat expected(APFloat::IEEEquad, APFloat::uninitialized);
+
+ // 1. Test Special Cases Values.
+ //
+ // Test all special values for nextUp and nextDown perscribed by IEEE-754R
+ // 2008. These are:
+ // 1. +inf
+ // 2. -inf
+ // 3. getLargest()
+ // 4. -getLargest()
+ // 5. getSmallest()
+ // 6. -getSmallest()
+ // 7. qNaN
+ // 8. sNaN
+ // 9. +0
+ // 10. -0
+
+ // nextUp(+inf) = +inf.
+ test = APFloat::getInf(APFloat::IEEEquad, false);
+ expected = APFloat::getInf(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.isInfinity());
+ EXPECT_TRUE(!test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(+inf) = -nextUp(-inf) = -(-getLargest()) = getLargest()
+ test = APFloat::getInf(APFloat::IEEEquad, false);
+ expected = APFloat::getLargest(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(!test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(-inf) = -getLargest()
+ test = APFloat::getInf(APFloat::IEEEquad, true);
+ expected = APFloat::getLargest(APFloat::IEEEquad, true);
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-inf) = -nextUp(+inf) = -(+inf) = -inf.
+ test = APFloat::getInf(APFloat::IEEEquad, true);
+ expected = APFloat::getInf(APFloat::IEEEquad, true);
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.isInfinity() && test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(getLargest()) = +inf
+ test = APFloat::getLargest(APFloat::IEEEquad, false);
+ expected = APFloat::getInf(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.isInfinity() && !test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(getLargest()) = -nextUp(-getLargest())
+ // = -(-getLargest() + inc)
+ // = getLargest() - inc.
+ test = APFloat::getLargest(APFloat::IEEEquad, false);
+ expected = APFloat(APFloat::IEEEquad,
+ "0x1.fffffffffffffffffffffffffffep+16383");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(!test.isInfinity() && !test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(-getLargest()) = -getLargest() + inc.
+ test = APFloat::getLargest(APFloat::IEEEquad, true);
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x1.fffffffffffffffffffffffffffep+16383");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-getLargest()) = -nextUp(getLargest()) = -(inf) = -inf.
+ test = APFloat::getLargest(APFloat::IEEEquad, true);
+ expected = APFloat::getInf(APFloat::IEEEquad, true);
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.isInfinity() && test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(getSmallest()) = getSmallest() + inc.
+ test = APFloat(APFloat::IEEEquad, "0x0.0000000000000000000000000001p-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x0.0000000000000000000000000002p-16382");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(getSmallest()) = -nextUp(-getSmallest()) = -(-0) = +0.
+ test = APFloat(APFloat::IEEEquad, "0x0.0000000000000000000000000001p-16382");
+ expected = APFloat::getZero(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.isZero() && !test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(-getSmallest()) = -0.
+ test = APFloat(APFloat::IEEEquad, "-0x0.0000000000000000000000000001p-16382");
+ expected = APFloat::getZero(APFloat::IEEEquad, true);
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.isZero() && test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-getSmallest()) = -nextUp(getSmallest()) = -getSmallest() - inc.
+ test = APFloat(APFloat::IEEEquad, "-0x0.0000000000000000000000000001p-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x0.0000000000000000000000000002p-16382");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(qNaN) = qNaN
+ test = APFloat::getQNaN(APFloat::IEEEquad, false);
+ expected = APFloat::getQNaN(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(qNaN) = qNaN
+ test = APFloat::getQNaN(APFloat::IEEEquad, false);
+ expected = APFloat::getQNaN(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(sNaN) = qNaN
+ test = APFloat::getSNaN(APFloat::IEEEquad, false);
+ expected = APFloat::getQNaN(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(false), APFloat::opInvalidOp);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(sNaN) = qNaN
+ test = APFloat::getSNaN(APFloat::IEEEquad, false);
+ expected = APFloat::getQNaN(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(true), APFloat::opInvalidOp);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(+0) = +getSmallest()
+ test = APFloat::getZero(APFloat::IEEEquad, false);
+ expected = APFloat::getSmallest(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(+0) = -nextUp(-0) = -getSmallest()
+ test = APFloat::getZero(APFloat::IEEEquad, false);
+ expected = APFloat::getSmallest(APFloat::IEEEquad, true);
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(-0) = +getSmallest()
+ test = APFloat::getZero(APFloat::IEEEquad, true);
+ expected = APFloat::getSmallest(APFloat::IEEEquad, false);
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-0) = -nextUp(0) = -getSmallest()
+ test = APFloat::getZero(APFloat::IEEEquad, true);
+ expected = APFloat::getSmallest(APFloat::IEEEquad, true);
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // 2. Binade Boundary Tests.
+
+ // 2a. Test denormal <-> normal binade boundaries.
+ // * nextUp(+Largest Denormal) -> +Smallest Normal.
+ // * nextDown(-Largest Denormal) -> -Smallest Normal.
+ // * nextUp(-Smallest Normal) -> -Largest Denormal.
+ // * nextDown(+Smallest Normal) -> +Largest Denormal.
+
+ // nextUp(+Largest Denormal) -> +Smallest Normal.
+ test = APFloat(APFloat::IEEEquad, "0x0.ffffffffffffffffffffffffffffp-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x1.0000000000000000000000000000p-16382");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_FALSE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-Largest Denormal) -> -Smallest Normal.
+ test = APFloat(APFloat::IEEEquad,
+ "-0x0.ffffffffffffffffffffffffffffp-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x1.0000000000000000000000000000p-16382");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_FALSE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(-Smallest Normal) -> -LargestDenormal.
+ test = APFloat(APFloat::IEEEquad,
+ "-0x1.0000000000000000000000000000p-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x0.ffffffffffffffffffffffffffffp-16382");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(+Smallest Normal) -> +Largest Denormal.
+ test = APFloat(APFloat::IEEEquad,
+ "+0x1.0000000000000000000000000000p-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "+0x0.ffffffffffffffffffffffffffffp-16382");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // 2b. Test normal <-> normal binade boundaries.
+ // * nextUp(-Normal Binade Boundary) -> -Normal Binade Boundary + 1.
+ // * nextDown(+Normal Binade Boundary) -> +Normal Binade Boundary - 1.
+ // * nextUp(+Normal Binade Boundary - 1) -> +Normal Binade Boundary.
+ // * nextDown(-Normal Binade Boundary + 1) -> -Normal Binade Boundary.
+
+ // nextUp(-Normal Binade Boundary) -> -Normal Binade Boundary + 1.
+ test = APFloat(APFloat::IEEEquad, "-0x1p+1");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x1.ffffffffffffffffffffffffffffp+0");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(+Normal Binade Boundary) -> +Normal Binade Boundary - 1.
+ test = APFloat(APFloat::IEEEquad, "0x1p+1");
+ expected = APFloat(APFloat::IEEEquad, "0x1.ffffffffffffffffffffffffffffp+0");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(+Normal Binade Boundary - 1) -> +Normal Binade Boundary.
+ test = APFloat(APFloat::IEEEquad, "0x1.ffffffffffffffffffffffffffffp+0");
+ expected = APFloat(APFloat::IEEEquad, "0x1p+1");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-Normal Binade Boundary + 1) -> -Normal Binade Boundary.
+ test = APFloat(APFloat::IEEEquad, "-0x1.ffffffffffffffffffffffffffffp+0");
+ expected = APFloat(APFloat::IEEEquad, "-0x1p+1");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // 2c. Test using next at binade boundaries with a direction away from the
+ // binade boundary. Away from denormal <-> normal boundaries.
+ //
+ // This is to make sure that even though we are at a binade boundary, since
+ // we are rounding away, we do not trigger the binade boundary code. Thus we
+ // test:
+ // * nextUp(-Largest Denormal) -> -Largest Denormal + inc.
+ // * nextDown(+Largest Denormal) -> +Largest Denormal - inc.
+ // * nextUp(+Smallest Normal) -> +Smallest Normal + inc.
+ // * nextDown(-Smallest Normal) -> -Smallest Normal - inc.
+
+ // nextUp(-Largest Denormal) -> -Largest Denormal + inc.
+ test = APFloat(APFloat::IEEEquad, "-0x0.ffffffffffffffffffffffffffffp-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x0.fffffffffffffffffffffffffffep-16382");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(+Largest Denormal) -> +Largest Denormal - inc.
+ test = APFloat(APFloat::IEEEquad, "0x0.ffffffffffffffffffffffffffffp-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x0.fffffffffffffffffffffffffffep-16382");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(!test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(+Smallest Normal) -> +Smallest Normal + inc.
+ test = APFloat(APFloat::IEEEquad, "0x1.0000000000000000000000000000p-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x1.0000000000000000000000000001p-16382");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(!test.isDenormal());
+ EXPECT_TRUE(!test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-Smallest Normal) -> -Smallest Normal - inc.
+ test = APFloat(APFloat::IEEEquad, "-0x1.0000000000000000000000000000p-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x1.0000000000000000000000000001p-16382");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(!test.isDenormal());
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // 2d. Test values which cause our exponent to go to min exponent. This
+ // is to ensure that guards in the code to check for min exponent
+ // trigger properly.
+ // * nextUp(-0x1p-16381) -> -0x1.ffffffffffffffffffffffffffffp-16382
+ // * nextDown(-0x1.ffffffffffffffffffffffffffffp-16382) ->
+ // -0x1p-16381
+ // * nextUp(0x1.ffffffffffffffffffffffffffffp-16382) -> 0x1p-16382
+ // * nextDown(0x1p-16382) -> 0x1.ffffffffffffffffffffffffffffp-16382
+
+ // nextUp(-0x1p-16381) -> -0x1.ffffffffffffffffffffffffffffp-16382
+ test = APFloat(APFloat::IEEEquad, "-0x1p-16381");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x1.ffffffffffffffffffffffffffffp-16382");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-0x1.ffffffffffffffffffffffffffffp-16382) ->
+ // -0x1p-16381
+ test = APFloat(APFloat::IEEEquad, "-0x1.ffffffffffffffffffffffffffffp-16382");
+ expected = APFloat(APFloat::IEEEquad, "-0x1p-16381");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(0x1.ffffffffffffffffffffffffffffp-16382) -> 0x1p-16381
+ test = APFloat(APFloat::IEEEquad, "0x1.ffffffffffffffffffffffffffffp-16382");
+ expected = APFloat(APFloat::IEEEquad, "0x1p-16381");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(0x1p-16381) -> 0x1.ffffffffffffffffffffffffffffp-16382
+ test = APFloat(APFloat::IEEEquad, "0x1p-16381");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x1.ffffffffffffffffffffffffffffp-16382");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // 3. Now we test both denormal/normal computation which will not cause us
+ // to go across binade boundaries. Specifically we test:
+ // * nextUp(+Denormal) -> +Denormal.
+ // * nextDown(+Denormal) -> +Denormal.
+ // * nextUp(-Denormal) -> -Denormal.
+ // * nextDown(-Denormal) -> -Denormal.
+ // * nextUp(+Normal) -> +Normal.
+ // * nextDown(+Normal) -> +Normal.
+ // * nextUp(-Normal) -> -Normal.
+ // * nextDown(-Normal) -> -Normal.
+
+ // nextUp(+Denormal) -> +Denormal.
+ test = APFloat(APFloat::IEEEquad,
+ "0x0.ffffffffffffffffffffffff000cp-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x0.ffffffffffffffffffffffff000dp-16382");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(!test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(+Denormal) -> +Denormal.
+ test = APFloat(APFloat::IEEEquad,
+ "0x0.ffffffffffffffffffffffff000cp-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x0.ffffffffffffffffffffffff000bp-16382");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(!test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(-Denormal) -> -Denormal.
+ test = APFloat(APFloat::IEEEquad,
+ "-0x0.ffffffffffffffffffffffff000cp-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x0.ffffffffffffffffffffffff000bp-16382");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-Denormal) -> -Denormal
+ test = APFloat(APFloat::IEEEquad,
+ "-0x0.ffffffffffffffffffffffff000cp-16382");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x0.ffffffffffffffffffffffff000dp-16382");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(+Normal) -> +Normal.
+ test = APFloat(APFloat::IEEEquad,
+ "0x1.ffffffffffffffffffffffff000cp-16000");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x1.ffffffffffffffffffffffff000dp-16000");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(!test.isDenormal());
+ EXPECT_TRUE(!test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(+Normal) -> +Normal.
+ test = APFloat(APFloat::IEEEquad,
+ "0x1.ffffffffffffffffffffffff000cp-16000");
+ expected = APFloat(APFloat::IEEEquad,
+ "0x1.ffffffffffffffffffffffff000bp-16000");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(!test.isDenormal());
+ EXPECT_TRUE(!test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextUp(-Normal) -> -Normal.
+ test = APFloat(APFloat::IEEEquad,
+ "-0x1.ffffffffffffffffffffffff000cp-16000");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x1.ffffffffffffffffffffffff000bp-16000");
+ EXPECT_EQ(test.next(false), APFloat::opOK);
+ EXPECT_TRUE(!test.isDenormal());
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ // nextDown(-Normal) -> -Normal.
+ test = APFloat(APFloat::IEEEquad,
+ "-0x1.ffffffffffffffffffffffff000cp-16000");
+ expected = APFloat(APFloat::IEEEquad,
+ "-0x1.ffffffffffffffffffffffff000dp-16000");
+ EXPECT_EQ(test.next(true), APFloat::opOK);
+ EXPECT_TRUE(!test.isDenormal());
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+}
+
+TEST(APFloatTest, FMA) {
+ APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven;
+
+ {
+ APFloat f1(14.5f);
+ APFloat f2(-14.5f);
+ APFloat f3(225.0f);
+ f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
+ EXPECT_EQ(14.75f, f1.convertToFloat());
+ }
+
+ {
+ APFloat Val2(2.0f);
+ APFloat f1((float)1.17549435e-38F);
+ APFloat f2((float)1.17549435e-38F);
+ f1.divide(Val2, rdmd);
+ f2.divide(Val2, rdmd);
+ APFloat f3(12.0f);
+ f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
+ EXPECT_EQ(12.0f, f1.convertToFloat());
+ }
+}
+
TEST(APFloatTest, Denormal) {
APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven;
@@ -95,6 +538,31 @@ TEST(APFloatTest, Zero) {
EXPECT_TRUE(APFloat(-0.0).isNegative());
}
+TEST(APFloatTest, DecimalStringsWithoutNullTerminators) {
+ // Make sure that we can parse strings without null terminators.
+ // rdar://14323230.
+ APFloat Val(APFloat::IEEEdouble);
+ Val.convertFromString(StringRef("0.00", 3),
+ llvm::APFloat::rmNearestTiesToEven);
+ EXPECT_EQ(Val.convertToDouble(), 0.0);
+ Val.convertFromString(StringRef("0.01", 3),
+ llvm::APFloat::rmNearestTiesToEven);
+ EXPECT_EQ(Val.convertToDouble(), 0.0);
+ Val.convertFromString(StringRef("0.09", 3),
+ llvm::APFloat::rmNearestTiesToEven);
+ EXPECT_EQ(Val.convertToDouble(), 0.0);
+ Val.convertFromString(StringRef("0.095", 4),
+ llvm::APFloat::rmNearestTiesToEven);
+ EXPECT_EQ(Val.convertToDouble(), 0.09);
+ Val.convertFromString(StringRef("0.00e+3", 7),
+ llvm::APFloat::rmNearestTiesToEven);
+ EXPECT_EQ(Val.convertToDouble(), 0.00);
+ Val.convertFromString(StringRef("0e+3", 4),
+ llvm::APFloat::rmNearestTiesToEven);
+ EXPECT_EQ(Val.convertToDouble(), 0.00);
+
+}
+
TEST(APFloatTest, fromZeroDecimalString) {
EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0").convertToDouble());
EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0").convertToDouble());
@@ -298,6 +766,8 @@ TEST(APFloatTest, fromDecimalString) {
EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "-99e99999").isInfinity());
EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "1e-99999").isPosZero());
EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "-1e-99999").isNegZero());
+
+ EXPECT_EQ(2.71828, convertToDoubleFromString("2.71828"));
}
TEST(APFloatTest, fromHexadecimalString) {
@@ -381,7 +851,10 @@ TEST(APFloatTest, fromHexadecimalString) {
EXPECT_EQ(1.0625, APFloat(APFloat::IEEEdouble, "0x1.1p0").convertToDouble());
EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble, "0x1p0").convertToDouble());
- EXPECT_EQ(2.71828, convertToDoubleFromString("2.71828"));
+ EXPECT_EQ(convertToDoubleFromString("0x1p-150"),
+ convertToDoubleFromString("+0x800000000000000001.p-221"));
+ EXPECT_EQ(2251799813685248.5,
+ convertToDoubleFromString("0x80000000000004000000.010p-28"));
}
TEST(APFloatTest, toString) {
@@ -393,10 +866,11 @@ TEST(APFloatTest, toString) {
ASSERT_EQ("0.0101", convertToString(1.01E-2, 5, 2));
ASSERT_EQ("0.0101", convertToString(1.01E-2, 4, 2));
ASSERT_EQ("1.01E-2", convertToString(1.01E-2, 5, 1));
- ASSERT_EQ("0.7853981633974483", convertToString(0.78539816339744830961, 0, 3));
- ASSERT_EQ("4.940656458412465E-324", convertToString(4.9406564584124654e-324, 0, 3));
- ASSERT_EQ("873.1834", convertToString(873.1834, 0, 1));
- ASSERT_EQ("8.731834E+2", convertToString(873.1834, 0, 0));
+ ASSERT_EQ("0.78539816339744828", convertToString(0.78539816339744830961, 0, 3));
+ ASSERT_EQ("4.9406564584124654E-324", convertToString(4.9406564584124654e-324, 0, 3));
+ ASSERT_EQ("873.18340000000001", convertToString(873.1834, 0, 1));
+ ASSERT_EQ("8.7318340000000001E+2", convertToString(873.1834, 0, 0));
+ ASSERT_EQ("1.7976931348623157E+308", convertToString(1.7976931348623157E+308, 0, 0));
}
TEST(APFloatTest, toInteger) {
@@ -771,6 +1245,103 @@ TEST(APFloatTest, getLargest) {
EXPECT_EQ(1.7976931348623158e+308, APFloat::getLargest(APFloat::IEEEdouble).convertToDouble());
}
+TEST(APFloatTest, getSmallest) {
+ APFloat test = APFloat::getSmallest(APFloat::IEEEsingle, false);
+ APFloat expected = APFloat(APFloat::IEEEsingle, "0x0.000002p-126");
+ EXPECT_FALSE(test.isNegative());
+ EXPECT_TRUE(test.isFiniteNonZero());
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ test = APFloat::getSmallest(APFloat::IEEEsingle, true);
+ expected = APFloat(APFloat::IEEEsingle, "-0x0.000002p-126");
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.isFiniteNonZero());
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ test = APFloat::getSmallest(APFloat::IEEEquad, false);
+ expected = APFloat(APFloat::IEEEquad, "0x0.0000000000000000000000000001p-16382");
+ EXPECT_FALSE(test.isNegative());
+ EXPECT_TRUE(test.isFiniteNonZero());
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ test = APFloat::getSmallest(APFloat::IEEEquad, true);
+ expected = APFloat(APFloat::IEEEquad, "-0x0.0000000000000000000000000001p-16382");
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.isFiniteNonZero());
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+}
+
+TEST(APFloatTest, getSmallestNormalized) {
+ APFloat test = APFloat::getSmallestNormalized(APFloat::IEEEsingle, false);
+ APFloat expected = APFloat(APFloat::IEEEsingle, "0x1p-126");
+ EXPECT_FALSE(test.isNegative());
+ EXPECT_TRUE(test.isFiniteNonZero());
+ EXPECT_FALSE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ test = APFloat::getSmallestNormalized(APFloat::IEEEsingle, true);
+ expected = APFloat(APFloat::IEEEsingle, "-0x1p-126");
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.isFiniteNonZero());
+ EXPECT_FALSE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ test = APFloat::getSmallestNormalized(APFloat::IEEEquad, false);
+ expected = APFloat(APFloat::IEEEquad, "0x1p-16382");
+ EXPECT_FALSE(test.isNegative());
+ EXPECT_TRUE(test.isFiniteNonZero());
+ EXPECT_FALSE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ test = APFloat::getSmallestNormalized(APFloat::IEEEquad, true);
+ expected = APFloat(APFloat::IEEEquad, "-0x1p-16382");
+ EXPECT_TRUE(test.isNegative());
+ EXPECT_TRUE(test.isFiniteNonZero());
+ EXPECT_FALSE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+}
+
+TEST(APFloatTest, getZero) {
+ struct {
+ const fltSemantics *semantics;
+ const bool sign;
+ const unsigned long long bitPattern[2];
+ const unsigned bitPatternLength;
+ } const GetZeroTest[] = {
+ { &APFloat::IEEEhalf, false, {0, 0}, 1},
+ { &APFloat::IEEEhalf, true, {0x8000ULL, 0}, 1},
+ { &APFloat::IEEEsingle, false, {0, 0}, 1},
+ { &APFloat::IEEEsingle, true, {0x80000000ULL, 0}, 1},
+ { &APFloat::IEEEdouble, false, {0, 0}, 1},
+ { &APFloat::IEEEdouble, true, {0x8000000000000000ULL, 0}, 1},
+ { &APFloat::IEEEquad, false, {0, 0}, 2},
+ { &APFloat::IEEEquad, true, {0, 0x8000000000000000ULL}, 2},
+ { &APFloat::PPCDoubleDouble, false, {0, 0}, 2},
+ { &APFloat::PPCDoubleDouble, true, {0x8000000000000000ULL, 0}, 2},
+ { &APFloat::x87DoubleExtended, false, {0, 0}, 2},
+ { &APFloat::x87DoubleExtended, true, {0, 0x8000ULL}, 2},
+ };
+ const unsigned NumGetZeroTests = 12;
+ for (unsigned i = 0; i < NumGetZeroTests; ++i) {
+ APFloat test = APFloat::getZero(*GetZeroTest[i].semantics,
+ GetZeroTest[i].sign);
+ const char *pattern = GetZeroTest[i].sign? "-0x0p+0" : "0x0p+0";
+ APFloat expected = APFloat(*GetZeroTest[i].semantics,
+ pattern);
+ EXPECT_TRUE(test.isZero());
+ EXPECT_TRUE(GetZeroTest[i].sign? test.isNegative() : !test.isNegative());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+ for (unsigned j = 0, je = GetZeroTest[i].bitPatternLength; j < je; ++j) {
+ EXPECT_EQ(GetZeroTest[i].bitPattern[j],
+ test.bitcastToAPInt().getRawData()[j]);
+ }
+ }
+}
+
TEST(APFloatTest, convert) {
bool losesInfo;
APFloat test(APFloat::IEEEdouble, "1.0");
@@ -857,4 +1428,1247 @@ TEST(APFloatTest, PPCDoubleDouble) {
EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]);
#endif
}
+
+TEST(APFloatTest, isNegative) {
+ APFloat t(APFloat::IEEEsingle, "0x1p+0");
+ EXPECT_FALSE(t.isNegative());
+ t = APFloat(APFloat::IEEEsingle, "-0x1p+0");
+ EXPECT_TRUE(t.isNegative());
+
+ EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle, false).isNegative());
+ EXPECT_TRUE(APFloat::getInf(APFloat::IEEEsingle, true).isNegative());
+
+ EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle, false).isNegative());
+ EXPECT_TRUE(APFloat::getZero(APFloat::IEEEsingle, true).isNegative());
+
+ EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle, false).isNegative());
+ EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle, true).isNegative());
+
+ EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle, false).isNegative());
+ EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, true).isNegative());
+}
+
+TEST(APFloatTest, isNormal) {
+ APFloat t(APFloat::IEEEsingle, "0x1p+0");
+ EXPECT_TRUE(t.isNormal());
+
+ EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle, false).isNormal());
+ EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle, false).isNormal());
+ EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle, false).isNormal());
+ EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle, false).isNormal());
+ EXPECT_FALSE(APFloat(APFloat::IEEEsingle, "0x1p-149").isNormal());
+}
+
+TEST(APFloatTest, isFinite) {
+ APFloat t(APFloat::IEEEsingle, "0x1p+0");
+ EXPECT_TRUE(t.isFinite());
+ EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle, false).isFinite());
+ EXPECT_TRUE(APFloat::getZero(APFloat::IEEEsingle, false).isFinite());
+ EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle, false).isFinite());
+ EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle, false).isFinite());
+ EXPECT_TRUE(APFloat(APFloat::IEEEsingle, "0x1p-149").isFinite());
+}
+
+TEST(APFloatTest, isInfinity) {
+ APFloat t(APFloat::IEEEsingle, "0x1p+0");
+ EXPECT_FALSE(t.isInfinity());
+ EXPECT_TRUE(APFloat::getInf(APFloat::IEEEsingle, false).isInfinity());
+ EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle, false).isInfinity());
+ EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle, false).isInfinity());
+ EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle, false).isInfinity());
+ EXPECT_FALSE(APFloat(APFloat::IEEEsingle, "0x1p-149").isInfinity());
+}
+
+TEST(APFloatTest, isNaN) {
+ APFloat t(APFloat::IEEEsingle, "0x1p+0");
+ EXPECT_FALSE(t.isNaN());
+ EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle, false).isNaN());
+ EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle, false).isNaN());
+ EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle, false).isNaN());
+ EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, false).isNaN());
+ EXPECT_FALSE(APFloat(APFloat::IEEEsingle, "0x1p-149").isNaN());
+}
+
+TEST(APFloatTest, isFiniteNonZero) {
+ // Test positive/negative normal value.
+ EXPECT_TRUE(APFloat(APFloat::IEEEsingle, "0x1p+0").isFiniteNonZero());
+ EXPECT_TRUE(APFloat(APFloat::IEEEsingle, "-0x1p+0").isFiniteNonZero());
+
+ // Test positive/negative denormal value.
+ EXPECT_TRUE(APFloat(APFloat::IEEEsingle, "0x1p-149").isFiniteNonZero());
+ EXPECT_TRUE(APFloat(APFloat::IEEEsingle, "-0x1p-149").isFiniteNonZero());
+
+ // Test +/- Infinity.
+ EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle, false).isFiniteNonZero());
+ EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle, true).isFiniteNonZero());
+
+ // Test +/- Zero.
+ EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle, false).isFiniteNonZero());
+ EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle, true).isFiniteNonZero());
+
+ // Test +/- qNaN. +/- dont mean anything with qNaN but paranoia can't hurt in
+ // this instance.
+ EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle, false).isFiniteNonZero());
+ EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle, true).isFiniteNonZero());
+
+ // Test +/- sNaN. +/- dont mean anything with sNaN but paranoia can't hurt in
+ // this instance.
+ EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle, false).isFiniteNonZero());
+ EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle, true).isFiniteNonZero());
+}
+
+TEST(APFloatTest, add) {
+ // Test Special Cases against each other and normal values.
+
+ // TODOS/NOTES:
+ // 1. Since we perform only default exception handling all operations with
+ // signaling NaNs should have a result that is a quiet NaN. Currently they
+ // return sNaN.
+
+ APFloat PInf = APFloat::getInf(APFloat::IEEEsingle, false);
+ APFloat MInf = APFloat::getInf(APFloat::IEEEsingle, true);
+ APFloat PZero = APFloat::getZero(APFloat::IEEEsingle, false);
+ APFloat MZero = APFloat::getZero(APFloat::IEEEsingle, true);
+ APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle, false);
+ APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle, false);
+ APFloat PNormalValue = APFloat(APFloat::IEEEsingle, "0x1p+0");
+ APFloat MNormalValue = APFloat(APFloat::IEEEsingle, "-0x1p+0");
+ APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle, false);
+ APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle, true);
+ APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, false);
+ APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, true);
+ APFloat PSmallestNormalized =
+ APFloat::getSmallestNormalized(APFloat::IEEEsingle, false);
+ APFloat MSmallestNormalized =
+ APFloat::getSmallestNormalized(APFloat::IEEEsingle, true);
+
+ const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
+
+ const unsigned NumTests = 169;
+ struct {
+ APFloat x;
+ APFloat y;
+ const char *result;
+ int status;
+ int category;
+ } SpecialCaseTests[NumTests] = {
+ { PInf, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+ // See Note 1.
+ { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { MInf, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+ // See Note 1.
+ { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PZero, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PZero, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+ // See Note 1.
+ { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PZero, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PZero, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PZero, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { PZero, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { PZero, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { PZero, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { PZero, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { PZero, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { MZero, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MZero, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+ // See Note 1.
+ { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MZero, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MZero, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MZero, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { MZero, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { MZero, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { MZero, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { MZero, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { MZero, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+ // See Note 1.
+ { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+ // See Note 1.
+ { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PNormalValue, PZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PNormalValue, MZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+ // See Note 1.
+ { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PNormalValue, PNormalValue, "0x1p+1", APFloat::opOK, APFloat::fcNormal },
+ { PNormalValue, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PNormalValue, PSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { PNormalValue, MSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { PNormalValue, PSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { PNormalValue, MSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { MNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MNormalValue, PZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, MZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+ // See Note 1.
+ { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MNormalValue, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MNormalValue, MNormalValue, "-0x1p+1", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MNormalValue, PSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { MNormalValue, MSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { MNormalValue, PSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { MNormalValue, MSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { PLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PLargestValue, PZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { PLargestValue, MZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+ // See Note 1.
+ { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PLargestValue, PLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
+ { PLargestValue, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PLargestValue, PSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PLargestValue, MSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PLargestValue, PSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PLargestValue, MSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MLargestValue, PZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { MLargestValue, MZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+ // See Note 1.
+ { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MLargestValue, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MLargestValue, MLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
+ { MLargestValue, PSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MLargestValue, MSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MLargestValue, PSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MLargestValue, MSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PSmallestValue, PZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, MZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+ // See Note 1.
+ { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PSmallestValue, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestValue, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestValue, PSmallestValue, "0x1p-148", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PSmallestValue, PSmallestNormalized, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, MSmallestNormalized, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MSmallestValue, PZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, MZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+ // See Note 1.
+ { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MSmallestValue, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { MSmallestValue, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { MSmallestValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MSmallestValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MSmallestValue, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MSmallestValue, MSmallestValue, "-0x1p-148", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, PSmallestNormalized, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, MSmallestNormalized, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PSmallestNormalized, PZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, MZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PSmallestNormalized, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestNormalized, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestNormalized, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestNormalized, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestNormalized, PSmallestValue, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, MSmallestValue, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, PSmallestNormalized, "0x1p-125", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MSmallestNormalized, PZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, MZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+ // See Note 1.
+ { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MSmallestNormalized, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { MSmallestNormalized, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { MSmallestNormalized, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MSmallestNormalized, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MSmallestNormalized, PSmallestValue, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, MSmallestValue, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MSmallestNormalized, MSmallestNormalized, "-0x1p-125", APFloat::opOK, APFloat::fcNormal }
+ };
+
+ for (size_t i = 0; i < NumTests; ++i) {
+ APFloat x(SpecialCaseTests[i].x);
+ APFloat y(SpecialCaseTests[i].y);
+ APFloat::opStatus status = x.add(y, APFloat::rmNearestTiesToEven);
+
+ APFloat result(APFloat::IEEEsingle, SpecialCaseTests[i].result);
+
+ EXPECT_TRUE(result.bitwiseIsEqual(x));
+ EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
+ EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
+ }
+}
+
+TEST(APFloatTest, subtract) {
+ // Test Special Cases against each other and normal values.
+
+ // TODOS/NOTES:
+ // 1. Since we perform only default exception handling all operations with
+ // signaling NaNs should have a result that is a quiet NaN. Currently they
+ // return sNaN.
+
+ APFloat PInf = APFloat::getInf(APFloat::IEEEsingle, false);
+ APFloat MInf = APFloat::getInf(APFloat::IEEEsingle, true);
+ APFloat PZero = APFloat::getZero(APFloat::IEEEsingle, false);
+ APFloat MZero = APFloat::getZero(APFloat::IEEEsingle, true);
+ APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle, false);
+ APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle, false);
+ APFloat PNormalValue = APFloat(APFloat::IEEEsingle, "0x1p+0");
+ APFloat MNormalValue = APFloat(APFloat::IEEEsingle, "-0x1p+0");
+ APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle, false);
+ APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle, true);
+ APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, false);
+ APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, true);
+ APFloat PSmallestNormalized =
+ APFloat::getSmallestNormalized(APFloat::IEEEsingle, false);
+ APFloat MSmallestNormalized =
+ APFloat::getSmallestNormalized(APFloat::IEEEsingle, true);
+
+ const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
+
+ const unsigned NumTests = 169;
+ struct {
+ APFloat x;
+ APFloat y;
+ const char *result;
+ int status;
+ int category;
+ } SpecialCaseTests[NumTests] = {
+ { PInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { PInf, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PZero, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PZero, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PZero, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PZero, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PZero, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { PZero, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { PZero, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { PZero, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { PZero, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { PZero, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { MZero, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MZero, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MZero, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MZero, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MZero, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MZero, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { MZero, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { MZero, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { MZero, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { MZero, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { MZero, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PNormalValue, PZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PNormalValue, MZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PNormalValue, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PNormalValue, MNormalValue, "0x1p+1", APFloat::opOK, APFloat::fcNormal },
+ { PNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PNormalValue, PSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { PNormalValue, MSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { PNormalValue, PSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { PNormalValue, MSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { MNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MNormalValue, PZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, MZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MNormalValue, PNormalValue, "-0x1p+1", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MNormalValue, PSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { MNormalValue, MSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { MNormalValue, PSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { MNormalValue, MSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { PLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PLargestValue, PZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { PLargestValue, MZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PLargestValue, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PLargestValue, MLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
+ { PLargestValue, PSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PLargestValue, MSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PLargestValue, PSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PLargestValue, MSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MLargestValue, PZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { MLargestValue, MZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MLargestValue, PLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
+ { MLargestValue, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MLargestValue, PSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MLargestValue, MSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MLargestValue, PSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MLargestValue, MSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PSmallestValue, PZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, MZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PSmallestValue, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestValue, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestValue, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PSmallestValue, MSmallestValue, "0x1p-148", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, PSmallestNormalized, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, MSmallestNormalized, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MSmallestValue, PZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, MZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MSmallestValue, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { MSmallestValue, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { MSmallestValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MSmallestValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MSmallestValue, PSmallestValue, "-0x1p-148", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MSmallestValue, PSmallestNormalized, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, MSmallestNormalized, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PSmallestNormalized, PZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, MZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PSmallestNormalized, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestNormalized, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestNormalized, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestNormalized, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { PSmallestNormalized, PSmallestValue, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, MSmallestValue, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PSmallestNormalized, MSmallestNormalized, "0x1p-125", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MSmallestNormalized, PZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, MZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MSmallestNormalized, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { MSmallestNormalized, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
+ { MSmallestNormalized, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MSmallestNormalized, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
+ { MSmallestNormalized, PSmallestValue, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, MSmallestValue, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, PSmallestNormalized, "-0x1p-125", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero }
+ };
+
+ for (size_t i = 0; i < NumTests; ++i) {
+ APFloat x(SpecialCaseTests[i].x);
+ APFloat y(SpecialCaseTests[i].y);
+ APFloat::opStatus status = x.subtract(y, APFloat::rmNearestTiesToEven);
+
+ APFloat result(APFloat::IEEEsingle, SpecialCaseTests[i].result);
+
+ EXPECT_TRUE(result.bitwiseIsEqual(x));
+ EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
+ EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
+ }
+}
+
+TEST(APFloatTest, multiply) {
+ // Test Special Cases against each other and normal values.
+
+ // TODOS/NOTES:
+ // 1. Since we perform only default exception handling all operations with
+ // signaling NaNs should have a result that is a quiet NaN. Currently they
+ // return sNaN.
+
+ APFloat PInf = APFloat::getInf(APFloat::IEEEsingle, false);
+ APFloat MInf = APFloat::getInf(APFloat::IEEEsingle, true);
+ APFloat PZero = APFloat::getZero(APFloat::IEEEsingle, false);
+ APFloat MZero = APFloat::getZero(APFloat::IEEEsingle, true);
+ APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle, false);
+ APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle, false);
+ APFloat PNormalValue = APFloat(APFloat::IEEEsingle, "0x1p+0");
+ APFloat MNormalValue = APFloat(APFloat::IEEEsingle, "-0x1p+0");
+ APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle, false);
+ APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle, true);
+ APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, false);
+ APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, true);
+ APFloat PSmallestNormalized =
+ APFloat::getSmallestNormalized(APFloat::IEEEsingle, false);
+ APFloat MSmallestNormalized =
+ APFloat::getSmallestNormalized(APFloat::IEEEsingle, true);
+
+ const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
+ const int UnderflowStatus = APFloat::opUnderflow | APFloat::opInexact;
+
+ const unsigned NumTests = 169;
+ struct {
+ APFloat x;
+ APFloat y;
+ const char *result;
+ int status;
+ int category;
+ } SpecialCaseTests[NumTests] = {
+ { PInf, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { PInf, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { MInf, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PZero, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { PZero, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PZero, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, MNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, MLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, MSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { MZero, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { MZero, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MZero, PNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, PLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, PSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PNormalValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PNormalValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PNormalValue, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PNormalValue, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { PNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { PNormalValue, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { PNormalValue, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { PNormalValue, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { PNormalValue, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MNormalValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MNormalValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MNormalValue, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { PLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PLargestValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PLargestValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { PLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { PLargestValue, PLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
+ { PLargestValue, MLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
+ { PLargestValue, PSmallestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
+ { PLargestValue, MSmallestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
+ { PLargestValue, PSmallestNormalized, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
+ { PLargestValue, MSmallestNormalized, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
+ { MLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MLargestValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MLargestValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { MLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { MLargestValue, PLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
+ { MLargestValue, MLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
+ { MLargestValue, PSmallestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
+ { MLargestValue, MSmallestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
+ { MLargestValue, PSmallestNormalized, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
+ { MLargestValue, MSmallestNormalized, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PSmallestValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PSmallestValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PSmallestValue, PNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, MNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, PLargestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, MLargestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, PSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { PSmallestValue, MSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { PSmallestValue, PSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { PSmallestValue, MSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { MSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MSmallestValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MSmallestValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MSmallestValue, PNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, MNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, PLargestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, MLargestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, PSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { MSmallestValue, MSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { MSmallestValue, PSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { MSmallestValue, MSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { PSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PSmallestNormalized, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PSmallestNormalized, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PSmallestNormalized, PNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, MNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, PLargestValue, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, MLargestValue, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, PSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { PSmallestNormalized, MSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { PSmallestNormalized, PSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { PSmallestNormalized, MSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { MSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MSmallestNormalized, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MSmallestNormalized, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MSmallestNormalized, PNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, MNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, PLargestValue, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, MLargestValue, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, PSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { MSmallestNormalized, MSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { MSmallestNormalized, PSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { MSmallestNormalized, MSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero }
+ };
+
+ for (size_t i = 0; i < NumTests; ++i) {
+ APFloat x(SpecialCaseTests[i].x);
+ APFloat y(SpecialCaseTests[i].y);
+ APFloat::opStatus status = x.multiply(y, APFloat::rmNearestTiesToEven);
+
+ APFloat result(APFloat::IEEEsingle, SpecialCaseTests[i].result);
+
+ EXPECT_TRUE(result.bitwiseIsEqual(x));
+ EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
+ EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
+ }
+}
+
+TEST(APFloatTest, divide) {
+ // Test Special Cases against each other and normal values.
+
+ // TODOS/NOTES:
+ // 1. Since we perform only default exception handling all operations with
+ // signaling NaNs should have a result that is a quiet NaN. Currently they
+ // return sNaN.
+
+ APFloat PInf = APFloat::getInf(APFloat::IEEEsingle, false);
+ APFloat MInf = APFloat::getInf(APFloat::IEEEsingle, true);
+ APFloat PZero = APFloat::getZero(APFloat::IEEEsingle, false);
+ APFloat MZero = APFloat::getZero(APFloat::IEEEsingle, true);
+ APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle, false);
+ APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle, false);
+ APFloat PNormalValue = APFloat(APFloat::IEEEsingle, "0x1p+0");
+ APFloat MNormalValue = APFloat(APFloat::IEEEsingle, "-0x1p+0");
+ APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle, false);
+ APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle, true);
+ APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, false);
+ APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, true);
+ APFloat PSmallestNormalized =
+ APFloat::getSmallestNormalized(APFloat::IEEEsingle, false);
+ APFloat MSmallestNormalized =
+ APFloat::getSmallestNormalized(APFloat::IEEEsingle, true);
+
+ const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
+ const int UnderflowStatus = APFloat::opUnderflow | APFloat::opInexact;
+
+ const unsigned NumTests = 169;
+ struct {
+ APFloat x;
+ APFloat y;
+ const char *result;
+ int status;
+ int category;
+ } SpecialCaseTests[NumTests] = {
+ { PInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { PInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { MInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
+ { MInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
+ { PZero, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { PZero, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PZero, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, MNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, MLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PZero, MSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { MZero, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MZero, PNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, PLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, PSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MZero, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
+ { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PNormalValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PNormalValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PNormalValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
+ { PNormalValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
+ { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PNormalValue, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PNormalValue, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PNormalValue, PLargestValue, "0x1p-128", UnderflowStatus, APFloat::fcNormal },
+ { PNormalValue, MLargestValue, "-0x1p-128", UnderflowStatus, APFloat::fcNormal },
+ { PNormalValue, PSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
+ { PNormalValue, MSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
+ { PNormalValue, PSmallestNormalized, "0x1p+126", APFloat::opOK, APFloat::fcNormal },
+ { PNormalValue, MSmallestNormalized, "-0x1p+126", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MNormalValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MNormalValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
+ { MNormalValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
+ { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MNormalValue, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, PLargestValue, "-0x1p-128", UnderflowStatus, APFloat::fcNormal },
+ { MNormalValue, MLargestValue, "0x1p-128", UnderflowStatus, APFloat::fcNormal },
+ { MNormalValue, PSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
+ { MNormalValue, MSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
+ { MNormalValue, PSmallestNormalized, "-0x1p+126", APFloat::opOK, APFloat::fcNormal },
+ { MNormalValue, MSmallestNormalized, "0x1p+126", APFloat::opOK, APFloat::fcNormal },
+ { PLargestValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PLargestValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PLargestValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
+ { PLargestValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
+ { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { PLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { PLargestValue, PLargestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PLargestValue, MLargestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PLargestValue, PSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
+ { PLargestValue, MSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
+ { PLargestValue, PSmallestNormalized, "inf", OverflowStatus, APFloat::fcInfinity },
+ { PLargestValue, MSmallestNormalized, "-inf", OverflowStatus, APFloat::fcInfinity },
+ { MLargestValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MLargestValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MLargestValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
+ { MLargestValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
+ { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { MLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
+ { MLargestValue, PLargestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MLargestValue, MLargestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MLargestValue, PSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
+ { MLargestValue, MSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
+ { MLargestValue, PSmallestNormalized, "-inf", OverflowStatus, APFloat::fcInfinity },
+ { MLargestValue, MSmallestNormalized, "inf", OverflowStatus, APFloat::fcInfinity },
+ { PSmallestValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PSmallestValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PSmallestValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
+ { PSmallestValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
+ { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PSmallestValue, PNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, MNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, PLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { PSmallestValue, MLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { PSmallestValue, PSmallestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, MSmallestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, PSmallestNormalized, "0x1p-23", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestValue, MSmallestNormalized, "-0x1p-23", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MSmallestValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MSmallestValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
+ { MSmallestValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
+ { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MSmallestValue, PNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, MNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, PLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { MSmallestValue, MLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { MSmallestValue, PSmallestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, MSmallestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, PSmallestNormalized, "-0x1p-23", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestValue, MSmallestNormalized, "0x1p-23", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PSmallestNormalized, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { PSmallestNormalized, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
+ { PSmallestNormalized, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
+ { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { PSmallestNormalized, PNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, MNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, PLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { PSmallestNormalized, MLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { PSmallestNormalized, PSmallestValue, "0x1p+23", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, MSmallestValue, "-0x1p+23", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, PSmallestNormalized, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { PSmallestNormalized, MSmallestNormalized, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MSmallestNormalized, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
+ { MSmallestNormalized, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
+ { MSmallestNormalized, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
+ { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+#if 0
+// See Note 1.
+ { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+#endif
+ { MSmallestNormalized, PNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, MNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, PLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { MSmallestNormalized, MLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
+ { MSmallestNormalized, PSmallestValue, "-0x1p+23", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, MSmallestValue, "0x1p+23", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, PSmallestNormalized, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ { MSmallestNormalized, MSmallestNormalized, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
+ };
+
+ for (size_t i = 0; i < NumTests; ++i) {
+ APFloat x(SpecialCaseTests[i].x);
+ APFloat y(SpecialCaseTests[i].y);
+ APFloat::opStatus status = x.divide(y, APFloat::rmNearestTiesToEven);
+
+ APFloat result(APFloat::IEEEsingle, SpecialCaseTests[i].result);
+
+ EXPECT_TRUE(result.bitwiseIsEqual(x));
+ EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
+ EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
+ }
+}
+
}
diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp
index f129fa71c8e06..3c0dfe1440447 100644
--- a/unittests/ADT/APIntTest.cpp
+++ b/unittests/ADT/APIntTest.cpp
@@ -532,4 +532,69 @@ TEST(APIntTest, Splat) {
EXPECT_EQ(APInt(15, 0xDB6D), APInt::getSplat(15, ValB));
}
+TEST(APIntTest, tcDecrement) {
+ // Test single word decrement.
+
+ // No out borrow.
+ {
+ integerPart singleWord = ~integerPart(0) << (integerPartWidth - 1);
+ integerPart carry = APInt::tcDecrement(&singleWord, 1);
+ EXPECT_EQ(carry, integerPart(0));
+ EXPECT_EQ(singleWord, ~integerPart(0) >> 1);
+ }
+
+ // With out borrow.
+ {
+ integerPart singleWord = 0;
+ integerPart carry = APInt::tcDecrement(&singleWord, 1);
+ EXPECT_EQ(carry, integerPart(1));
+ EXPECT_EQ(singleWord, ~integerPart(0));
+ }
+
+ // Test multiword decrement.
+
+ // No across word borrow, no out borrow.
+ {
+ integerPart test[4] = {0x1, 0x1, 0x1, 0x1};
+ integerPart expected[4] = {0x0, 0x1, 0x1, 0x1};
+ APInt::tcDecrement(test, 4);
+ EXPECT_EQ(APInt::tcCompare(test, expected, 4), 0);
+ }
+
+ // 1 across word borrow, no out borrow.
+ {
+ integerPart test[4] = {0x0, 0xF, 0x1, 0x1};
+ integerPart expected[4] = {~integerPart(0), 0xE, 0x1, 0x1};
+ integerPart carry = APInt::tcDecrement(test, 4);
+ EXPECT_EQ(carry, integerPart(0));
+ EXPECT_EQ(APInt::tcCompare(test, expected, 4), 0);
+ }
+
+ // 2 across word borrow, no out borrow.
+ {
+ integerPart test[4] = {0x0, 0x0, 0xC, 0x1};
+ integerPart expected[4] = {~integerPart(0), ~integerPart(0), 0xB, 0x1};
+ integerPart carry = APInt::tcDecrement(test, 4);
+ EXPECT_EQ(carry, integerPart(0));
+ EXPECT_EQ(APInt::tcCompare(test, expected, 4), 0);
+ }
+
+ // 3 across word borrow, no out borrow.
+ {
+ integerPart test[4] = {0x0, 0x0, 0x0, 0x1};
+ integerPart expected[4] = {~integerPart(0), ~integerPart(0), ~integerPart(0), 0x0};
+ integerPart carry = APInt::tcDecrement(test, 4);
+ EXPECT_EQ(carry, integerPart(0));
+ EXPECT_EQ(APInt::tcCompare(test, expected, 4), 0);
+ }
+
+ // 3 across word borrow, with out borrow.
+ {
+ integerPart test[4] = {0x0, 0x0, 0x0, 0x0};
+ integerPart expected[4] = {~integerPart(0), ~integerPart(0), ~integerPart(0), ~integerPart(0)};
+ integerPart carry = APInt::tcDecrement(test, 4);
+ EXPECT_EQ(carry, integerPart(1));
+ EXPECT_EQ(APInt::tcCompare(test, expected, 4), 0);
+ }
+}
}
diff --git a/unittests/ADT/BitVectorTest.cpp b/unittests/ADT/BitVectorTest.cpp
index dc298a83d571a..d7cde891fb562 100644
--- a/unittests/ADT/BitVectorTest.cpp
+++ b/unittests/ADT/BitVectorTest.cpp
@@ -141,6 +141,30 @@ TYPED_TEST(BitVectorTest, TrivialOperation) {
EXPECT_TRUE(Vec.none());
EXPECT_FALSE(Vec.empty());
+ Vec.flip();
+ EXPECT_EQ(130U, Vec.count());
+ EXPECT_EQ(130U, Vec.size());
+ EXPECT_TRUE(Vec.any());
+ EXPECT_TRUE(Vec.all());
+ EXPECT_FALSE(Vec.none());
+ EXPECT_FALSE(Vec.empty());
+
+ Vec.resize(64);
+ EXPECT_EQ(64U, Vec.count());
+ EXPECT_EQ(64U, Vec.size());
+ EXPECT_TRUE(Vec.any());
+ EXPECT_TRUE(Vec.all());
+ EXPECT_FALSE(Vec.none());
+ EXPECT_FALSE(Vec.empty());
+
+ Vec.flip();
+ EXPECT_EQ(0U, Vec.count());
+ EXPECT_EQ(64U, Vec.size());
+ EXPECT_FALSE(Vec.any());
+ EXPECT_FALSE(Vec.all());
+ EXPECT_TRUE(Vec.none());
+ EXPECT_FALSE(Vec.empty());
+
Inv = TypeParam().flip();
EXPECT_EQ(0U, Inv.count());
EXPECT_EQ(0U, Inv.size());
@@ -333,5 +357,41 @@ TYPED_TEST(BitVectorTest, RangeOps) {
EXPECT_TRUE( E.test(32));
EXPECT_FALSE(E.test(33));
}
+
+TYPED_TEST(BitVectorTest, CompoundTestReset) {
+ TypeParam A(50, true);
+ TypeParam B(50, false);
+
+ TypeParam C(100, true);
+ TypeParam D(100, false);
+
+ EXPECT_FALSE(A.test(A));
+ EXPECT_TRUE(A.test(B));
+ EXPECT_FALSE(A.test(C));
+ EXPECT_TRUE(A.test(D));
+ EXPECT_FALSE(B.test(A));
+ EXPECT_FALSE(B.test(B));
+ EXPECT_FALSE(B.test(C));
+ EXPECT_FALSE(B.test(D));
+ EXPECT_TRUE(C.test(A));
+ EXPECT_TRUE(C.test(B));
+ EXPECT_FALSE(C.test(C));
+ EXPECT_TRUE(C.test(D));
+
+ A.reset(B);
+ A.reset(D);
+ EXPECT_TRUE(A.all());
+ A.reset(A);
+ EXPECT_TRUE(A.none());
+ A.set();
+ A.reset(C);
+ EXPECT_TRUE(A.none());
+ A.set();
+
+ C.reset(A);
+ EXPECT_EQ(50, C.find_first());
+ C.reset(C);
+ EXPECT_TRUE(C.none());
+}
}
#endif
diff --git a/unittests/ADT/CMakeLists.txt b/unittests/ADT/CMakeLists.txt
index 9aad793d8bc4d..8ad303a9e1b33 100644
--- a/unittests/ADT/CMakeLists.txt
+++ b/unittests/ADT/CMakeLists.txt
@@ -21,6 +21,7 @@ set(ADTSources
MapVectorTest.cpp
OptionalTest.cpp
PackedVectorTest.cpp
+ PointerUnionTest.cpp
SCCIteratorTest.cpp
SmallPtrSetTest.cpp
SmallStringTest.cpp
@@ -34,6 +35,7 @@ set(ADTSources
TripleTest.cpp
TwineTest.cpp
VariadicFunctionTest.cpp
+ polymorphic_ptr_test.cpp
)
# They cannot be compiled on MSVC9 due to its bug.
diff --git a/unittests/ADT/IntrusiveRefCntPtrTest.cpp b/unittests/ADT/IntrusiveRefCntPtrTest.cpp
index 0c8c4ca16dd73..c67ec130912de 100644
--- a/unittests/ADT/IntrusiveRefCntPtrTest.cpp
+++ b/unittests/ADT/IntrusiveRefCntPtrTest.cpp
@@ -10,11 +10,13 @@
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "gtest/gtest.h"
-namespace llvm {
-
-struct VirtualRefCounted : public RefCountedBaseVPTR {
+namespace {
+struct VirtualRefCounted : public llvm::RefCountedBaseVPTR {
virtual void f() {}
};
+}
+
+namespace llvm {
// Run this test with valgrind to detect memory leaks.
TEST(IntrusiveRefCntPtr, RefCountedBaseVPTRCopyDoesNotLeak) {
diff --git a/unittests/ADT/PointerUnionTest.cpp b/unittests/ADT/PointerUnionTest.cpp
new file mode 100644
index 0000000000000..7eb718112d692
--- /dev/null
+++ b/unittests/ADT/PointerUnionTest.cpp
@@ -0,0 +1,64 @@
+//===- llvm/unittest/ADT/PointerUnionTest.cpp - Optional unit tests -------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/ADT/PointerUnion.h"
+using namespace llvm;
+
+namespace {
+
+typedef PointerUnion<int*, float*> PU;
+
+// Test fixture
+class PointerUnionTest : public testing::Test {
+};
+
+float f = 3.14f;
+int i = 42;
+
+const PU a(&f);
+const PU b(&i);
+const PU n;
+
+TEST_F(PointerUnionTest, Comparison) {
+ EXPECT_TRUE(a != b);
+ EXPECT_FALSE(a == b);
+ EXPECT_TRUE(b != n);
+ EXPECT_FALSE(b == n);
+}
+
+TEST_F(PointerUnionTest, Null) {
+ EXPECT_FALSE(a.isNull());
+ EXPECT_FALSE(b.isNull());
+ EXPECT_TRUE(n.isNull());
+ EXPECT_FALSE(!a);
+ EXPECT_FALSE(!b);
+ EXPECT_TRUE(!n);
+ // workaround an issue with EXPECT macros and explicit bool
+ EXPECT_TRUE((bool)a);
+ EXPECT_TRUE((bool)b);
+ EXPECT_FALSE(n);
+}
+
+TEST_F(PointerUnionTest, Is) {
+ EXPECT_FALSE(a.is<int*>());
+ EXPECT_TRUE(a.is<float*>());
+ EXPECT_TRUE(b.is<int*>());
+ EXPECT_FALSE(b.is<float*>());
+ EXPECT_TRUE(n.is<int*>());
+ EXPECT_FALSE(n.is<float*>());
+}
+
+TEST_F(PointerUnionTest, Get) {
+ EXPECT_EQ(a.get<float*>(), &f);
+ EXPECT_EQ(b.get<int*>(), &i);
+ EXPECT_EQ(n.get<int*>(), (int*)0);
+}
+
+} // end anonymous namespace
diff --git a/unittests/ADT/StringRefTest.cpp b/unittests/ADT/StringRefTest.cpp
index fa87cd0e2c867..88691ae197494 100644
--- a/unittests/ADT/StringRefTest.cpp
+++ b/unittests/ADT/StringRefTest.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/raw_ostream.h"
@@ -60,6 +61,9 @@ TEST(StringRefTest, StringOps) {
EXPECT_EQ( 0, StringRef("AaB").compare_lower("aab"));
EXPECT_EQ( 1, StringRef("AaB").compare_lower("AAA"));
EXPECT_EQ(-1, StringRef("AaB").compare_lower("aaBb"));
+ EXPECT_EQ(-1, StringRef("AaB").compare_lower("bb"));
+ EXPECT_EQ( 1, StringRef("aaBb").compare_lower("AaB"));
+ EXPECT_EQ( 1, StringRef("bb").compare_lower("AaB"));
EXPECT_EQ( 1, StringRef("AaB").compare_lower("aA"));
EXPECT_EQ( 1, StringRef("\xFF").compare_lower("\1"));
@@ -247,19 +251,41 @@ TEST(StringRefTest, Trim) {
TEST(StringRefTest, StartsWith) {
StringRef Str("hello");
+ EXPECT_TRUE(Str.startswith(""));
EXPECT_TRUE(Str.startswith("he"));
EXPECT_FALSE(Str.startswith("helloworld"));
EXPECT_FALSE(Str.startswith("hi"));
}
+TEST(StringRefTest, StartsWithLower) {
+ StringRef Str("heLLo");
+ EXPECT_TRUE(Str.startswith_lower(""));
+ EXPECT_TRUE(Str.startswith_lower("he"));
+ EXPECT_TRUE(Str.startswith_lower("hell"));
+ EXPECT_TRUE(Str.startswith_lower("HELlo"));
+ EXPECT_FALSE(Str.startswith_lower("helloworld"));
+ EXPECT_FALSE(Str.startswith_lower("hi"));
+}
+
TEST(StringRefTest, EndsWith) {
StringRef Str("hello");
+ EXPECT_TRUE(Str.endswith(""));
EXPECT_TRUE(Str.endswith("lo"));
EXPECT_FALSE(Str.endswith("helloworld"));
EXPECT_FALSE(Str.endswith("worldhello"));
EXPECT_FALSE(Str.endswith("so"));
}
+TEST(StringRefTest, EndsWithLower) {
+ StringRef Str("heLLo");
+ EXPECT_TRUE(Str.endswith_lower(""));
+ EXPECT_TRUE(Str.endswith_lower("lo"));
+ EXPECT_TRUE(Str.endswith_lower("LO"));
+ EXPECT_TRUE(Str.endswith_lower("ELlo"));
+ EXPECT_FALSE(Str.endswith_lower("helloworld"));
+ EXPECT_FALSE(Str.endswith_lower("hi"));
+}
+
TEST(StringRefTest, Find) {
StringRef Str("hello");
EXPECT_EQ(2U, Str.find('l'));
@@ -477,6 +503,32 @@ TEST(StringRefTest, getAsUnsignedIntegerBadStrings) {
}
}
+static const char *join_input[] = { "a", "b", "c" };
+static const char join_result1[] = "a";
+static const char join_result2[] = "a:b:c";
+static const char join_result3[] = "a::b::c";
+
+TEST(StringRefTest, joinStrings) {
+ std::vector<StringRef> v1;
+ std::vector<std::string> v2;
+ for (size_t i = 0; i < array_lengthof(join_input); ++i) {
+ v1.push_back(join_input[i]);
+ v2.push_back(join_input[i]);
+ }
+ bool v1_join1 = join(v1.begin(), v1.begin() + 1, ":") == join_result1;
+ EXPECT_TRUE(v1_join1);
+ bool v1_join2 = join(v1.begin(), v1.end(), ":") == join_result2;
+ EXPECT_TRUE(v1_join2);
+ bool v1_join3 = join(v1.begin(), v1.end(), "::") == join_result3;
+ EXPECT_TRUE(v1_join3);
+
+ bool v2_join1 = join(v2.begin(), v2.begin() + 1, ":") == join_result1;
+ EXPECT_TRUE(v2_join1);
+ bool v2_join2 = join(v2.begin(), v2.end(), ":") == join_result2;
+ EXPECT_TRUE(v2_join2);
+ bool v2_join3 = join(v2.begin(), v2.end(), "::") == join_result3;
+ EXPECT_TRUE(v2_join3);
+}
} // end anonymous namespace
diff --git a/unittests/ADT/polymorphic_ptr_test.cpp b/unittests/ADT/polymorphic_ptr_test.cpp
new file mode 100644
index 0000000000000..bd5d83879a83f
--- /dev/null
+++ b/unittests/ADT/polymorphic_ptr_test.cpp
@@ -0,0 +1,129 @@
+//===- llvm/unittest/ADT/polymorphic_ptr.h - polymorphic_ptr<T> tests -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/ADT/polymorphic_ptr.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+namespace {
+
+struct S {
+ S(int x) : x(x) {}
+ S *clone() { return new S(*this); }
+ int x;
+};
+
+// A function that forces the return of a copy.
+template <typename T>
+T dummy_copy(const T &arg) { return arg; }
+
+TEST(polymorphic_ptr_test, Basic) {
+ polymorphic_ptr<S> null;
+ EXPECT_FALSE((bool)null);
+ EXPECT_TRUE(!null);
+ EXPECT_EQ((S*)0, null.get());
+
+ S *s = new S(42);
+ polymorphic_ptr<S> p(s);
+ EXPECT_TRUE((bool)p);
+ EXPECT_FALSE(!p);
+ EXPECT_TRUE(p != null);
+ EXPECT_FALSE(p == null);
+ EXPECT_TRUE(p == s);
+ EXPECT_TRUE(s == p);
+ EXPECT_FALSE(p != s);
+ EXPECT_FALSE(s != p);
+ EXPECT_EQ(s, &*p);
+ EXPECT_EQ(s, p.operator->());
+ EXPECT_EQ(s, p.get());
+ EXPECT_EQ(42, p->x);
+
+ EXPECT_EQ(s, p.take());
+ EXPECT_FALSE((bool)p);
+ EXPECT_TRUE(!p);
+ p = s;
+ EXPECT_TRUE((bool)p);
+ EXPECT_FALSE(!p);
+ EXPECT_EQ(s, &*p);
+ EXPECT_EQ(s, p.operator->());
+ EXPECT_EQ(s, p.get());
+ EXPECT_EQ(42, p->x);
+
+ polymorphic_ptr<S> p2((llvm_move(p)));
+#if !LLVM_HAS_RVALUE_REFERENCES
+ // 'p' may not have been moved from in C++98, fake it for the test.
+ p2 = p.take();
+#endif
+ EXPECT_FALSE((bool)p);
+ EXPECT_TRUE(!p);
+ EXPECT_TRUE((bool)p2);
+ EXPECT_FALSE(!p2);
+ EXPECT_EQ(s, &*p2);
+
+ using std::swap;
+ swap(p, p2);
+ EXPECT_TRUE((bool)p);
+ EXPECT_FALSE(!p);
+ EXPECT_EQ(s, &*p);
+ EXPECT_FALSE((bool)p2);
+ EXPECT_TRUE(!p2);
+
+ // Force copies and that everything survives.
+ polymorphic_ptr<S> p3 = dummy_copy(polymorphic_ptr<S>(p));
+ EXPECT_TRUE((bool)p3);
+ EXPECT_FALSE(!p3);
+ EXPECT_NE(s, &*p3);
+ EXPECT_EQ(42, p3->x);
+
+ // Force copies of null without trying to dereference anything.
+ polymorphic_ptr<S> null_copy = dummy_copy(polymorphic_ptr<S>(null));
+ EXPECT_FALSE((bool)null_copy);
+ EXPECT_TRUE(!null_copy);
+ EXPECT_EQ(null, null_copy);
+}
+
+struct Base {
+ virtual ~Base() {}
+ virtual Base *clone() = 0;
+ virtual StringRef name() { return "Base"; }
+};
+
+struct DerivedA : Base {
+ virtual DerivedA *clone() { return new DerivedA(); }
+ virtual StringRef name() { return "DerivedA"; }
+};
+struct DerivedB : Base {
+ virtual DerivedB *clone() { return new DerivedB(); }
+ virtual StringRef name() { return "DerivedB"; }
+};
+
+TEST(polymorphic_ptr_test, Polymorphism) {
+ polymorphic_ptr<Base> a(new DerivedA());
+ polymorphic_ptr<Base> b(new DerivedB());
+
+ EXPECT_EQ("DerivedA", a->name());
+ EXPECT_EQ("DerivedB", b->name());
+
+ polymorphic_ptr<Base> copy = dummy_copy(a);
+ EXPECT_NE(a, copy);
+ EXPECT_EQ("DerivedA", copy->name());
+
+ copy = dummy_copy(b);
+ EXPECT_NE(b, copy);
+ EXPECT_EQ("DerivedB", copy->name());
+
+ // Test creating a copy out of a temporary directly.
+ copy = dummy_copy<polymorphic_ptr<Base> >(new DerivedA());
+ EXPECT_NE(a, copy);
+ EXPECT_EQ("DerivedA", copy->name());
+}
+
+}