Skip to content

Commit 8606d01

Browse files
committed
[APFloat] Enlarge ExponentType to 32bit integer
Enlarge the size of ExponentType from 16bit integer to 32bit. This is required to prevent exponent overflow/underflow. Note that IEEEFloat size and alignment don't change in 64bit or 32bit compilation targets (and in turn, neither does APFloat). Fixes PR34851. Differential Revision: https://reviews.llvm.org/D69771
1 parent 8ca7871 commit 8606d01

File tree

2 files changed

+118
-16
lines changed

2 files changed

+118
-16
lines changed

llvm/include/llvm/ADT/APFloat.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ struct APFloatBase {
143143
static const unsigned integerPartWidth = APInt::APINT_BITS_PER_WORD;
144144

145145
/// A signed type to represent a floating point numbers unbiased exponent.
146-
typedef signed short ExponentType;
146+
typedef int32_t ExponentType;
147147

148148
/// \name Floating Point Semantics.
149149
/// @{

llvm/unittests/ADT/APFloatTest.cpp

+117-15
Original file line numberDiff line numberDiff line change
@@ -2335,21 +2335,28 @@ TEST(APFloatTest, multiply) {
23352335
APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
23362336
APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
23372337
APFloat PSmallestNormalized =
2338-
APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
2338+
APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
23392339
APFloat MSmallestNormalized =
2340-
APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
2340+
APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
2341+
2342+
APFloat MaxQuad(APFloat::IEEEquad(),
2343+
"0x1.ffffffffffffffffffffffffffffp+16383");
2344+
APFloat MinQuad(APFloat::IEEEquad(),
2345+
"0x0.0000000000000000000000000001p-16382");
2346+
APFloat NMinQuad(APFloat::IEEEquad(),
2347+
"-0x0.0000000000000000000000000001p-16382");
23412348

23422349
const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
23432350
const int UnderflowStatus = APFloat::opUnderflow | APFloat::opInexact;
23442351

2345-
const unsigned NumTests = 169;
23462352
struct {
23472353
APFloat x;
23482354
APFloat y;
23492355
const char *result;
23502356
int status;
23512357
int category;
2352-
} SpecialCaseTests[NumTests] = {
2358+
APFloat::roundingMode roundingMode = APFloat::rmNearestTiesToEven;
2359+
} SpecialCaseTests[] = {
23532360
{ PInf, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
23542361
{ PInf, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
23552362
{ PInf, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
@@ -2587,15 +2594,70 @@ TEST(APFloatTest, multiply) {
25872594
{ MSmallestNormalized, PSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
25882595
{ MSmallestNormalized, MSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
25892596
{ MSmallestNormalized, PSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2590-
{ MSmallestNormalized, MSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero }
2597+
{ MSmallestNormalized, MSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2598+
2599+
{MaxQuad, MinQuad, "0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,
2600+
APFloat::fcNormal, APFloat::rmNearestTiesToEven},
2601+
{MaxQuad, MinQuad, "0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,
2602+
APFloat::fcNormal, APFloat::rmTowardPositive},
2603+
{MaxQuad, MinQuad, "0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,
2604+
APFloat::fcNormal, APFloat::rmTowardNegative},
2605+
{MaxQuad, MinQuad, "0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,
2606+
APFloat::fcNormal, APFloat::rmTowardZero},
2607+
{MaxQuad, MinQuad, "0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,
2608+
APFloat::fcNormal, APFloat::rmNearestTiesToAway},
2609+
2610+
{MaxQuad, NMinQuad, "-0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,
2611+
APFloat::fcNormal, APFloat::rmNearestTiesToEven},
2612+
{MaxQuad, NMinQuad, "-0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,
2613+
APFloat::fcNormal, APFloat::rmTowardPositive},
2614+
{MaxQuad, NMinQuad, "-0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,
2615+
APFloat::fcNormal, APFloat::rmTowardNegative},
2616+
{MaxQuad, NMinQuad, "-0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,
2617+
APFloat::fcNormal, APFloat::rmTowardZero},
2618+
{MaxQuad, NMinQuad, "-0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,
2619+
APFloat::fcNormal, APFloat::rmNearestTiesToAway},
2620+
2621+
{MaxQuad, MaxQuad, "inf", OverflowStatus, APFloat::fcInfinity,
2622+
APFloat::rmNearestTiesToEven},
2623+
{MaxQuad, MaxQuad, "inf", OverflowStatus, APFloat::fcInfinity,
2624+
APFloat::rmTowardPositive},
2625+
{MaxQuad, MaxQuad, "0x1.ffffffffffffffffffffffffffffp+16383",
2626+
APFloat::opInexact, APFloat::fcNormal, APFloat::rmTowardNegative},
2627+
{MaxQuad, MaxQuad, "0x1.ffffffffffffffffffffffffffffp+16383",
2628+
APFloat::opInexact, APFloat::fcNormal, APFloat::rmTowardZero},
2629+
{MaxQuad, MaxQuad, "inf", OverflowStatus, APFloat::fcInfinity,
2630+
APFloat::rmNearestTiesToAway},
2631+
2632+
{MinQuad, MinQuad, "0", UnderflowStatus, APFloat::fcZero,
2633+
APFloat::rmNearestTiesToEven},
2634+
{MinQuad, MinQuad, "0x0.0000000000000000000000000001p-16382",
2635+
UnderflowStatus, APFloat::fcNormal, APFloat::rmTowardPositive},
2636+
{MinQuad, MinQuad, "0", UnderflowStatus, APFloat::fcZero,
2637+
APFloat::rmTowardNegative},
2638+
{MinQuad, MinQuad, "0", UnderflowStatus, APFloat::fcZero,
2639+
APFloat::rmTowardZero},
2640+
{MinQuad, MinQuad, "0", UnderflowStatus, APFloat::fcZero,
2641+
APFloat::rmNearestTiesToAway},
2642+
2643+
{MinQuad, NMinQuad, "-0", UnderflowStatus, APFloat::fcZero,
2644+
APFloat::rmNearestTiesToEven},
2645+
{MinQuad, NMinQuad, "-0", UnderflowStatus, APFloat::fcZero,
2646+
APFloat::rmTowardPositive},
2647+
{MinQuad, NMinQuad, "-0x0.0000000000000000000000000001p-16382",
2648+
UnderflowStatus, APFloat::fcNormal, APFloat::rmTowardNegative},
2649+
{MinQuad, NMinQuad, "-0", UnderflowStatus, APFloat::fcZero,
2650+
APFloat::rmTowardZero},
2651+
{MinQuad, NMinQuad, "-0", UnderflowStatus, APFloat::fcZero,
2652+
APFloat::rmNearestTiesToAway},
25912653
};
25922654

2593-
for (size_t i = 0; i < NumTests; ++i) {
2655+
for (size_t i = 0; i < array_lengthof(SpecialCaseTests); ++i) {
25942656
APFloat x(SpecialCaseTests[i].x);
25952657
APFloat y(SpecialCaseTests[i].y);
2596-
APFloat::opStatus status = x.multiply(y, APFloat::rmNearestTiesToEven);
2658+
APFloat::opStatus status = x.multiply(y, SpecialCaseTests[i].roundingMode);
25972659

2598-
APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result);
2660+
APFloat result(x.getSemantics(), SpecialCaseTests[i].result);
25992661

26002662
EXPECT_TRUE(result.bitwiseIsEqual(x));
26012663
EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
@@ -2624,21 +2686,28 @@ TEST(APFloatTest, divide) {
26242686
APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
26252687
APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
26262688
APFloat PSmallestNormalized =
2627-
APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
2689+
APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
26282690
APFloat MSmallestNormalized =
2629-
APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
2691+
APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
2692+
2693+
APFloat MaxQuad(APFloat::IEEEquad(),
2694+
"0x1.ffffffffffffffffffffffffffffp+16383");
2695+
APFloat MinQuad(APFloat::IEEEquad(),
2696+
"0x0.0000000000000000000000000001p-16382");
2697+
APFloat NMinQuad(APFloat::IEEEquad(),
2698+
"-0x0.0000000000000000000000000001p-16382");
26302699

26312700
const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
26322701
const int UnderflowStatus = APFloat::opUnderflow | APFloat::opInexact;
26332702

2634-
const unsigned NumTests = 169;
26352703
struct {
26362704
APFloat x;
26372705
APFloat y;
26382706
const char *result;
26392707
int status;
26402708
int category;
2641-
} SpecialCaseTests[NumTests] = {
2709+
APFloat::roundingMode roundingMode = APFloat::rmNearestTiesToEven;
2710+
} SpecialCaseTests[] = {
26422711
{ PInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
26432712
{ PInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
26442713
{ PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
@@ -2877,14 +2946,47 @@ TEST(APFloatTest, divide) {
28772946
{ MSmallestNormalized, MSmallestValue, "0x1p+23", APFloat::opOK, APFloat::fcNormal },
28782947
{ MSmallestNormalized, PSmallestNormalized, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
28792948
{ MSmallestNormalized, MSmallestNormalized, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2949+
2950+
{MaxQuad, NMinQuad, "-inf", OverflowStatus, APFloat::fcInfinity,
2951+
APFloat::rmNearestTiesToEven},
2952+
{MaxQuad, NMinQuad, "-0x1.ffffffffffffffffffffffffffffp+16383",
2953+
APFloat::opInexact, APFloat::fcNormal, APFloat::rmTowardPositive},
2954+
{MaxQuad, NMinQuad, "-inf", OverflowStatus, APFloat::fcInfinity,
2955+
APFloat::rmTowardNegative},
2956+
{MaxQuad, NMinQuad, "-0x1.ffffffffffffffffffffffffffffp+16383",
2957+
APFloat::opInexact, APFloat::fcNormal, APFloat::rmTowardZero},
2958+
{MaxQuad, NMinQuad, "-inf", OverflowStatus, APFloat::fcInfinity,
2959+
APFloat::rmNearestTiesToAway},
2960+
2961+
{MinQuad, MaxQuad, "0", UnderflowStatus, APFloat::fcZero,
2962+
APFloat::rmNearestTiesToEven},
2963+
{MinQuad, MaxQuad, "0x0.0000000000000000000000000001p-16382",
2964+
UnderflowStatus, APFloat::fcNormal, APFloat::rmTowardPositive},
2965+
{MinQuad, MaxQuad, "0", UnderflowStatus, APFloat::fcZero,
2966+
APFloat::rmTowardNegative},
2967+
{MinQuad, MaxQuad, "0", UnderflowStatus, APFloat::fcZero,
2968+
APFloat::rmTowardZero},
2969+
{MinQuad, MaxQuad, "0", UnderflowStatus, APFloat::fcZero,
2970+
APFloat::rmNearestTiesToAway},
2971+
2972+
{NMinQuad, MaxQuad, "-0", UnderflowStatus, APFloat::fcZero,
2973+
APFloat::rmNearestTiesToEven},
2974+
{NMinQuad, MaxQuad, "-0", UnderflowStatus, APFloat::fcZero,
2975+
APFloat::rmTowardPositive},
2976+
{NMinQuad, MaxQuad, "-0x0.0000000000000000000000000001p-16382",
2977+
UnderflowStatus, APFloat::fcNormal, APFloat::rmTowardNegative},
2978+
{NMinQuad, MaxQuad, "-0", UnderflowStatus, APFloat::fcZero,
2979+
APFloat::rmTowardZero},
2980+
{NMinQuad, MaxQuad, "-0", UnderflowStatus, APFloat::fcZero,
2981+
APFloat::rmNearestTiesToAway},
28802982
};
28812983

2882-
for (size_t i = 0; i < NumTests; ++i) {
2984+
for (size_t i = 0; i < array_lengthof(SpecialCaseTests); ++i) {
28832985
APFloat x(SpecialCaseTests[i].x);
28842986
APFloat y(SpecialCaseTests[i].y);
2885-
APFloat::opStatus status = x.divide(y, APFloat::rmNearestTiesToEven);
2987+
APFloat::opStatus status = x.divide(y, SpecialCaseTests[i].roundingMode);
28862988

2887-
APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result);
2989+
APFloat result(x.getSemantics(), SpecialCaseTests[i].result);
28882990

28892991
EXPECT_TRUE(result.bitwiseIsEqual(x));
28902992
EXPECT_TRUE((int)status == SpecialCaseTests[i].status);

0 commit comments

Comments
 (0)