[llvm] [ConstantFolding] Add constant folding support for nextafter/nexttoward (PR #167324)
Jakub Kuderski via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 11 08:38:56 PST 2025
================
@@ -10182,4 +10182,113 @@ TEST(APFloatTest, FrexpQuietSNaN) {
EXPECT_FALSE(Result.isSignaling());
}
+TEST(APFloatTest, getPromoted) {
+ // Strengthening promotions are allowed.
+ bool LosesInfo = false;
+ APFloat ValidPromotionTest(1.0f);
+ APFloat FloatVal = ValidPromotionTest.getPromoted(APFloat::IEEEsingle());
+ APFloat DoubleVal = ValidPromotionTest.getPromoted(APFloat::IEEEdouble());
+ APFloat QuadVal = ValidPromotionTest.getPromoted(APFloat::IEEEquad());
+ APFloat X87DoubleVal =
+ ValidPromotionTest.getPromoted(APFloat::x87DoubleExtended());
+ APFloat PPCDoubleDoubleVal =
+ ValidPromotionTest.getPromoted(APFloat::PPCDoubleDoubleLegacy());
+
+ // Trivial promotions to the same semantics are allowed.
+ FloatVal.getPromoted(FloatVal.getSemantics());
+ DoubleVal.getPromoted(DoubleVal.getSemantics());
+ QuadVal.getPromoted(QuadVal.getSemantics());
+ X87DoubleVal.getPromoted(X87DoubleVal.getSemantics());
+ PPCDoubleDoubleVal.getPromoted(PPCDoubleDoubleVal.getSemantics());
+
+ // Promotions have the expected semantics.
+ EXPECT_EQ(&FloatVal.getSemantics(), &APFloat::IEEEsingle());
+ EXPECT_EQ(&DoubleVal.getSemantics(), &APFloat::IEEEdouble());
+ EXPECT_EQ(&QuadVal.getSemantics(), &APFloat::IEEEquad());
+ EXPECT_EQ(&X87DoubleVal.getSemantics(), &APFloat::x87DoubleExtended());
+ EXPECT_EQ(&PPCDoubleDoubleVal.getSemantics(),
+ &APFloat::PPCDoubleDoubleLegacy());
+
+ // Promotions preserve the initial value.
+ QuadVal.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
+ &LosesInfo);
+ EXPECT_FALSE(LosesInfo);
+ X87DoubleVal.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
+ &LosesInfo);
+ EXPECT_FALSE(LosesInfo);
+ PPCDoubleDoubleVal.convert(APFloat::IEEEdouble(),
+ APFloat::rmNearestTiesToEven, &LosesInfo);
+ EXPECT_FALSE(LosesInfo);
+ EXPECT_EQ(1.0, FloatVal.convertToFloat());
+ EXPECT_EQ(1.0, DoubleVal.convertToDouble());
+ EXPECT_EQ(1.0, QuadVal.convertToDouble());
+ EXPECT_EQ(1.0, X87DoubleVal.convertToDouble());
+ EXPECT_EQ(1.0, PPCDoubleDoubleVal.convertToDouble());
+
+ // All invalid promotions are swiftly killed.
+ APFloat InvalidPromotionTest(1.0f);
+ EXPECT_DEATH(InvalidPromotionTest.getPromoted(APFloat::IEEEhalf()),
+ "Target semantics will lose information");
+ EXPECT_DEATH(InvalidPromotionTest.getPromoted(APFloat::BFloat()),
+ "Target semantics will lose information.");
+
+ APFloat InvalidPromotionDoubleTest =
+ InvalidPromotionTest.getPromoted(APFloat::IEEEdouble());
+ EXPECT_DEATH(InvalidPromotionDoubleTest.getPromoted(APFloat::BFloat()),
+ "Target semantics will lose information.");
+ EXPECT_DEATH(InvalidPromotionDoubleTest.getPromoted(APFloat::IEEEsingle()),
+ "Target semantics will lose information");
+ EXPECT_DEATH(InvalidPromotionDoubleTest.getPromoted(APFloat::IEEEhalf()),
+ "Target semantics will lose information");
+
+ APFloat InvalidPromotionQuadTest =
+ InvalidPromotionTest.getPromoted(APFloat::IEEEquad());
+ EXPECT_DEATH(InvalidPromotionQuadTest.getPromoted(APFloat::BFloat()),
+ "Target semantics will lose information.");
+ EXPECT_DEATH(InvalidPromotionQuadTest.getPromoted(APFloat::IEEEsingle()),
+ "Target semantics will lose information");
+ EXPECT_DEATH(InvalidPromotionQuadTest.getPromoted(APFloat::IEEEhalf()),
+ "Target semantics will lose information");
+ EXPECT_DEATH(InvalidPromotionQuadTest.getPromoted(APFloat::IEEEdouble()),
+ "Target semantics will lose information");
+ EXPECT_DEATH(
+ InvalidPromotionQuadTest.getPromoted(APFloat::x87DoubleExtended()),
+ "Target semantics will lose information");
+ EXPECT_DEATH(
+ InvalidPromotionQuadTest.getPromoted(APFloat::PPCDoubleDoubleLegacy()),
+ "Target semantics will lose information");
+
+ APFloat InvalidPromotionX87Test =
+ InvalidPromotionTest.getPromoted(APFloat::x87DoubleExtended());
+ EXPECT_DEATH(InvalidPromotionX87Test.getPromoted(APFloat::BFloat()),
+ "Target semantics will lose information.");
+ EXPECT_DEATH(InvalidPromotionX87Test.getPromoted(APFloat::IEEEsingle()),
+ "Target semantics will lose information");
+ EXPECT_DEATH(InvalidPromotionX87Test.getPromoted(APFloat::IEEEhalf()),
+ "Target semantics will lose information");
+ EXPECT_DEATH(InvalidPromotionX87Test.getPromoted(APFloat::IEEEdouble()),
+ "Target semantics will lose information");
+ EXPECT_DEATH(
+ InvalidPromotionX87Test.getPromoted(APFloat::PPCDoubleDoubleLegacy()),
+ "Target semantics will lose information");
+
+ APFloat InvalidPromotionPPCDoubleDoubleTest =
+ InvalidPromotionTest.getPromoted(APFloat::PPCDoubleDoubleLegacy());
+ EXPECT_DEATH(
+ InvalidPromotionPPCDoubleDoubleTest.getPromoted(APFloat::BFloat()),
+ "Target semantics will lose information.");
+ EXPECT_DEATH(
+ InvalidPromotionPPCDoubleDoubleTest.getPromoted(APFloat::IEEEsingle()),
+ "Target semantics will lose information");
+ EXPECT_DEATH(
+ InvalidPromotionPPCDoubleDoubleTest.getPromoted(APFloat::IEEEhalf()),
+ "Target semantics will lose information");
+ EXPECT_DEATH(
+ InvalidPromotionPPCDoubleDoubleTest.getPromoted(APFloat::IEEEdouble()),
+ "Target semantics will lose information");
+ EXPECT_DEATH(InvalidPromotionPPCDoubleDoubleTest.getPromoted(
+ APFloat::x87DoubleExtended()),
+ "Target semantics will lose information");
----------------
kuhar wrote:
EXPECT_DEATH tests are usually surrounded with ifdefs -- you can find existing examples in the codebase.
We shouldn't add more than a couple of EXPECT_DEATH checks -- each will result in a `fork` which slows down tests a lot.
https://github.com/llvm/llvm-project/pull/167324
More information about the llvm-commits
mailing list