[llvm] [APFloat] add power (PR #122889)
Iman Hosseini via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 16 04:30:30 PST 2025
https://github.com/ImanHosseini updated https://github.com/llvm/llvm-project/pull/122889
>From 10da74e43550f58760ed899282cb4d1002ff6070 Mon Sep 17 00:00:00 2001
From: ImanHosseini <imanhosseini.17 at gmail.com>
Date: Tue, 14 Jan 2025 11:35:31 +0000
Subject: [PATCH 01/10] add apfloat power
---
llvm/include/llvm/ADT/APFloat.h | 21 +++++++++++++++++++++
llvm/unittests/ADT/APFloatTest.cpp | 15 +++++++++++++++
2 files changed, 36 insertions(+)
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index 9792749230cbf9..803949cf9abcbf 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -1536,6 +1536,27 @@ inline APFloat abs(APFloat X) {
return X;
}
+/// Returns X^N for N >= 0.
+/// Returns X^N for N >= 0.
+inline APFloat pow(const APFloat &X, const int &N) {
+ assert(N >= 0 && "negative exponents not supported.");
+ APFloat Acc = APFloat::getOne(X.getSemantics());
+ if (N == 0) {
+ return APFloat::getOne(X.getSemantics());
+ }
+ APFloat Base = X;
+ int64_t RemainingExponent = N;
+ while (RemainingExponent > 0) {
+ while (RemainingExponent % 2 == 0) {
+ Base = Base * Base;
+ RemainingExponent /= 2;
+ }
+ --RemainingExponent;
+ Acc = Acc * Base;
+ }
+ return Acc;
+};
+
/// Returns the negated value of the argument.
inline APFloat neg(APFloat X) {
X.changeSign();
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index f291c814886d35..0e4fe151af10af 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -3793,6 +3793,21 @@ TEST(APFloatTest, abs) {
EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(MSmallestNormalized)));
}
+TEST(APFloatTest, pow) {
+ APFloat One = APFloat(APFloat::IEEEsingle(), "1.0");
+ APFloat Two = APFloat(APFloat::IEEEsingle(), "2.0");
+ APFloat Four = APFloat(APFloat::IEEEsingle(), "4.0");
+ APFloat Eight = APFloat(APFloat::IEEEsingle(), "8.0");
+ APFloat NegTwo = APFloat(APFloat::IEEEsingle(), "-2.0");
+ APFloat NegEight = APFloat(APFloat::IEEEsingle(), "-8.0");
+
+ EXPECT_TRUE(One.bitwiseIsEqual(pow(One, 0)));
+ EXPECT_TRUE(One.bitwiseIsEqual(pow(One, 3)));
+ EXPECT_TRUE(Four.bitwiseIsEqual(pow(Two, 2)));
+ EXPECT_TRUE(Eight.bitwiseIsEqual(pow(Two, 3)));
+ EXPECT_TRUE(NegEight.bitwiseIsEqual(pow(NegTwo, 3)));
+}
+
TEST(APFloatTest, neg) {
APFloat One = APFloat(APFloat::IEEEsingle(), "1.0");
APFloat NegOne = APFloat(APFloat::IEEEsingle(), "-1.0");
>From eb093a1b06402fbdfe89769aa7ea1caee7c9a4e9 Mon Sep 17 00:00:00 2001
From: ImanHosseini <imanhosseini.17 at gmail.com>
Date: Tue, 14 Jan 2025 12:58:19 +0000
Subject: [PATCH 02/10] rmv extra ;
---
llvm/include/llvm/ADT/APFloat.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index 803949cf9abcbf..eeace70dfad29f 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -1555,7 +1555,7 @@ inline APFloat pow(const APFloat &X, const int &N) {
Acc = Acc * Base;
}
return Acc;
-};
+}
/// Returns the negated value of the argument.
inline APFloat neg(APFloat X) {
>From 38468c983bbd6047dd842dc3d5d5550a198e736d Mon Sep 17 00:00:00 2001
From: ImanHosseini <imanhosseini.17 at gmail.com>
Date: Tue, 14 Jan 2025 15:34:38 +0000
Subject: [PATCH 03/10] N -> int64_t to be similar to APInt pow
---
llvm/include/llvm/ADT/APFloat.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index eeace70dfad29f..6b669eca6f82b5 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -1537,8 +1537,7 @@ inline APFloat abs(APFloat X) {
}
/// Returns X^N for N >= 0.
-/// Returns X^N for N >= 0.
-inline APFloat pow(const APFloat &X, const int &N) {
+inline APFloat pow(const APFloat &X, int64_t N) {
assert(N >= 0 && "negative exponents not supported.");
APFloat Acc = APFloat::getOne(X.getSemantics());
if (N == 0) {
>From eb07e2aa0d3f95d2c7fce624df597a62d0c61721 Mon Sep 17 00:00:00 2001
From: ImanHosseini <imanhosseini.17 at gmail.com>
Date: Tue, 14 Jan 2025 22:13:26 +0000
Subject: [PATCH 04/10] rename to `powi`.
---
llvm/include/llvm/ADT/APFloat.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index 6b669eca6f82b5..ad1e37b1c0c22d 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -1537,11 +1537,11 @@ inline APFloat abs(APFloat X) {
}
/// Returns X^N for N >= 0.
-inline APFloat pow(const APFloat &X, int64_t N) {
+inline APFloat powi(const APFloat &X, int64_t N) {
assert(N >= 0 && "negative exponents not supported.");
APFloat Acc = APFloat::getOne(X.getSemantics());
if (N == 0) {
- return APFloat::getOne(X.getSemantics());
+ return Acc;
}
APFloat Base = X;
int64_t RemainingExponent = N;
>From 09ad4eb4a40a69b8b1d3dec6f1b0bc92bdcf95d8 Mon Sep 17 00:00:00 2001
From: ImanHosseini <imanhosseini.17 at gmail.com>
Date: Wed, 15 Jan 2025 18:32:25 +0000
Subject: [PATCH 05/10] add more tests
---
llvm/unittests/ADT/APFloatTest.cpp | 39 ++++++++++++++++++++++++------
1 file changed, 31 insertions(+), 8 deletions(-)
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index 0e4fe151af10af..b85ba0eb88df6c 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -3793,19 +3793,42 @@ TEST(APFloatTest, abs) {
EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(MSmallestNormalized)));
}
-TEST(APFloatTest, pow) {
- APFloat One = APFloat(APFloat::IEEEsingle(), "1.0");
+TEST(APFloatTest, powi) {
+ APFloat One = APFloat::getOne(APFloat::IEEEsingle(), false);
APFloat Two = APFloat(APFloat::IEEEsingle(), "2.0");
APFloat Four = APFloat(APFloat::IEEEsingle(), "4.0");
APFloat Eight = APFloat(APFloat::IEEEsingle(), "8.0");
APFloat NegTwo = APFloat(APFloat::IEEEsingle(), "-2.0");
APFloat NegEight = APFloat(APFloat::IEEEsingle(), "-8.0");
-
- EXPECT_TRUE(One.bitwiseIsEqual(pow(One, 0)));
- EXPECT_TRUE(One.bitwiseIsEqual(pow(One, 3)));
- EXPECT_TRUE(Four.bitwiseIsEqual(pow(Two, 2)));
- EXPECT_TRUE(Eight.bitwiseIsEqual(pow(Two, 3)));
- EXPECT_TRUE(NegEight.bitwiseIsEqual(pow(NegTwo, 3)));
+ APFloat PosInf = APFloat::getInf(APFloat::IEEEsingle(), false);
+ APFloat NegInf = APFloat::getInf(APFloat::IEEEsingle(), true);
+ APFloat PosZero = APFloat::getZero(APFloat::IEEEsingle(), false);
+ APFloat NegZero = APFloat::getZero(APFloat::IEEEsingle(), true);
+ APFloat PosQNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
+ APFloat NegQNaN = APFloat::getNaN(APFloat::IEEEsingle(), true);
+ APFloat PosSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
+ APFloat NegSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), true);
+
+ EXPECT_TRUE(One.bitwiseIsEqual(powi(One, 0)));
+ EXPECT_TRUE(One.bitwiseIsEqual(powi(One, 3)));
+ EXPECT_TRUE(Four.bitwiseIsEqual(powi(Two, 2)));
+ EXPECT_TRUE(Eight.bitwiseIsEqual(powi(Two, 3)));
+
+ // See page 63 of IEEE 754-2019.
+ EXPECT_TRUE(One.bitwiseIsEqual(powi(PosInf, 0)));
+ EXPECT_TRUE(NegEight.bitwiseIsEqual(powi(NegTwo, 3)));
+ EXPECT_TRUE(PosZero.bitwiseIsEqual(powi(PosZero, 3)));
+ EXPECT_TRUE(NegZero.bitwiseIsEqual(powi(NegZero, 5)));
+ EXPECT_TRUE(PosZero.bitwiseIsEqual(powi(NegZero, 6)));
+ EXPECT_TRUE(NegInf.bitwiseIsEqual(powi(NegInf, 3)));
+ EXPECT_TRUE(PosInf.bitwiseIsEqual(powi(NegInf, 4)));
+ EXPECT_TRUE(PosInf.bitwiseIsEqual(powi(PosInf, 3)));
+
+ EXPECT_TRUE(PosQNaN.bitwiseIsEqual(powi(PosQNaN, 1)));
+ EXPECT_TRUE(NegQNaN.bitwiseIsEqual(powi(NegQNaN, 1)));
+ // Check signaling NaN is quieted for n == 1.
+ EXPECT_TRUE(PosQNaN.bitwiseIsEqual(powi(PosSNaN, 1)));
+ EXPECT_TRUE(NegSNaN.bitwiseIsEqual(powi(NegSNaN, 1)));
}
TEST(APFloatTest, neg) {
>From 8f6da4e6352e4416d53c334f228225cf22ef7b6d Mon Sep 17 00:00:00 2001
From: ImanHosseini <imanhosseini.17 at gmail.com>
Date: Wed, 15 Jan 2025 18:35:59 +0000
Subject: [PATCH 06/10] sink.
---
llvm/include/llvm/ADT/APFloat.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index ad1e37b1c0c22d..a07f637b384a8b 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -1538,11 +1538,11 @@ inline APFloat abs(APFloat X) {
/// Returns X^N for N >= 0.
inline APFloat powi(const APFloat &X, int64_t N) {
- assert(N >= 0 && "negative exponents not supported.");
APFloat Acc = APFloat::getOne(X.getSemantics());
if (N == 0) {
return Acc;
}
+ assert(N >= 0 && "negative exponents not supported.");
APFloat Base = X;
int64_t RemainingExponent = N;
while (RemainingExponent > 0) {
>From 7ce49552843c9c523a3f404c34c4e7efb8c74c02 Mon Sep 17 00:00:00 2001
From: ImanHosseini <imanhosseini.17 at gmail.com>
Date: Wed, 15 Jan 2025 19:03:46 +0000
Subject: [PATCH 07/10] canonicalize? +payload.
---
llvm/include/llvm/ADT/APFloat.h | 3 +++
llvm/unittests/ADT/APFloatTest.cpp | 12 +++++++-----
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index a07f637b384a8b..99d2f6467039a9 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -1542,6 +1542,9 @@ inline APFloat powi(const APFloat &X, int64_t N) {
if (N == 0) {
return Acc;
}
+ if (N == 1) {
+ return X.isNaN() ? X.makeQuiet() : X;
+ }
assert(N >= 0 && "negative exponents not supported.");
APFloat Base = X;
int64_t RemainingExponent = N;
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index b85ba0eb88df6c..970f41e0088caf 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -3804,11 +3804,13 @@ TEST(APFloatTest, powi) {
APFloat NegInf = APFloat::getInf(APFloat::IEEEsingle(), true);
APFloat PosZero = APFloat::getZero(APFloat::IEEEsingle(), false);
APFloat NegZero = APFloat::getZero(APFloat::IEEEsingle(), true);
- APFloat PosQNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
- APFloat NegQNaN = APFloat::getNaN(APFloat::IEEEsingle(), true);
- APFloat PosSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
- APFloat NegSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), true);
+ APFloat PosQNaN = APFloat::getNaN(APFloat::IEEEsingle(), false, 0x1337);
+ APFloat NegQNaN = APFloat::getNaN(APFloat::IEEEsingle(), true, 0x1337);
+ APInt Payload(64, 0x1337);
+ APFloat PosSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false, &Payload);
+ APFloat NegSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), true, &Payload);
+ // Simple cases.
EXPECT_TRUE(One.bitwiseIsEqual(powi(One, 0)));
EXPECT_TRUE(One.bitwiseIsEqual(powi(One, 3)));
EXPECT_TRUE(Four.bitwiseIsEqual(powi(Two, 2)));
@@ -3828,7 +3830,7 @@ TEST(APFloatTest, powi) {
EXPECT_TRUE(NegQNaN.bitwiseIsEqual(powi(NegQNaN, 1)));
// Check signaling NaN is quieted for n == 1.
EXPECT_TRUE(PosQNaN.bitwiseIsEqual(powi(PosSNaN, 1)));
- EXPECT_TRUE(NegSNaN.bitwiseIsEqual(powi(NegSNaN, 1)));
+ EXPECT_TRUE(NegQNaN.bitwiseIsEqual(powi(NegSNaN, 1)));
}
TEST(APFloatTest, neg) {
>From 35beb61e31785917d7b0b2c03fc798935b135ab8 Mon Sep 17 00:00:00 2001
From: ImanHosseini <imanhosseini.17 at gmail.com>
Date: Wed, 15 Jan 2025 19:05:22 +0000
Subject: [PATCH 08/10] fmt.
---
llvm/unittests/ADT/APFloatTest.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index 970f41e0088caf..851dd2740a71af 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -3809,13 +3809,13 @@ TEST(APFloatTest, powi) {
APInt Payload(64, 0x1337);
APFloat PosSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false, &Payload);
APFloat NegSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), true, &Payload);
-
+
// Simple cases.
EXPECT_TRUE(One.bitwiseIsEqual(powi(One, 0)));
EXPECT_TRUE(One.bitwiseIsEqual(powi(One, 3)));
EXPECT_TRUE(Four.bitwiseIsEqual(powi(Two, 2)));
EXPECT_TRUE(Eight.bitwiseIsEqual(powi(Two, 3)));
-
+
// See page 63 of IEEE 754-2019.
EXPECT_TRUE(One.bitwiseIsEqual(powi(PosInf, 0)));
EXPECT_TRUE(NegEight.bitwiseIsEqual(powi(NegTwo, 3)));
@@ -3825,7 +3825,7 @@ TEST(APFloatTest, powi) {
EXPECT_TRUE(NegInf.bitwiseIsEqual(powi(NegInf, 3)));
EXPECT_TRUE(PosInf.bitwiseIsEqual(powi(NegInf, 4)));
EXPECT_TRUE(PosInf.bitwiseIsEqual(powi(PosInf, 3)));
-
+
EXPECT_TRUE(PosQNaN.bitwiseIsEqual(powi(PosQNaN, 1)));
EXPECT_TRUE(NegQNaN.bitwiseIsEqual(powi(NegQNaN, 1)));
// Check signaling NaN is quieted for n == 1.
>From b13601ba70be343e36b0d44bf953b554ca751f77 Mon Sep 17 00:00:00 2001
From: ImanHosseini <imanhosseini.17 at gmail.com>
Date: Wed, 15 Jan 2025 19:15:20 +0000
Subject: [PATCH 09/10] more tests
---
llvm/unittests/ADT/APFloatTest.cpp | 34 +++++++++++++++++++++++-------
1 file changed, 26 insertions(+), 8 deletions(-)
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index 851dd2740a71af..83d1c25edeea50 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -3794,12 +3794,20 @@ TEST(APFloatTest, abs) {
}
TEST(APFloatTest, powi) {
+ // Simple cases.
APFloat One = APFloat::getOne(APFloat::IEEEsingle(), false);
APFloat Two = APFloat(APFloat::IEEEsingle(), "2.0");
+ APFloat NegTwo = APFloat(APFloat::IEEEsingle(), "-2.0");
APFloat Four = APFloat(APFloat::IEEEsingle(), "4.0");
APFloat Eight = APFloat(APFloat::IEEEsingle(), "8.0");
- APFloat NegTwo = APFloat(APFloat::IEEEsingle(), "-2.0");
APFloat NegEight = APFloat(APFloat::IEEEsingle(), "-8.0");
+
+ EXPECT_TRUE(One.bitwiseIsEqual(powi(One, 0)));
+ EXPECT_TRUE(One.bitwiseIsEqual(powi(One, 3)));
+ EXPECT_TRUE(Four.bitwiseIsEqual(powi(Two, 2)));
+ EXPECT_TRUE(Eight.bitwiseIsEqual(powi(Two, 3)));
+
+ // See page 63 of IEEE 754-2019.
APFloat PosInf = APFloat::getInf(APFloat::IEEEsingle(), false);
APFloat NegInf = APFloat::getInf(APFloat::IEEEsingle(), true);
APFloat PosZero = APFloat::getZero(APFloat::IEEEsingle(), false);
@@ -3810,13 +3818,6 @@ TEST(APFloatTest, powi) {
APFloat PosSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false, &Payload);
APFloat NegSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), true, &Payload);
- // Simple cases.
- EXPECT_TRUE(One.bitwiseIsEqual(powi(One, 0)));
- EXPECT_TRUE(One.bitwiseIsEqual(powi(One, 3)));
- EXPECT_TRUE(Four.bitwiseIsEqual(powi(Two, 2)));
- EXPECT_TRUE(Eight.bitwiseIsEqual(powi(Two, 3)));
-
- // See page 63 of IEEE 754-2019.
EXPECT_TRUE(One.bitwiseIsEqual(powi(PosInf, 0)));
EXPECT_TRUE(NegEight.bitwiseIsEqual(powi(NegTwo, 3)));
EXPECT_TRUE(PosZero.bitwiseIsEqual(powi(PosZero, 3)));
@@ -3826,11 +3827,28 @@ TEST(APFloatTest, powi) {
EXPECT_TRUE(PosInf.bitwiseIsEqual(powi(NegInf, 4)));
EXPECT_TRUE(PosInf.bitwiseIsEqual(powi(PosInf, 3)));
+ // Nans
EXPECT_TRUE(PosQNaN.bitwiseIsEqual(powi(PosQNaN, 1)));
EXPECT_TRUE(NegQNaN.bitwiseIsEqual(powi(NegQNaN, 1)));
// Check signaling NaN is quieted for n == 1.
EXPECT_TRUE(PosQNaN.bitwiseIsEqual(powi(PosSNaN, 1)));
EXPECT_TRUE(NegQNaN.bitwiseIsEqual(powi(NegSNaN, 1)));
+
+ APFloat LargestDenormalF64(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023");
+ APFloat NegLargestDenormalF64(APFloat::IEEEdouble(),
+ "-0x1.ffffffffffffep-1023");
+ APFloat Smallest = APFloat::getSmallest(APFloat::IEEEsingle(), false);
+ APFloat NegSmallest = APFloat::getSmallest(APFloat::IEEEsingle(), true);
+ APFloat Largest = APFloat::getLargest(APFloat::IEEEsingle(), false);
+ APFloat NegLargest = APFloat::getLargest(APFloat::IEEEsingle(), true);
+
+ EXPECT_TRUE(LargestDenormalF64.bitwiseIsEqual(powi(LargestDenormalF64, 1)));
+ EXPECT_TRUE(
+ NegLargestDenormalF64.bitwiseIsEqual(powi(NegLargestDenormalF64, 1)));
+ EXPECT_TRUE(Smallest.bitwiseIsEqual(powi(Smallest, 1)));
+ EXPECT_TRUE(NegSmallest.bitwiseIsEqual(powi(NegSmallest, 1)));
+ EXPECT_TRUE(Largest.bitwiseIsEqual(powi(Largest, 1)));
+ EXPECT_TRUE(NegLargest.bitwiseIsEqual(powi(NegLargest, 1)));
}
TEST(APFloatTest, neg) {
>From 33beb563e0fcd5cbe6f5c52632851fbeb63bfe42 Mon Sep 17 00:00:00 2001
From: ImanHosseini <imanhosseini.17 at gmail.com>
Date: Thu, 16 Jan 2025 12:30:04 +0000
Subject: [PATCH 10/10] test smallest ^ 2
---
llvm/include/llvm/ADT/APFloat.h | 3 ---
llvm/unittests/ADT/APFloatTest.cpp | 23 ++++++++++++++---------
2 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index 99d2f6467039a9..a07f637b384a8b 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -1542,9 +1542,6 @@ inline APFloat powi(const APFloat &X, int64_t N) {
if (N == 0) {
return Acc;
}
- if (N == 1) {
- return X.isNaN() ? X.makeQuiet() : X;
- }
assert(N >= 0 && "negative exponents not supported.");
APFloat Base = X;
int64_t RemainingExponent = N;
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index 83d1c25edeea50..c4132addcabefb 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -3794,6 +3794,7 @@ TEST(APFloatTest, abs) {
}
TEST(APFloatTest, powi) {
+
// Simple cases.
APFloat One = APFloat::getOne(APFloat::IEEEsingle(), false);
APFloat Two = APFloat(APFloat::IEEEsingle(), "2.0");
@@ -3801,12 +3802,12 @@ TEST(APFloatTest, powi) {
APFloat Four = APFloat(APFloat::IEEEsingle(), "4.0");
APFloat Eight = APFloat(APFloat::IEEEsingle(), "8.0");
APFloat NegEight = APFloat(APFloat::IEEEsingle(), "-8.0");
-
+
EXPECT_TRUE(One.bitwiseIsEqual(powi(One, 0)));
EXPECT_TRUE(One.bitwiseIsEqual(powi(One, 3)));
EXPECT_TRUE(Four.bitwiseIsEqual(powi(Two, 2)));
EXPECT_TRUE(Eight.bitwiseIsEqual(powi(Two, 3)));
-
+
// See page 63 of IEEE 754-2019.
APFloat PosInf = APFloat::getInf(APFloat::IEEEsingle(), false);
APFloat NegInf = APFloat::getInf(APFloat::IEEEsingle(), true);
@@ -3817,7 +3818,7 @@ TEST(APFloatTest, powi) {
APInt Payload(64, 0x1337);
APFloat PosSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false, &Payload);
APFloat NegSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), true, &Payload);
-
+
EXPECT_TRUE(One.bitwiseIsEqual(powi(PosInf, 0)));
EXPECT_TRUE(NegEight.bitwiseIsEqual(powi(NegTwo, 3)));
EXPECT_TRUE(PosZero.bitwiseIsEqual(powi(PosZero, 3)));
@@ -3826,7 +3827,7 @@ TEST(APFloatTest, powi) {
EXPECT_TRUE(NegInf.bitwiseIsEqual(powi(NegInf, 3)));
EXPECT_TRUE(PosInf.bitwiseIsEqual(powi(NegInf, 4)));
EXPECT_TRUE(PosInf.bitwiseIsEqual(powi(PosInf, 3)));
-
+
// Nans
EXPECT_TRUE(PosQNaN.bitwiseIsEqual(powi(PosQNaN, 1)));
EXPECT_TRUE(NegQNaN.bitwiseIsEqual(powi(NegQNaN, 1)));
@@ -3835,20 +3836,24 @@ TEST(APFloatTest, powi) {
EXPECT_TRUE(NegQNaN.bitwiseIsEqual(powi(NegSNaN, 1)));
APFloat LargestDenormalF64(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023");
- APFloat NegLargestDenormalF64(APFloat::IEEEdouble(),
- "-0x1.ffffffffffffep-1023");
+ APFloat NegLargestDenormalF64(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1023");
APFloat Smallest = APFloat::getSmallest(APFloat::IEEEsingle(), false);
APFloat NegSmallest = APFloat::getSmallest(APFloat::IEEEsingle(), true);
APFloat Largest = APFloat::getLargest(APFloat::IEEEsingle(), false);
APFloat NegLargest = APFloat::getLargest(APFloat::IEEEsingle(), true);
-
+
EXPECT_TRUE(LargestDenormalF64.bitwiseIsEqual(powi(LargestDenormalF64, 1)));
- EXPECT_TRUE(
- NegLargestDenormalF64.bitwiseIsEqual(powi(NegLargestDenormalF64, 1)));
+ EXPECT_TRUE(NegLargestDenormalF64.bitwiseIsEqual(powi(NegLargestDenormalF64, 1)));
EXPECT_TRUE(Smallest.bitwiseIsEqual(powi(Smallest, 1)));
EXPECT_TRUE(NegSmallest.bitwiseIsEqual(powi(NegSmallest, 1)));
EXPECT_TRUE(Largest.bitwiseIsEqual(powi(Largest, 1)));
EXPECT_TRUE(NegLargest.bitwiseIsEqual(powi(NegLargest, 1)));
+
+ EXPECT_TRUE(PosZero.bitwiseIsEqual(powi(Smallest, 2)));
+ EXPECT_TRUE(NegZero.bitwiseIsEqual(powi(NegSmallest, 3)));
+ EXPECT_TRUE(powi(Largest, 2).isInfinity());
+ EXPECT_TRUE(powi(NegLargest, 2).isInfinity());
+ EXPECT_TRUE(powi(NegLargest, 3).isNegative());
}
TEST(APFloatTest, neg) {
More information about the llvm-commits
mailing list