[llvm] [ConstantFolding] Constant fold nextafter and nexttoward (PR #168794)
Sayan Sivakumaran via llvm-commits
llvm-commits at lists.llvm.org
Sun Nov 23 10:00:47 PST 2025
================
@@ -3174,6 +3176,53 @@ static Constant *evaluateCompare(const APFloat &Op1, const APFloat &Op2,
return nullptr;
}
+/// Returns the first NaN in the operand list if it exists, preserving the NaN
+/// payload if possible. Returns nullptr if no NaNs are in the list.
+static Constant *TryConstantFoldNaN(ArrayRef<APFloat> Operands,
+ const Type *RetTy) {
+ assert(RetTy != nullptr);
+ for (const APFloat &Op : Operands) {
+ if (Op.isNaN()) {
+ bool Unused;
+ APFloat Ret(Op);
+ Ret.convert(RetTy->getFltSemantics(), detail::rmNearestTiesToEven,
+ &Unused);
+ return ConstantFP::get(RetTy->getContext(), Ret);
+ }
+ }
+ return nullptr;
+}
+
+static Constant *ConstantFoldNextToward(const APFloat &Op0, const APFloat &Op1,
+ const Type *RetTy,
+ bool *WouldSetErrno) {
+ assert(RetTy != nullptr);
+ *WouldSetErrno = false;
+
+ Constant *RetNaN = TryConstantFoldNaN({Op0, Op1}, RetTy);
+ if (RetNaN != nullptr) {
+ return RetNaN;
+ }
+
+ // Recall that the second argument of nexttoward is always a long double,
+ // so we may need to promote the first argument for comparisons to be valid.
+ bool LosesInfo;
+ APFloat PromotedOp0(Op0);
+ PromotedOp0.convert(Op1.getSemantics(), detail::rmNearestTiesToEven,
+ &LosesInfo);
+ assert(!LosesInfo && "Unexpected lossy promotion");
+
+ if (PromotedOp0 == Op1)
----------------
sivakusayan wrote:
Done
https://github.com/llvm/llvm-project/pull/168794
More information about the llvm-commits
mailing list