[llvm] [Mips] Fix wrong qNaN encoding when -mnan=legacy (PR #153777)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 22 01:05:56 PDT 2025
https://github.com/yingopq updated https://github.com/llvm/llvm-project/pull/153777
>From 5da4af7d09ecb3e3514dc3a095815d3d9151d7d7 Mon Sep 17 00:00:00 2001
From: Ying Huang <ying.huang at oss.cipunited.com>
Date: Fri, 15 Aug 2025 05:57:33 -0400
Subject: [PATCH] [Mips] Fix wrong qNaN encoding when -mnan=legacy
The correct value is:
Single floating-point 0x7fbf ffff(legacy) 0x7fc0 0000(nan2008)
Double floating-point 0x7ff7 ffff ffff ffff(legacy) 0x7ff8 0000 0000 0000(nan2008)
Fix #100495.
---
llvm/include/llvm/CodeGen/TargetLowering.h | 4 ++++
.../CodeGen/SelectionDAG/TargetLowering.cpp | 7 +++++--
llvm/lib/Target/Mips/MipsISelLowering.cpp | 14 ++++++++++++++
llvm/lib/Target/Mips/MipsISelLowering.h | 2 ++
llvm/test/CodeGen/Mips/fminimum-fmaximum.ll | 18 ++++++++++++++++++
5 files changed, 43 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/CodeGen/Mips/fminimum-fmaximum.ll
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index ed7495694cc70..7d7c93e29a39b 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -4433,6 +4433,10 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
///
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
+ /// For targets which need get QNaN by assigning a certain value to the
+ /// parameter payload.
+ virtual APFloat getNaNValue(EVT VT) const;
+
/// Return true if it is profitable to move this shift by a constant amount
/// through its operand, adjusting any immediate operands as necessary to
/// preserve semantics. This transformation may not be desirable if it
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 911bbabc42aa3..b90cf81f188cd 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -8731,6 +8731,10 @@ SDValue TargetLowering::expandFMINNUM_FMAXNUM(SDNode *Node,
return SDValue();
}
+APFloat TargetLowering::getNaNValue(EVT VT) const {
+ return APFloat::getNaN(VT.getFltSemantics());
+}
+
SDValue TargetLowering::expandFMINIMUM_FMAXIMUM(SDNode *N,
SelectionDAG &DAG) const {
if (SDValue Expanded = expandVectorNaryOpBySplitting(N, DAG))
@@ -8773,8 +8777,7 @@ SDValue TargetLowering::expandFMINIMUM_FMAXIMUM(SDNode *N,
// Propagate any NaN of both operands
if (!N->getFlags().hasNoNaNs() &&
(!DAG.isKnownNeverNaN(RHS) || !DAG.isKnownNeverNaN(LHS))) {
- ConstantFP *FPNaN = ConstantFP::get(*DAG.getContext(),
- APFloat::getNaN(VT.getFltSemantics()));
+ ConstantFP *FPNaN = ConstantFP::get(*DAG.getContext(), getNaNValue(VT));
MinMax = DAG.getSelect(DL, VT, DAG.getSetCC(DL, CCVT, LHS, RHS, ISD::SETUO),
DAG.getConstantFP(*FPNaN, DL, VT), MinMax, Flags);
}
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index 9fbbdb2ecb264..7a27c0b9c9316 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -1255,6 +1255,20 @@ static SDValue performSignExtendCombine(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
+APFloat MipsTargetLowering::getNaNValue(EVT VT) const {
+ if (!Subtarget.isNaN2008()) {
+ if (&VT.getFltSemantics() == &APFloat::IEEEsingle()) {
+ APInt intPayload(64, 0xbfffff);
+ return APFloat::getSNaN(VT.getFltSemantics(), false, &intPayload);
+ } else if (&VT.getFltSemantics() == &APFloat::IEEEdouble()) {
+ APInt intPayload(64, 0x7ffffffffffff);
+ return APFloat::getSNaN(VT.getFltSemantics(), false, &intPayload);
+ }
+ }
+
+ return APFloat::getNaN(VT.getFltSemantics());
+}
+
SDValue MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
const {
SelectionDAG &DAG = DCI.DAG;
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index c65c76ccffc75..870306529de8f 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -341,6 +341,8 @@ class TargetRegisterClass;
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
+ APFloat getNaNValue(EVT VT) const override;
+
MachineBasicBlock *
EmitInstrWithCustomInserter(MachineInstr &MI,
MachineBasicBlock *MBB) const override;
diff --git a/llvm/test/CodeGen/Mips/fminimum-fmaximum.ll b/llvm/test/CodeGen/Mips/fminimum-fmaximum.ll
new file mode 100644
index 0000000000000..0121e8905303f
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/fminimum-fmaximum.ll
@@ -0,0 +1,18 @@
+; RUN: llc -mtriple=mips64el-unknown-linux-gnuabi64 -mcpu=mips64r2 -mattr=+nan2008 < %s | FileCheck -check-prefixes=NAN2008 %s
+; RUN: llc -mtriple=mips64el-unknown-linux-gnuabi64 -mcpu=mips64r2 -mattr=-nan2008 < %s | FileCheck -check-prefixes=LEGACY %s
+
+define float @test_fminimum_f32(float %a, float %b) {
+; NAN2008: .4byte 0x7fc00000 # float NaN
+;
+; LEGACY: .4byte 0x7fbfffff # float NaN
+ %val = tail call float @llvm.minimum.f32(float %a, float %b)
+ ret float %val
+}
+
+define double @test_fminimum_f64(double %a, double %b) {
+; NAN2008: .8byte 0x7ff8000000000000 # double NaN
+;
+; LEGACY: .8byte 0x7ff7ffffffffffff # double NaN
+ %val = tail call double @llvm.minimum.f64(double %a, double %b)
+ ret double %val
+}
More information about the llvm-commits
mailing list