[llvm] CodeGen: Add ISD::AssertNoFPClass (PR #135946)
YunQiang Su via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 21 03:36:57 PDT 2025
https://github.com/wzssyqa updated https://github.com/llvm/llvm-project/pull/135946
>From 62e1163a9eaadbb3fe845f2d7ee40a91d1189dee Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Wed, 16 Apr 2025 18:10:21 +0800
Subject: [PATCH 1/8] CodeGen: Add ISD::AssertNoFPClass
It is used to mark a value that we are sure that it is not some fcType.
The examples include:
* An arguments of a function is marked with nofpclass
* Output value of an intrinsic can be sure to not be some type
So that the following operation can make some assumptions.
---
llvm/include/llvm/CodeGen/ISDOpcodes.h | 6 ++++++
llvm/include/llvm/Target/TargetSelectionDAG.td | 1 +
llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp | 3 +++
llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp | 3 +++
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 4 ++++
llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp | 1 +
llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 1 +
7 files changed, 19 insertions(+)
diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index ad8a95a353b56..7a9b716f652f3 100644
--- a/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -67,6 +67,12 @@ enum NodeType {
/// poisoned the assertion will not be true for that value.
AssertAlign,
+ /// AssertNoFPClass - These nodes record if a register contains a float
+ /// value that is known to be not some type.
+ /// NOTE: In case of the source value (or any vector element value) is
+ /// poisoned the assertion will not be true for that value.
+ AssertNoFPClass,
+
/// Various leaf nodes.
BasicBlock,
VALUETYPE,
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index 9c241b6c4df0f..8453cf7f4e58a 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -859,6 +859,7 @@ def SDT_assert : SDTypeProfile<1, 1,
[SDTCisInt<0>, SDTCisInt<1>, SDTCisSameAs<1, 0>]>;
def assertsext : SDNode<"ISD::AssertSext", SDT_assert>;
def assertzext : SDNode<"ISD::AssertZext", SDT_assert>;
+def assernofpclass : SDNode<"ISD::AssertNoFPClass", SDTFPUnaryOp>;
def assertalign : SDNode<"ISD::AssertAlign", SDT_assert>;
def convergencectrl_anchor : SDNode<"ISD::CONVERGENCECTRL_ANCHOR",
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 432209e8ecb0a..d03eeaa01b697 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -168,6 +168,7 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
case ISD::POISON:
case ISD::UNDEF: R = SoftenFloatRes_UNDEF(N); break;
case ISD::VAARG: R = SoftenFloatRes_VAARG(N); break;
+ case ISD::AssertNoFPClass: R = GetSoftenedFloat(N->getOperand(0)); break;
case ISD::VECREDUCE_FADD:
case ISD::VECREDUCE_FMUL:
case ISD::VECREDUCE_FMIN:
@@ -2576,6 +2577,7 @@ bool DAGTypeLegalizer::PromoteFloatOperand(SDNode *N, unsigned OpNo) {
R = PromoteFloatOp_FAKE_USE(N, OpNo);
break;
case ISD::FCOPYSIGN: R = PromoteFloatOp_FCOPYSIGN(N, OpNo); break;
+ case ISD::AssertNoFPClass:
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT:
case ISD::LROUND:
@@ -2803,6 +2805,7 @@ void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) {
case ISD::FTRUNC:
case ISD::FTAN:
case ISD::FTANH:
+ case ISD::AssertNoFPClass:
case ISD::FCANONICALIZE: R = PromoteFloatRes_UnaryOp(N); break;
// Binary FP Operations
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index a01e1cff74564..54da9fe3c6a40 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -129,6 +129,7 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
case ISD::UINT_TO_FP:
case ISD::ZERO_EXTEND:
case ISD::FCANONICALIZE:
+ case ISD::AssertNoFPClass:
R = ScalarizeVecRes_UnaryOp(N);
break;
case ISD::ADDRSPACECAST:
@@ -1276,6 +1277,7 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
case ISD::UINT_TO_FP:
case ISD::VP_UINT_TO_FP:
case ISD::FCANONICALIZE:
+ case ISD::AssertNoFPClass:
SplitVecRes_UnaryOp(N, Lo, Hi);
break;
case ISD::ADDRSPACECAST:
@@ -4844,6 +4846,7 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
case ISD::FREEZE:
case ISD::ARITH_FENCE:
case ISD::FCANONICALIZE:
+ case ISD::AssertNoFPClass:
Res = WidenVecRes_Unary(N);
break;
case ISD::FMA: case ISD::VP_FMA:
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index f502a536d43b1..3c7367ac7002a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -7406,6 +7406,10 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
N2.getOpcode() == ISD::TargetConstant && "Invalid FP_ROUND!");
if (N1.getValueType() == VT) return N1; // noop conversion.
break;
+ case ISD::AssertNoFPClass:
+ assert(N1.getValueType().isFloatingPoint() &&
+ "AssertNoFPClass is used for a non-floating type");
+ return N1;
case ISD::AssertSext:
case ISD::AssertZext: {
EVT EVT = cast<VTSDNode>(N2)->getVT();
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 8fcec6c6cd7c6..240115ac739f0 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -122,6 +122,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::TokenFactor: return "TokenFactor";
case ISD::AssertSext: return "AssertSext";
case ISD::AssertZext: return "AssertZext";
+ case ISD::AssertNoFPClass: return "AssertNoFPClass";
case ISD::AssertAlign: return "AssertAlign";
case ISD::BasicBlock: return "BasicBlock";
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 598de6b207754..62d911fed2a3f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -3265,6 +3265,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
return;
case ISD::AssertSext:
case ISD::AssertZext:
+ case ISD::AssertNoFPClass:
case ISD::AssertAlign:
ReplaceUses(SDValue(NodeToMatch, 0), NodeToMatch->getOperand(0));
CurDAG->RemoveDeadNode(NodeToMatch);
>From e727de166f33911ddf501e0270cf098df9ab08c6 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Fri, 18 Apr 2025 11:19:08 +0800
Subject: [PATCH 2/8] fix typo assernofpclass
---
llvm/include/llvm/Target/TargetSelectionDAG.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index 8453cf7f4e58a..156fbb925873e 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -859,7 +859,7 @@ def SDT_assert : SDTypeProfile<1, 1,
[SDTCisInt<0>, SDTCisInt<1>, SDTCisSameAs<1, 0>]>;
def assertsext : SDNode<"ISD::AssertSext", SDT_assert>;
def assertzext : SDNode<"ISD::AssertZext", SDT_assert>;
-def assernofpclass : SDNode<"ISD::AssertNoFPClass", SDTFPUnaryOp>;
+def assertnofpclass : SDNode<"ISD::AssertNoFPClass", SDTFPUnaryOp>;
def assertalign : SDNode<"ISD::AssertAlign", SDT_assert>;
def convergencectrl_anchor : SDNode<"ISD::CONVERGENCECTRL_ANCHOR",
>From 1024b94f87e8e3053f04a2f344117040b709aecf Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Mon, 21 Apr 2025 10:48:36 +0800
Subject: [PATCH 3/8] Add isKnownNeverNaN test
---
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 13 ++++++++++++-
.../CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 10 ++++++++++
llvm/test/CodeGen/AArch64/nofpclass.ll | 12 ++++++++++++
3 files changed, 34 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/AArch64/nofpclass.ll
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 3c7367ac7002a..68d8fd5a93f38 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5760,6 +5760,17 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op, const APInt &DemandedElts,
return false;
return true;
}
+ case ISD::AssertNoFPClass: {
+ SDValue SDNoFPClass = Op.getOperand(1);
+ assert(isa<ConstantSDNode>(SDNoFPClass) && "NoFPClass is not Constant");
+ FPClassTest NoFPClass = static_cast<FPClassTest>(
+ dyn_cast<ConstantSDNode>(SDNoFPClass)->getZExtValue());
+ if (NoFPClass & fcNan)
+ return true;
+ if (SNaN && (NoFPClass & fcSNan))
+ return true;
+ return isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1);
+ }
default:
if (Opcode >= ISD::BUILTIN_OP_END || Opcode == ISD::INTRINSIC_WO_CHAIN ||
Opcode == ISD::INTRINSIC_W_CHAIN || Opcode == ISD::INTRINSIC_VOID) {
@@ -7409,7 +7420,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
case ISD::AssertNoFPClass:
assert(N1.getValueType().isFloatingPoint() &&
"AssertNoFPClass is used for a non-floating type");
- return N1;
+ break;
case ISD::AssertSext:
case ISD::AssertZext: {
EVT EVT = cast<VTSDNode>(N2)->getVT();
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index d7a67cca3c197..9e8cdb21536f2 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -11848,6 +11848,16 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
SDValue Res = DAG.getMergeValues(ArrayRef(ArgValues.data(), NumValues),
SDB->getCurSDLoc());
+ FPClassTest NoFPClass = Arg.getNoFPClass();
+ if (NoFPClass != fcNone) {
+ EVT I64EVT = EVT::getIntegerVT(*DAG.getContext(), 64);
+ SDValue SDNoFPClass =
+ DAG.getConstant(static_cast<uint64_t>(NoFPClass), dl, I64EVT);
+ SDNodeFlags ResFlags = Res->getFlags();
+ Res = DAG.getNode(ISD::AssertNoFPClass, dl, Res.getValueType(), Res,
+ SDNoFPClass, ResFlags);
+ }
+
SDB->setValue(&Arg, Res);
if (!TM.Options.EnableFastISel && Res.getOpcode() == ISD::BUILD_PAIR) {
// We want to associate the argument with the frame index, among
diff --git a/llvm/test/CodeGen/AArch64/nofpclass.ll b/llvm/test/CodeGen/AArch64/nofpclass.ll
new file mode 100644
index 0000000000000..f34081699a5a4
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/nofpclass.ll
@@ -0,0 +1,12 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc --mtriple=aarch64-linux-gnu < %s | FileCheck %s
+
+define nofpclass(nzero) float @f(float noundef nofpclass(nan) %a, float noundef nofpclass(nan) %b) {
+; CHECK-LABEL: f:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: fmaxnm s0, s0, s1
+; CHECK-NEXT: ret
+entry:
+ %cond = tail call float @llvm.maximumnum.f32(float %a, float %b)
+ ret float %cond
+}
>From d77aef15ba338b10800425720cd5a6fe429199fb Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Mon, 21 Apr 2025 10:52:27 +0800
Subject: [PATCH 4/8] Mention operands
---
llvm/include/llvm/CodeGen/ISDOpcodes.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index 7a9b716f652f3..1b3ac8dc3ee8a 100644
--- a/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -69,6 +69,9 @@ enum NodeType {
/// AssertNoFPClass - These nodes record if a register contains a float
/// value that is known to be not some type.
+ /// This node takes two operands. The first is the node that is known
+ /// never to be a float type. and the second is a constant value with
+ /// the value of FPClassTest (casted to uint64_t).
/// NOTE: In case of the source value (or any vector element value) is
/// poisoned the assertion will not be true for that value.
AssertNoFPClass,
>From 5d3aaac0ff6a8946f96d4aed5275625a49aa2695 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Mon, 21 Apr 2025 10:56:01 +0800
Subject: [PATCH 5/8] Fix typo
---
llvm/include/llvm/CodeGen/ISDOpcodes.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index 1b3ac8dc3ee8a..3fc1457f835b9 100644
--- a/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -70,7 +70,7 @@ enum NodeType {
/// AssertNoFPClass - These nodes record if a register contains a float
/// value that is known to be not some type.
/// This node takes two operands. The first is the node that is known
- /// never to be a float type. and the second is a constant value with
+ /// never to be some float types. and the second is a constant value with
/// the value of FPClassTest (casted to uint64_t).
/// NOTE: In case of the source value (or any vector element value) is
/// poisoned the assertion will not be true for that value.
>From b06150fa18402e636ae015f029b01d9caf57518f Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Mon, 21 Apr 2025 11:43:40 +0800
Subject: [PATCH 6/8] Fix AssertNoFPClass assert
---
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 68d8fd5a93f38..0d1f334dafe85 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -7417,10 +7417,17 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
N2.getOpcode() == ISD::TargetConstant && "Invalid FP_ROUND!");
if (N1.getValueType() == VT) return N1; // noop conversion.
break;
- case ISD::AssertNoFPClass:
+ case ISD::AssertNoFPClass: {
assert(N1.getValueType().isFloatingPoint() &&
"AssertNoFPClass is used for a non-floating type");
+ assert(isa<ConstantSDNode>(N2) && "NoFPClass is not Constant");
+ FPClassTest NoFPClass =
+ static_cast<FPClassTest>(dyn_cast<ConstantSDNode>(N2)->getZExtValue());
+ assert(llvm::to_underlying(NoFPClass) <=
+ BitmaskEnumDetail::Mask<FPClassTest>() &&
+ "FPClassTest value too large");
break;
+ }
case ISD::AssertSext:
case ISD::AssertZext: {
EVT EVT = cast<VTSDNode>(N2)->getVT();
>From 062db54fdfb0e18282fd95dec371ed79abd49c58 Mon Sep 17 00:00:00 2001
From: Your Name <you at example.com>
Date: Mon, 21 Apr 2025 18:24:52 +0800
Subject: [PATCH 7/8] Fix code styles
1. Use Op.getConstantOperandVal to get Constant value
2. (NoFPClass & fcNan) == fcNan
3. Use N2->getAsZExtValue() to get Constant value
4. Use getTargetConstant with ptr width to fix 32bit target
5. Don't propagate the flags
6. Add MIPSr6 testcase for 32bit target tests
---
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 13 +++++--------
.../SelectionDAG/SelectionDAGBuilder.cpp | 7 +++----
llvm/test/CodeGen/Mips/nofpclass.ll | 18 ++++++++++++++++++
3 files changed, 26 insertions(+), 12 deletions(-)
create mode 100644 llvm/test/CodeGen/Mips/nofpclass.ll
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 0d1f334dafe85..6bdf07aa15474 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5761,13 +5761,11 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op, const APInt &DemandedElts,
return true;
}
case ISD::AssertNoFPClass: {
- SDValue SDNoFPClass = Op.getOperand(1);
- assert(isa<ConstantSDNode>(SDNoFPClass) && "NoFPClass is not Constant");
- FPClassTest NoFPClass = static_cast<FPClassTest>(
- dyn_cast<ConstantSDNode>(SDNoFPClass)->getZExtValue());
- if (NoFPClass & fcNan)
+ FPClassTest NoFPClass =
+ static_cast<FPClassTest>(Op.getConstantOperandVal(1));
+ if ((NoFPClass & fcNan) == fcNan)
return true;
- if (SNaN && (NoFPClass & fcSNan))
+ if (SNaN && (NoFPClass & fcSNan) == fcSNan)
return true;
return isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1);
}
@@ -7421,8 +7419,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
assert(N1.getValueType().isFloatingPoint() &&
"AssertNoFPClass is used for a non-floating type");
assert(isa<ConstantSDNode>(N2) && "NoFPClass is not Constant");
- FPClassTest NoFPClass =
- static_cast<FPClassTest>(dyn_cast<ConstantSDNode>(N2)->getZExtValue());
+ FPClassTest NoFPClass = static_cast<FPClassTest>(N2->getAsZExtVal());
assert(llvm::to_underlying(NoFPClass) <=
BitmaskEnumDetail::Mask<FPClassTest>() &&
"FPClassTest value too large");
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 9e8cdb21536f2..6cabe1f293f86 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -11850,12 +11850,11 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
FPClassTest NoFPClass = Arg.getNoFPClass();
if (NoFPClass != fcNone) {
- EVT I64EVT = EVT::getIntegerVT(*DAG.getContext(), 64);
SDValue SDNoFPClass =
- DAG.getConstant(static_cast<uint64_t>(NoFPClass), dl, I64EVT);
- SDNodeFlags ResFlags = Res->getFlags();
+ DAG.getTargetConstant(static_cast<uint64_t>(NoFPClass), dl,
+ TLI->getPointerTy(DAG.getDataLayout()));
Res = DAG.getNode(ISD::AssertNoFPClass, dl, Res.getValueType(), Res,
- SDNoFPClass, ResFlags);
+ SDNoFPClass);
}
SDB->setValue(&Arg, Res);
diff --git a/llvm/test/CodeGen/Mips/nofpclass.ll b/llvm/test/CodeGen/Mips/nofpclass.ll
new file mode 100644
index 0000000000000..a1eab763f4d01
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/nofpclass.ll
@@ -0,0 +1,18 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc --mtriple=mipsisa32r6-linux-gnu < %s | FileCheck %s --check-prefix=MIPS32R6
+; RUN: llc --mtriple=mipsisa64r6-linux-gnu < %s | FileCheck %s --check-prefix=MIPS64R6
+
+define nofpclass(nzero) float @f(float nofpclass(nan) %a, float nofpclass(nan) %b) {
+; MIPS32R6-LABEL: f:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: jr $ra
+; MIPS32R6-NEXT: max.s $f0, $f12, $f14
+;
+; MIPS64R6-LABEL: f:
+; MIPS64R6: # %bb.0: # %entry
+; MIPS64R6-NEXT: jr $ra
+; MIPS64R6-NEXT: max.s $f0, $f12, $f13
+entry:
+ %cond = tail call float @llvm.maximumnum.f32(float %a, float %b)
+ ret float %cond
+}
>From 30e6ee0c9a68111f4de401aeb9996f600686fecd Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Mon, 21 Apr 2025 18:36:37 +0800
Subject: [PATCH 8/8] Add Vector test case
---
llvm/test/CodeGen/AArch64/nofpclass.ll | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/AArch64/nofpclass.ll b/llvm/test/CodeGen/AArch64/nofpclass.ll
index f34081699a5a4..2a8c64f94737e 100644
--- a/llvm/test/CodeGen/AArch64/nofpclass.ll
+++ b/llvm/test/CodeGen/AArch64/nofpclass.ll
@@ -1,7 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc --mtriple=aarch64-linux-gnu < %s | FileCheck %s
-define nofpclass(nzero) float @f(float noundef nofpclass(nan) %a, float noundef nofpclass(nan) %b) {
+define nofpclass(nzero) float @f(float nofpclass(nan) %a, float nofpclass(nan) %b) {
; CHECK-LABEL: f:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fmaxnm s0, s0, s1
@@ -10,3 +10,13 @@ entry:
%cond = tail call float @llvm.maximumnum.f32(float %a, float %b)
ret float %cond
}
+
+define <4 x float> @fv4f32(<4 x float> nofpclass(nan) %a, <4 x float> nofpclass(nan) %b) {
+; CHECK-LABEL: fv4f32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: fmaxnm v0.4s, v0.4s, v1.4s
+; CHECK-NEXT: ret
+entry:
+ %c = call <4 x float> @llvm.maximumnum.v4f32(<4 x float> %a, <4 x float> %b)
+ ret <4 x float> %c
+}
More information about the llvm-commits
mailing list