[llvm] [APFloat] add power (PR #122889)

Iman Hosseini via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 17 07:24:35 PST 2025


================
@@ -3793,6 +3793,71 @@ TEST(APFloatTest, abs) {
   EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(MSmallestNormalized)));
 }
 
+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 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);
+  APFloat NegZero = APFloat::getZero(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);
+
+  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)));
+
+  // 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)));
----------------
ImanHosseini wrote:

https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005fpowi 
This is not named `pown`, and we aren't committing to any precision or rounding guarantee. Same as with gcc's `powi`, we can maybe explicitly state it that this function does not come with a rounding guarantee?

https://github.com/llvm/llvm-project/pull/122889


More information about the llvm-commits mailing list