Skip to content

Commit 69f6098

Browse files
committed
APFloat: allow 64-bit of payload
Summary: The APFloat and Constant APIs taking an APInt allow arbitrary payloads, and that's great. There's a convenience API which takes an unsigned, and that's silly because it then directly creates a 64-bit APInt. Just change it to 64-bits directly. At the same time, add ConstantFP NaN getters which match the APFloat ones (with getQNaN / getSNaN and APInt parameters). Improve the APFloat testing to set more payload bits. Reviewers: scanon, rjmccall Subscribers: jkorous, dexonsmith, kristina, llvm-commits Differential Revision: https://reviews.llvm.org/D55460 llvm-svn: 348791
1 parent ce2837f commit 69f6098

File tree

4 files changed

+72
-30
lines changed

4 files changed

+72
-30
lines changed

llvm/include/llvm/ADT/APFloat.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -870,13 +870,13 @@ class APFloat : public APFloatBase {
870870
/// Factory for NaN values.
871871
///
872872
/// \param Negative - True iff the NaN generated should be negative.
873-
/// \param type - The unspecified fill bits for creating the NaN, 0 by
873+
/// \param payload - The unspecified fill bits for creating the NaN, 0 by
874874
/// default. The value is truncated as necessary.
875875
static APFloat getNaN(const fltSemantics &Sem, bool Negative = false,
876-
unsigned type = 0) {
877-
if (type) {
878-
APInt fill(64, type);
879-
return getQNaN(Sem, Negative, &fill);
876+
uint64_t payload = 0) {
877+
if (payload) {
878+
APInt intPayload(64, payload);
879+
return getQNaN(Sem, Negative, &intPayload);
880880
} else {
881881
return getQNaN(Sem, Negative, nullptr);
882882
}

llvm/include/llvm/IR/Constants.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,11 @@ class ConstantFP final : public ConstantData {
290290

291291
static Constant *get(Type* Ty, StringRef Str);
292292
static ConstantFP *get(LLVMContext &Context, const APFloat &V);
293-
static Constant *getNaN(Type *Ty, bool Negative = false, unsigned type = 0);
293+
static Constant *getNaN(Type *Ty, bool Negative = false, uint64_t Payload = 0);
294+
static Constant *getQNaN(Type *Ty, bool Negative = false,
295+
APInt *Payload = nullptr);
296+
static Constant *getSNaN(Type *Ty, bool Negative = false,
297+
APInt *Payload = nullptr);
294298
static Constant *getNegativeZero(Type *Ty);
295299
static Constant *getInfinity(Type *Ty, bool Negative = false);
296300

llvm/lib/IR/Constants.cpp

+24-2
Original file line numberDiff line numberDiff line change
@@ -719,9 +719,9 @@ Constant *ConstantFP::get(Type *Ty, StringRef Str) {
719719
return C;
720720
}
721721

722-
Constant *ConstantFP::getNaN(Type *Ty, bool Negative, unsigned Type) {
722+
Constant *ConstantFP::getNaN(Type *Ty, bool Negative, uint64_t Payload) {
723723
const fltSemantics &Semantics = *TypeToFloatSemantics(Ty->getScalarType());
724-
APFloat NaN = APFloat::getNaN(Semantics, Negative, Type);
724+
APFloat NaN = APFloat::getNaN(Semantics, Negative, Payload);
725725
Constant *C = get(Ty->getContext(), NaN);
726726

727727
if (VectorType *VTy = dyn_cast<VectorType>(Ty))
@@ -730,6 +730,28 @@ Constant *ConstantFP::getNaN(Type *Ty, bool Negative, unsigned Type) {
730730
return C;
731731
}
732732

733+
Constant *ConstantFP::getQNaN(Type *Ty, bool Negative, APInt *Payload) {
734+
const fltSemantics &Semantics = *TypeToFloatSemantics(Ty->getScalarType());
735+
APFloat NaN = APFloat::getQNaN(Semantics, Negative, Payload);
736+
Constant *C = get(Ty->getContext(), NaN);
737+
738+
if (VectorType *VTy = dyn_cast<VectorType>(Ty))
739+
return ConstantVector::getSplat(VTy->getNumElements(), C);
740+
741+
return C;
742+
}
743+
744+
Constant *ConstantFP::getSNaN(Type *Ty, bool Negative, APInt *Payload) {
745+
const fltSemantics &Semantics = *TypeToFloatSemantics(Ty->getScalarType());
746+
APFloat NaN = APFloat::getSNaN(Semantics, Negative, Payload);
747+
Constant *C = get(Ty->getContext(), NaN);
748+
749+
if (VectorType *VTy = dyn_cast<VectorType>(Ty))
750+
return ConstantVector::getSplat(VTy->getNumElements(), C);
751+
752+
return C;
753+
}
754+
733755
Constant *ConstantFP::getNegativeZero(Type *Ty) {
734756
const fltSemantics &Semantics = *TypeToFloatSemantics(Ty->getScalarType());
735757
APFloat NegZero = APFloat::getZero(Semantics, /*Negative=*/true);

llvm/unittests/ADT/APFloatTest.cpp

+38-22
Original file line numberDiff line numberDiff line change
@@ -1070,33 +1070,49 @@ TEST(APFloatTest, toInteger) {
10701070
EXPECT_EQ(APSInt::getMaxValue(5, false), result);
10711071
}
10721072

1073-
static APInt nanbits(const fltSemantics &Sem,
1074-
bool SNaN, bool Negative, uint64_t fill) {
1075-
APInt apfill(64, fill);
1073+
static APInt nanbitsFromAPInt(const fltSemantics &Sem, bool SNaN, bool Negative,
1074+
uint64_t payload) {
1075+
APInt appayload(64, payload);
10761076
if (SNaN)
1077-
return APFloat::getSNaN(Sem, Negative, &apfill).bitcastToAPInt();
1077+
return APFloat::getSNaN(Sem, Negative, &appayload).bitcastToAPInt();
10781078
else
1079-
return APFloat::getQNaN(Sem, Negative, &apfill).bitcastToAPInt();
1079+
return APFloat::getQNaN(Sem, Negative, &appayload).bitcastToAPInt();
10801080
}
10811081

10821082
TEST(APFloatTest, makeNaN) {
1083-
ASSERT_EQ(0x7fc00000, nanbits(APFloat::IEEEsingle(), false, false, 0));
1084-
ASSERT_EQ(0xffc00000, nanbits(APFloat::IEEEsingle(), false, true, 0));
1085-
ASSERT_EQ(0x7fc0ae72, nanbits(APFloat::IEEEsingle(), false, false, 0xae72));
1086-
ASSERT_EQ(0x7fffae72, nanbits(APFloat::IEEEsingle(), false, false, 0xffffae72));
1087-
ASSERT_EQ(0x7fa00000, nanbits(APFloat::IEEEsingle(), true, false, 0));
1088-
ASSERT_EQ(0xffa00000, nanbits(APFloat::IEEEsingle(), true, true, 0));
1089-
ASSERT_EQ(0x7f80ae72, nanbits(APFloat::IEEEsingle(), true, false, 0xae72));
1090-
ASSERT_EQ(0x7fbfae72, nanbits(APFloat::IEEEsingle(), true, false, 0xffffae72));
1091-
1092-
ASSERT_EQ(0x7ff8000000000000ULL, nanbits(APFloat::IEEEdouble(), false, false, 0));
1093-
ASSERT_EQ(0xfff8000000000000ULL, nanbits(APFloat::IEEEdouble(), false, true, 0));
1094-
ASSERT_EQ(0x7ff800000000ae72ULL, nanbits(APFloat::IEEEdouble(), false, false, 0xae72));
1095-
ASSERT_EQ(0x7fffffffffffae72ULL, nanbits(APFloat::IEEEdouble(), false, false, 0xffffffffffffae72ULL));
1096-
ASSERT_EQ(0x7ff4000000000000ULL, nanbits(APFloat::IEEEdouble(), true, false, 0));
1097-
ASSERT_EQ(0xfff4000000000000ULL, nanbits(APFloat::IEEEdouble(), true, true, 0));
1098-
ASSERT_EQ(0x7ff000000000ae72ULL, nanbits(APFloat::IEEEdouble(), true, false, 0xae72));
1099-
ASSERT_EQ(0x7ff7ffffffffae72ULL, nanbits(APFloat::IEEEdouble(), true, false, 0xffffffffffffae72ULL));
1083+
const struct {
1084+
uint64_t expected;
1085+
const fltSemantics &semantics;
1086+
bool SNaN;
1087+
bool Negative;
1088+
uint64_t payload;
1089+
} tests[] = {
1090+
/* expected semantics SNaN Neg payload */
1091+
{ 0x7fc00000ULL, APFloat::IEEEsingle(), false, false, 0x00000000ULL },
1092+
{ 0xffc00000ULL, APFloat::IEEEsingle(), false, true, 0x00000000ULL },
1093+
{ 0x7fc0ae72ULL, APFloat::IEEEsingle(), false, false, 0x0000ae72ULL },
1094+
{ 0x7fffae72ULL, APFloat::IEEEsingle(), false, false, 0xffffae72ULL },
1095+
{ 0x7fdaae72ULL, APFloat::IEEEsingle(), false, false, 0x00daae72ULL },
1096+
{ 0x7fa00000ULL, APFloat::IEEEsingle(), true, false, 0x00000000ULL },
1097+
{ 0xffa00000ULL, APFloat::IEEEsingle(), true, true, 0x00000000ULL },
1098+
{ 0x7f80ae72ULL, APFloat::IEEEsingle(), true, false, 0x0000ae72ULL },
1099+
{ 0x7fbfae72ULL, APFloat::IEEEsingle(), true, false, 0xffffae72ULL },
1100+
{ 0x7f9aae72ULL, APFloat::IEEEsingle(), true, false, 0x001aae72ULL },
1101+
{ 0x7ff8000000000000ULL, APFloat::IEEEdouble(), false, false, 0x0000000000000000ULL },
1102+
{ 0xfff8000000000000ULL, APFloat::IEEEdouble(), false, true, 0x0000000000000000ULL },
1103+
{ 0x7ff800000000ae72ULL, APFloat::IEEEdouble(), false, false, 0x000000000000ae72ULL },
1104+
{ 0x7fffffffffffae72ULL, APFloat::IEEEdouble(), false, false, 0xffffffffffffae72ULL },
1105+
{ 0x7ffdaaaaaaaaae72ULL, APFloat::IEEEdouble(), false, false, 0x000daaaaaaaaae72ULL },
1106+
{ 0x7ff4000000000000ULL, APFloat::IEEEdouble(), true, false, 0x0000000000000000ULL },
1107+
{ 0xfff4000000000000ULL, APFloat::IEEEdouble(), true, true, 0x0000000000000000ULL },
1108+
{ 0x7ff000000000ae72ULL, APFloat::IEEEdouble(), true, false, 0x000000000000ae72ULL },
1109+
{ 0x7ff7ffffffffae72ULL, APFloat::IEEEdouble(), true, false, 0xffffffffffffae72ULL },
1110+
{ 0x7ff1aaaaaaaaae72ULL, APFloat::IEEEdouble(), true, false, 0x0001aaaaaaaaae72ULL },
1111+
};
1112+
1113+
for (const auto &t : tests) {
1114+
ASSERT_EQ(t.expected, nanbitsFromAPInt(t.semantics, t.SNaN, t.Negative, t.payload));
1115+
}
11001116
}
11011117

11021118
#ifdef GTEST_HAS_DEATH_TEST

0 commit comments

Comments
 (0)