[llvm] SelectionDAG: Support nofpclass(nan/qnan/snan) in arguments (PR #130051)

YunQiang Su via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 9 17:50:57 PDT 2025


https://github.com/wzssyqa updated https://github.com/llvm/llvm-project/pull/130051

>From 3a271aeff00e0234608e0bf6c647648f0506ca79 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Thu, 6 Mar 2025 18:09:56 +0800
Subject: [PATCH 1/2] SelectionDAG: Support nofpclass(nan/qnan/snan)

SelectionDAGISel::LowerArguments: Pass NoNaN Flags to InVals.

`nofpclass` support values nan, snan, qnan, where nan=snan|qnan.
So let's use NoSNaNs and NoQNaNs in SDNodeFlags.

Thus, we can use it in isKnownNeverNaN.
---
 llvm/include/llvm/CodeGen/SelectionDAGNodes.h |  21 +-
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |   7 +-
 .../SelectionDAG/SelectionDAGBuilder.cpp      |  10 +
 .../AArch64/fp-maximumnum-minimumnum.ll       | 973 ++++++++++++++++++
 .../LoongArch/fp-maximumnum-minimumnum.ll     | 241 +++++
 .../CodeGen/Mips/fp-maximumnum-minimumnum.ll  |  73 ++
 6 files changed, 1319 insertions(+), 6 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index 20283ad8f2689..6f2eeceb719dc 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -397,7 +397,7 @@ struct SDNodeFlags {
     Exact = 1 << 2,
     Disjoint = 1 << 3,
     NonNeg = 1 << 4,
-    NoNaNs = 1 << 5,
+    // 1 << 5 was used as NoNaNs
     NoInfs = 1 << 6,
     NoSignedZeros = 1 << 7,
     AllowReciprocal = 1 << 8,
@@ -416,11 +416,14 @@ struct SDNodeFlags {
     // Compare instructions which may carry the samesign flag.
     SameSign = 1 << 14,
 
+    NoSNaNs = 1 << 15,
+    NoQNaNs = 1 << 16,
+
     // NOTE: Please update LargestValue in LLVM_DECLARE_ENUM_AS_BITMASK below
     // the class definition when adding new flags.
 
     PoisonGeneratingFlags = NoUnsignedWrap | NoSignedWrap | Exact | Disjoint |
-                            NonNeg | NoNaNs | NoInfs | SameSign,
+                            NonNeg | NoSNaNs | NoQNaNs | NoInfs | SameSign,
   };
 
   /// Default constructor turns off all optimization flags.
@@ -428,7 +431,8 @@ struct SDNodeFlags {
 
   /// Propagate the fast-math-flags from an IR FPMathOperator.
   void copyFMF(const FPMathOperator &FPMO) {
-    setNoNaNs(FPMO.hasNoNaNs());
+    setNoSNaNs(FPMO.hasNoNaNs());
+    setNoQNaNs(FPMO.hasNoNaNs());
     setNoInfs(FPMO.hasNoInfs());
     setNoSignedZeros(FPMO.hasNoSignedZeros());
     setAllowReciprocal(FPMO.hasAllowReciprocal());
@@ -444,7 +448,12 @@ struct SDNodeFlags {
   void setDisjoint(bool b) { setFlag<Disjoint>(b); }
   void setSameSign(bool b) { setFlag<SameSign>(b); }
   void setNonNeg(bool b) { setFlag<NonNeg>(b); }
-  void setNoNaNs(bool b) { setFlag<NoNaNs>(b); }
+  void setNoNaNs(bool b) {
+    setFlag<NoSNaNs>(b);
+    setFlag<NoQNaNs>(b);
+  }
+  void setNoSNaNs(bool b) { setFlag<NoSNaNs>(b); }
+  void setNoQNaNs(bool b) { setFlag<NoQNaNs>(b); }
   void setNoInfs(bool b) { setFlag<NoInfs>(b); }
   void setNoSignedZeros(bool b) { setFlag<NoSignedZeros>(b); }
   void setAllowReciprocal(bool b) { setFlag<AllowReciprocal>(b); }
@@ -461,7 +470,9 @@ struct SDNodeFlags {
   bool hasDisjoint() const { return Flags & Disjoint; }
   bool hasSameSign() const { return Flags & SameSign; }
   bool hasNonNeg() const { return Flags & NonNeg; }
-  bool hasNoNaNs() const { return Flags & NoNaNs; }
+  bool hasNoNaNs() const { return (Flags & NoSNaNs) && (Flags & NoQNaNs); }
+  bool hasNoSNaNs() const { return Flags & NoSNaNs; }
+  bool hasNoQNaNs() const { return Flags & NoQNaNs; }
   bool hasNoInfs() const { return Flags & NoInfs; }
   bool hasNoSignedZeros() const { return Flags & NoSignedZeros; }
   bool hasAllowReciprocal() const { return Flags & AllowReciprocal; }
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index df30148b78b65..7fc97fadeff09 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5613,7 +5613,12 @@ bool SelectionDAG::isBaseWithConstantOffset(SDValue Op) const {
 
 bool SelectionDAG::isKnownNeverNaN(SDValue Op, bool SNaN, unsigned Depth) const {
   // If we're told that NaNs won't happen, assume they won't.
-  if (getTarget().Options.NoNaNsFPMath || Op->getFlags().hasNoNaNs())
+  if (getTarget().Options.NoNaNsFPMath)
+    return true;
+  SDNodeFlags OpFlags = Op->getFlags();
+  if (SNaN && OpFlags.hasNoSNaNs())
+    return true;
+  if (OpFlags.hasNoSNaNs() && OpFlags.hasNoQNaNs())
     return true;
 
   if (Depth >= MaxRecursionDepth)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 86b99a5210924..0604db4c64608 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -11885,6 +11885,16 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
           AssertOp = ISD::AssertSext;
         else if (Arg.hasAttribute(Attribute::ZExt))
           AssertOp = ISD::AssertZext;
+        if (Arg.hasAttribute(Attribute::NoFPClass)) {
+          SDNodeFlags InValFlags = InVals[i]->getFlags();
+          bool NoSNaN = ((Arg.getNoFPClass() & llvm::fcSNan) == llvm::fcSNan);
+          bool NoQNaN = ((Arg.getNoFPClass() & llvm::fcQNan) == llvm::fcQNan);
+          InValFlags.setNoSNaNs(NoSNaN);
+          InValFlags.setNoQNaNs(NoQNaN);
+          InValFlags.setNoInfs((Arg.getNoFPClass() & llvm::fcInf) ==
+                               llvm::fcInf);
+          InVals[i]->setFlags(InValFlags);
+        }
 
         ArgValues.push_back(getCopyFromParts(DAG, dl, &InVals[i], NumParts,
                                              PartVT, VT, nullptr, NewRoot,
diff --git a/llvm/test/CodeGen/AArch64/fp-maximumnum-minimumnum.ll b/llvm/test/CodeGen/AArch64/fp-maximumnum-minimumnum.ll
index bb3f9a3e52a16..2ef6d17f657b2 100644
--- a/llvm/test/CodeGen/AArch64/fp-maximumnum-minimumnum.ll
+++ b/llvm/test/CodeGen/AArch64/fp-maximumnum-minimumnum.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc --mtriple=aarch64 --mattr=+fullfp16 < %s | FileCheck %s --check-prefix=AARCH64
+; FIXME: nofpclass with length more than 128bit, may emit unnecessary instructions.
 
 ;;;;;;;;;;;;;;;;  max_f64
 define double @max_nnan_f64(double %a, double %b) {
@@ -1032,3 +1033,975 @@ entry:
   %c = call <16 x half> @llvm.minimumnum.v16f16(<16 x half> %a, <16 x half> %b)
   ret <16 x half> %c
 }
+;;;;;;;;;;;;;;;;  max_f64
+define double @max_nofpclass_f64(double nofpclass(nan) %a, double nofpclass(nan) %b) {
+; AARCH64-LABEL: max_nofpclass_f64:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm d0, d0, d1
+; AARCH64-NEXT:    ret
+entry:
+  %c = call double @llvm.maximumnum.f64(double %a, double %b)
+  ret double %c
+}
+
+define <2 x double> @max_nofpclass_v2f64(<2 x double> nofpclass(nan) %a, <2 x double> nofpclass(nan) %b) {
+; AARCH64-LABEL: max_nofpclass_v2f64:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm v0.2d, v0.2d, v1.2d
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <2 x double> @llvm.maximumnum.v2f64(<2 x double> %a, <2 x double> %b)
+  ret <2 x double> %c
+}
+
+define <3 x double> @max_nofpclass_v3f64(<3 x double> nofpclass(nan) %a, <3 x double> nofpclass(nan) %b) {
+; AARCH64-LABEL: max_nofpclass_v3f64:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    // kill: def $d3 killed $d3 def $q3
+; AARCH64-NEXT:    // kill: def $d0 killed $d0 def $q0
+; AARCH64-NEXT:    // kill: def $d4 killed $d4 def $q4
+; AARCH64-NEXT:    // kill: def $d1 killed $d1 def $q1
+; AARCH64-NEXT:    // kill: def $d2 killed $d2 def $q2
+; AARCH64-NEXT:    // kill: def $d5 killed $d5 def $q5
+; AARCH64-NEXT:    mov v0.d[1], v1.d[0]
+; AARCH64-NEXT:    mov v3.d[1], v4.d[0]
+; AARCH64-NEXT:    fminnm v2.2d, v2.2d, v2.2d
+; AARCH64-NEXT:    fminnm v1.2d, v3.2d, v3.2d
+; AARCH64-NEXT:    fminnm v0.2d, v0.2d, v0.2d
+; AARCH64-NEXT:    fmaxnm v0.2d, v0.2d, v1.2d
+; AARCH64-NEXT:    fminnm v1.2d, v5.2d, v5.2d
+; AARCH64-NEXT:    fmaxnm v2.2d, v2.2d, v1.2d
+; AARCH64-NEXT:    ext v1.16b, v0.16b, v0.16b, #8
+; AARCH64-NEXT:    // kill: def $d0 killed $d0 killed $q0
+; AARCH64-NEXT:    // kill: def $d1 killed $d1 killed $q1
+; AARCH64-NEXT:    // kill: def $d2 killed $d2 killed $q2
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <3 x double> @llvm.maximumnum.v3f64(<3 x double> %a, <3 x double> %b)
+  ret <3 x double> %c
+}
+
+define <4 x double> @max_nofpclass_v4f64(<4 x double> nofpclass(nan) %a, <4 x double> nofpclass(nan) %b) {
+; AARCH64-LABEL: max_nofpclass_v4f64:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v3.2d, v3.2d, v3.2d
+; AARCH64-NEXT:    fminnm v1.2d, v1.2d, v1.2d
+; AARCH64-NEXT:    fmaxnm v0.2d, v0.2d, v2.2d
+; AARCH64-NEXT:    fmaxnm v1.2d, v1.2d, v3.2d
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <4 x double> @llvm.maximumnum.v4f64(<4 x double> %a, <4 x double> %b)
+  ret <4 x double> %c
+}
+
+;;;;;;;;;;;;;;;;;; max_f32
+define float @max_nofpclass_f32(float nofpclass(nan) %a, float nofpclass(nan) %b) {
+; AARCH64-LABEL: max_nofpclass_f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm s0, s0, s1
+; AARCH64-NEXT:    ret
+entry:
+  %c = call float @llvm.maximumnum.f32(float %a, float %b)
+  ret float %c
+}
+
+define <2 x float> @max_nofpclass_v2f32(<2 x float> nofpclass(nan) %a, <2 x float> nofpclass(nan) %b) {
+; AARCH64-LABEL: max_nofpclass_v2f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm v0.2s, v0.2s, v1.2s
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <2 x float> @llvm.maximumnum.v2f32(<2 x float> %a, <2 x float> %b)
+  ret <2 x float> %c
+}
+
+define <3 x float> @max_nofpclass_v3f32(<3 x float> nofpclass(nan) %a, <3 x float> nofpclass(nan) %b) {
+; AARCH64-LABEL: max_nofpclass_v3f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm v0.4s, v0.4s, v1.4s
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <3 x float> @llvm.maximumnum.v3f32(<3 x float> %a, <3 x float> %b)
+  ret <3 x float> %c
+}
+
+define <4 x float> @max_nofpclass_v4f32(<4 x float> nofpclass(nan) %a, <4 x float> nofpclass(nan) %b) {
+; AARCH64-LABEL: max_nofpclass_v4f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm v0.4s, v0.4s, v1.4s
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <4 x float> @llvm.maximumnum.v4f32(<4 x float> %a, <4 x float> %b)
+  ret <4 x float> %c
+}
+
+define <5 x float> @max_nofpclass_v5f32(<5 x float> nofpclass(nan) %a, <5 x float> nofpclass(nan) %b) {
+; AARCH64-LABEL: max_nofpclass_v5f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    // kill: def $s0 killed $s0 def $q0
+; AARCH64-NEXT:    // kill: def $s5 killed $s5 def $q5
+; AARCH64-NEXT:    // kill: def $s1 killed $s1 def $q1
+; AARCH64-NEXT:    // kill: def $s6 killed $s6 def $q6
+; AARCH64-NEXT:    // kill: def $s2 killed $s2 def $q2
+; AARCH64-NEXT:    // kill: def $s7 killed $s7 def $q7
+; AARCH64-NEXT:    // kill: def $s3 killed $s3 def $q3
+; AARCH64-NEXT:    mov x8, sp
+; AARCH64-NEXT:    // kill: def $s4 killed $s4 def $q4
+; AARCH64-NEXT:    mov v0.s[1], v1.s[0]
+; AARCH64-NEXT:    mov v5.s[1], v6.s[0]
+; AARCH64-NEXT:    mov v0.s[2], v2.s[0]
+; AARCH64-NEXT:    mov v5.s[2], v7.s[0]
+; AARCH64-NEXT:    ldr s2, [sp, #8]
+; AARCH64-NEXT:    fminnm v2.4s, v2.4s, v2.4s
+; AARCH64-NEXT:    mov v0.s[3], v3.s[0]
+; AARCH64-NEXT:    ld1 { v5.s }[3], [x8]
+; AARCH64-NEXT:    fminnm v3.4s, v4.4s, v4.4s
+; AARCH64-NEXT:    fminnm v1.4s, v5.4s, v5.4s
+; AARCH64-NEXT:    fminnm v0.4s, v0.4s, v0.4s
+; AARCH64-NEXT:    fmaxnm v4.4s, v3.4s, v2.4s
+; AARCH64-NEXT:    // kill: def $s4 killed $s4 killed $q4
+; AARCH64-NEXT:    fmaxnm v0.4s, v0.4s, v1.4s
+; AARCH64-NEXT:    mov s1, v0.s[1]
+; AARCH64-NEXT:    mov s2, v0.s[2]
+; AARCH64-NEXT:    mov s3, v0.s[3]
+; AARCH64-NEXT:    // kill: def $s0 killed $s0 killed $q0
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <5 x float> @llvm.maximumnum.v5f32(<5 x float> %a, <5 x float> %b)
+  ret <5 x float> %c
+}
+
+define <8 x float> @max_nofpclass_v8f32(<8 x float> nofpclass(nan) %a, <8 x float> nofpclass(nan) %b) {
+; AARCH64-LABEL: max_nofpclass_v8f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v3.4s, v3.4s, v3.4s
+; AARCH64-NEXT:    fminnm v1.4s, v1.4s, v1.4s
+; AARCH64-NEXT:    fmaxnm v0.4s, v0.4s, v2.4s
+; AARCH64-NEXT:    fmaxnm v1.4s, v1.4s, v3.4s
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <8 x float> @llvm.maximumnum.v8f32(<8 x float> %a, <8 x float> %b)
+  ret <8 x float> %c
+}
+
+define <2 x half> @max_nofpclass_v2f16(<2 x half> nofpclass(nan) %a, <2 x half> nofpclass(nan) %b) {
+; AARCH64-LABEL: max_nofpclass_v2f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm v0.4h, v0.4h, v1.4h
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <2 x half> @llvm.maximumnum.v2f16(<2 x half> %a, <2 x half> %b)
+  ret <2 x half> %c
+}
+
+define <4 x half> @max_nofpclass_v4f16(<4 x half> nofpclass(nan) %a, <4 x half> nofpclass(nan) %b) {
+; AARCH64-LABEL: max_nofpclass_v4f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm v0.4h, v0.4h, v1.4h
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <4 x half> @llvm.maximumnum.v4f16(<4 x half> %a, <4 x half> %b)
+  ret <4 x half> %c
+}
+
+define <8 x half> @max_nofpclass_v8f16(<8 x half> nofpclass(nan) %a, <8 x half> nofpclass(nan) %b) {
+; AARCH64-LABEL: max_nofpclass_v8f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm v0.8h, v0.8h, v1.8h
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <8 x half> @llvm.maximumnum.v8f16(<8 x half> %a, <8 x half> %b)
+  ret <8 x half> %c
+}
+
+define <9 x half> @max_nofpclass_v9f16(<9 x half> nofpclass(nan) %a, <9 x half> nofpclass(nan) %b) {
+; AARCH64-LABEL: max_nofpclass_v9f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    // kill: def $h0 killed $h0 def $q0
+; AARCH64-NEXT:    // kill: def $h1 killed $h1 def $q1
+; AARCH64-NEXT:    // kill: def $h2 killed $h2 def $q2
+; AARCH64-NEXT:    add x9, sp, #16
+; AARCH64-NEXT:    // kill: def $h3 killed $h3 def $q3
+; AARCH64-NEXT:    // kill: def $h4 killed $h4 def $q4
+; AARCH64-NEXT:    // kill: def $h5 killed $h5 def $q5
+; AARCH64-NEXT:    // kill: def $h6 killed $h6 def $q6
+; AARCH64-NEXT:    // kill: def $h7 killed $h7 def $q7
+; AARCH64-NEXT:    mov v0.h[1], v1.h[0]
+; AARCH64-NEXT:    ldr h1, [sp, #8]
+; AARCH64-NEXT:    ld1 { v1.h }[1], [x9]
+; AARCH64-NEXT:    add x9, sp, #24
+; AARCH64-NEXT:    mov v0.h[2], v2.h[0]
+; AARCH64-NEXT:    ldr h2, [sp]
+; AARCH64-NEXT:    ld1 { v1.h }[2], [x9]
+; AARCH64-NEXT:    add x9, sp, #32
+; AARCH64-NEXT:    fminnm v2.8h, v2.8h, v2.8h
+; AARCH64-NEXT:    mov v0.h[3], v3.h[0]
+; AARCH64-NEXT:    ld1 { v1.h }[3], [x9]
+; AARCH64-NEXT:    add x9, sp, #40
+; AARCH64-NEXT:    ldr h3, [sp, #72]
+; AARCH64-NEXT:    ld1 { v1.h }[4], [x9]
+; AARCH64-NEXT:    add x9, sp, #48
+; AARCH64-NEXT:    fminnm v3.8h, v3.8h, v3.8h
+; AARCH64-NEXT:    mov v0.h[4], v4.h[0]
+; AARCH64-NEXT:    ld1 { v1.h }[5], [x9]
+; AARCH64-NEXT:    add x9, sp, #56
+; AARCH64-NEXT:    fmaxnm v2.8h, v2.8h, v3.8h
+; AARCH64-NEXT:    mov v0.h[5], v5.h[0]
+; AARCH64-NEXT:    ld1 { v1.h }[6], [x9]
+; AARCH64-NEXT:    add x9, sp, #64
+; AARCH64-NEXT:    str h2, [x8, #16]
+; AARCH64-NEXT:    mov v0.h[6], v6.h[0]
+; AARCH64-NEXT:    ld1 { v1.h }[7], [x9]
+; AARCH64-NEXT:    fminnm v1.8h, v1.8h, v1.8h
+; AARCH64-NEXT:    mov v0.h[7], v7.h[0]
+; AARCH64-NEXT:    fminnm v0.8h, v0.8h, v0.8h
+; AARCH64-NEXT:    fmaxnm v0.8h, v0.8h, v1.8h
+; AARCH64-NEXT:    str q0, [x8]
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <9 x half> @llvm.maximumnum.v9f16(<9 x half> %a, <9 x half> %b)
+  ret <9 x half> %c
+}
+
+define <16 x half> @max_nofpclass_v16f16(<16 x half> nofpclass(nan) %a, <16 x half> nofpclass(nan) %b) {
+; AARCH64-LABEL: max_nofpclass_v16f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v3.8h, v3.8h, v3.8h
+; AARCH64-NEXT:    fminnm v1.8h, v1.8h, v1.8h
+; AARCH64-NEXT:    fmaxnm v0.8h, v0.8h, v2.8h
+; AARCH64-NEXT:    fmaxnm v1.8h, v1.8h, v3.8h
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <16 x half> @llvm.maximumnum.v16f16(<16 x half> %a, <16 x half> %b)
+  ret <16 x half> %c
+}
+
+;;;;;;;;;;;;;;;;  min_f64
+define double @min_nofpclass_f64(double nofpclass(nan) %a, double nofpclass(nan) %b) {
+; AARCH64-LABEL: min_nofpclass_f64:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm d0, d0, d1
+; AARCH64-NEXT:    ret
+entry:
+  %c = call double @llvm.minimumnum.f64(double %a, double %b)
+  ret double %c
+}
+
+define <2 x double> @min_nofpclass_v2f64(<2 x double> nofpclass(nan) %a, <2 x double> nofpclass(nan) %b) {
+; AARCH64-LABEL: min_nofpclass_v2f64:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v0.2d, v0.2d, v1.2d
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <2 x double> @llvm.minimumnum.v2f64(<2 x double> %a, <2 x double> %b)
+  ret <2 x double> %c
+}
+
+define <3 x double> @min_nofpclass_v3f64(<3 x double> nofpclass(nan) %a, <3 x double> nofpclass(nan) %b) {
+; AARCH64-LABEL: min_nofpclass_v3f64:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    // kill: def $d3 killed $d3 def $q3
+; AARCH64-NEXT:    // kill: def $d0 killed $d0 def $q0
+; AARCH64-NEXT:    // kill: def $d4 killed $d4 def $q4
+; AARCH64-NEXT:    // kill: def $d1 killed $d1 def $q1
+; AARCH64-NEXT:    // kill: def $d2 killed $d2 def $q2
+; AARCH64-NEXT:    // kill: def $d5 killed $d5 def $q5
+; AARCH64-NEXT:    mov v0.d[1], v1.d[0]
+; AARCH64-NEXT:    mov v3.d[1], v4.d[0]
+; AARCH64-NEXT:    fminnm v2.2d, v2.2d, v2.2d
+; AARCH64-NEXT:    fminnm v1.2d, v3.2d, v3.2d
+; AARCH64-NEXT:    fminnm v0.2d, v0.2d, v0.2d
+; AARCH64-NEXT:    fminnm v0.2d, v0.2d, v1.2d
+; AARCH64-NEXT:    fminnm v1.2d, v5.2d, v5.2d
+; AARCH64-NEXT:    fminnm v2.2d, v2.2d, v1.2d
+; AARCH64-NEXT:    ext v1.16b, v0.16b, v0.16b, #8
+; AARCH64-NEXT:    // kill: def $d0 killed $d0 killed $q0
+; AARCH64-NEXT:    // kill: def $d1 killed $d1 killed $q1
+; AARCH64-NEXT:    // kill: def $d2 killed $d2 killed $q2
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <3 x double> @llvm.minimumnum.v3f64(<3 x double> %a, <3 x double> %b)
+  ret <3 x double> %c
+}
+
+define <4 x double> @min_nofpclass_v4f64(<4 x double> nofpclass(nan) %a, <4 x double> nofpclass(nan) %b) {
+; AARCH64-LABEL: min_nofpclass_v4f64:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v3.2d, v3.2d, v3.2d
+; AARCH64-NEXT:    fminnm v1.2d, v1.2d, v1.2d
+; AARCH64-NEXT:    fminnm v0.2d, v0.2d, v2.2d
+; AARCH64-NEXT:    fminnm v1.2d, v1.2d, v3.2d
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <4 x double> @llvm.minimumnum.v4f64(<4 x double> %a, <4 x double> %b)
+  ret <4 x double> %c
+}
+
+define <2 x float> @min_nofpclass_v2f32(<2 x float> nofpclass(nan) %a, <2 x float> nofpclass(nan) %b) {
+; AARCH64-LABEL: min_nofpclass_v2f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v0.2s, v0.2s, v1.2s
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <2 x float> @llvm.minimumnum.v2f32(<2 x float> %a, <2 x float> %b)
+  ret <2 x float> %c
+}
+
+define <3 x float> @min_nofpclass_v3f32(<3 x float> nofpclass(nan) %a, <3 x float> nofpclass(nan) %b) {
+; AARCH64-LABEL: min_nofpclass_v3f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v0.4s, v0.4s, v1.4s
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <3 x float> @llvm.minimumnum.v3f32(<3 x float> %a, <3 x float> %b)
+  ret <3 x float> %c
+}
+
+define <4 x float> @min_nofpclass_v4f32(<4 x float> nofpclass(nan) %a, <4 x float> nofpclass(nan) %b) {
+; AARCH64-LABEL: min_nofpclass_v4f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v0.4s, v0.4s, v1.4s
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <4 x float> @llvm.minimumnum.v4f32(<4 x float> %a, <4 x float> %b)
+  ret <4 x float> %c
+}
+
+define <5 x float> @min_nofpclass_v5f32(<5 x float> nofpclass(nan) %a, <5 x float> nofpclass(nan) %b) {
+; AARCH64-LABEL: min_nofpclass_v5f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    // kill: def $s0 killed $s0 def $q0
+; AARCH64-NEXT:    // kill: def $s5 killed $s5 def $q5
+; AARCH64-NEXT:    // kill: def $s1 killed $s1 def $q1
+; AARCH64-NEXT:    // kill: def $s6 killed $s6 def $q6
+; AARCH64-NEXT:    // kill: def $s2 killed $s2 def $q2
+; AARCH64-NEXT:    // kill: def $s7 killed $s7 def $q7
+; AARCH64-NEXT:    // kill: def $s3 killed $s3 def $q3
+; AARCH64-NEXT:    mov x8, sp
+; AARCH64-NEXT:    // kill: def $s4 killed $s4 def $q4
+; AARCH64-NEXT:    mov v0.s[1], v1.s[0]
+; AARCH64-NEXT:    mov v5.s[1], v6.s[0]
+; AARCH64-NEXT:    mov v0.s[2], v2.s[0]
+; AARCH64-NEXT:    mov v5.s[2], v7.s[0]
+; AARCH64-NEXT:    ldr s2, [sp, #8]
+; AARCH64-NEXT:    fminnm v2.4s, v2.4s, v2.4s
+; AARCH64-NEXT:    mov v0.s[3], v3.s[0]
+; AARCH64-NEXT:    ld1 { v5.s }[3], [x8]
+; AARCH64-NEXT:    fminnm v3.4s, v4.4s, v4.4s
+; AARCH64-NEXT:    fminnm v1.4s, v5.4s, v5.4s
+; AARCH64-NEXT:    fminnm v0.4s, v0.4s, v0.4s
+; AARCH64-NEXT:    fminnm v4.4s, v3.4s, v2.4s
+; AARCH64-NEXT:    // kill: def $s4 killed $s4 killed $q4
+; AARCH64-NEXT:    fminnm v0.4s, v0.4s, v1.4s
+; AARCH64-NEXT:    mov s1, v0.s[1]
+; AARCH64-NEXT:    mov s2, v0.s[2]
+; AARCH64-NEXT:    mov s3, v0.s[3]
+; AARCH64-NEXT:    // kill: def $s0 killed $s0 killed $q0
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <5 x float> @llvm.minimumnum.v5f32(<5 x float> %a, <5 x float> %b)
+  ret <5 x float> %c
+}
+
+define <8 x float> @min_nofpclass_v8f32(<8 x float> nofpclass(nan) %a, <8 x float> nofpclass(nan) %b) {
+; AARCH64-LABEL: min_nofpclass_v8f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v3.4s, v3.4s, v3.4s
+; AARCH64-NEXT:    fminnm v1.4s, v1.4s, v1.4s
+; AARCH64-NEXT:    fminnm v0.4s, v0.4s, v2.4s
+; AARCH64-NEXT:    fminnm v1.4s, v1.4s, v3.4s
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <8 x float> @llvm.minimumnum.v8f32(<8 x float> %a, <8 x float> %b)
+  ret <8 x float> %c
+}
+
+;;;;;;;;;;;;;;;;;; min_f16
+define half @min_nofpclass_f16(half nofpclass(nan) %a, half nofpclass(nan) %b) {
+; AARCH64-LABEL: min_nofpclass_f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm h0, h0, h1
+; AARCH64-NEXT:    ret
+entry:
+  %c = call half @llvm.minimumnum.f16(half %a, half %b)
+  ret half %c
+}
+
+define <2 x half> @min_nofpclass_v2f16(<2 x half> nofpclass(nan) %a, <2 x half> nofpclass(nan) %b) {
+; AARCH64-LABEL: min_nofpclass_v2f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v0.4h, v0.4h, v1.4h
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <2 x half> @llvm.minimumnum.v2f16(<2 x half> %a, <2 x half> %b)
+  ret <2 x half> %c
+}
+
+define <4 x half> @min_nofpclass_v4f16(<4 x half> nofpclass(nan) %a, <4 x half> nofpclass(nan) %b) {
+; AARCH64-LABEL: min_nofpclass_v4f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v0.4h, v0.4h, v1.4h
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <4 x half> @llvm.minimumnum.v4f16(<4 x half> %a, <4 x half> %b)
+  ret <4 x half> %c
+}
+
+define <8 x half> @min_nofpclass_v8f16(<8 x half> nofpclass(nan) %a, <8 x half> nofpclass(nan) %b) {
+; AARCH64-LABEL: min_nofpclass_v8f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v0.8h, v0.8h, v1.8h
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <8 x half> @llvm.minimumnum.v8f16(<8 x half> %a, <8 x half> %b)
+  ret <8 x half> %c
+}
+
+define <9 x half> @min_nofpclass_v9f16(<9 x half> nofpclass(nan) %a, <9 x half> nofpclass(nan) %b) {
+; AARCH64-LABEL: min_nofpclass_v9f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    // kill: def $h0 killed $h0 def $q0
+; AARCH64-NEXT:    // kill: def $h1 killed $h1 def $q1
+; AARCH64-NEXT:    // kill: def $h2 killed $h2 def $q2
+; AARCH64-NEXT:    add x9, sp, #16
+; AARCH64-NEXT:    // kill: def $h3 killed $h3 def $q3
+; AARCH64-NEXT:    // kill: def $h4 killed $h4 def $q4
+; AARCH64-NEXT:    // kill: def $h5 killed $h5 def $q5
+; AARCH64-NEXT:    // kill: def $h6 killed $h6 def $q6
+; AARCH64-NEXT:    // kill: def $h7 killed $h7 def $q7
+; AARCH64-NEXT:    mov v0.h[1], v1.h[0]
+; AARCH64-NEXT:    ldr h1, [sp, #8]
+; AARCH64-NEXT:    ld1 { v1.h }[1], [x9]
+; AARCH64-NEXT:    add x9, sp, #24
+; AARCH64-NEXT:    mov v0.h[2], v2.h[0]
+; AARCH64-NEXT:    ldr h2, [sp]
+; AARCH64-NEXT:    ld1 { v1.h }[2], [x9]
+; AARCH64-NEXT:    add x9, sp, #32
+; AARCH64-NEXT:    fminnm v2.8h, v2.8h, v2.8h
+; AARCH64-NEXT:    mov v0.h[3], v3.h[0]
+; AARCH64-NEXT:    ld1 { v1.h }[3], [x9]
+; AARCH64-NEXT:    add x9, sp, #40
+; AARCH64-NEXT:    ldr h3, [sp, #72]
+; AARCH64-NEXT:    ld1 { v1.h }[4], [x9]
+; AARCH64-NEXT:    add x9, sp, #48
+; AARCH64-NEXT:    fminnm v3.8h, v3.8h, v3.8h
+; AARCH64-NEXT:    mov v0.h[4], v4.h[0]
+; AARCH64-NEXT:    ld1 { v1.h }[5], [x9]
+; AARCH64-NEXT:    add x9, sp, #56
+; AARCH64-NEXT:    fminnm v2.8h, v2.8h, v3.8h
+; AARCH64-NEXT:    mov v0.h[5], v5.h[0]
+; AARCH64-NEXT:    ld1 { v1.h }[6], [x9]
+; AARCH64-NEXT:    add x9, sp, #64
+; AARCH64-NEXT:    str h2, [x8, #16]
+; AARCH64-NEXT:    mov v0.h[6], v6.h[0]
+; AARCH64-NEXT:    ld1 { v1.h }[7], [x9]
+; AARCH64-NEXT:    fminnm v1.8h, v1.8h, v1.8h
+; AARCH64-NEXT:    mov v0.h[7], v7.h[0]
+; AARCH64-NEXT:    fminnm v0.8h, v0.8h, v0.8h
+; AARCH64-NEXT:    fminnm v0.8h, v0.8h, v1.8h
+; AARCH64-NEXT:    str q0, [x8]
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <9 x half> @llvm.minimumnum.v9f16(<9 x half> %a, <9 x half> %b)
+  ret <9 x half> %c
+}
+
+define <16 x half> @min_nofpclass_v16f16(<16 x half> nofpclass(nan) %a, <16 x half> nofpclass(nan) %b) {
+; AARCH64-LABEL: min_nofpclass_v16f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v3.8h, v3.8h, v3.8h
+; AARCH64-NEXT:    fminnm v1.8h, v1.8h, v1.8h
+; AARCH64-NEXT:    fminnm v0.8h, v0.8h, v2.8h
+; AARCH64-NEXT:    fminnm v1.8h, v1.8h, v3.8h
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <16 x half> @llvm.minimumnum.v16f16(<16 x half> %a, <16 x half> %b)
+  ret <16 x half> %c
+}
+
+
+;;;;;;;;;;;;;;;;  max_f64
+define double @max_nofpclass_s_f64(double nofpclass(snan) %a, double nofpclass(snan) %b) {
+; AARCH64-LABEL: max_nofpclass_s_f64:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm d0, d0, d1
+; AARCH64-NEXT:    ret
+entry:
+  %c = call double @llvm.maximumnum.f64(double %a, double %b)
+  ret double %c
+}
+
+define <2 x double> @max_nofpclass_s_v2f64(<2 x double> nofpclass(snan) %a, <2 x double> nofpclass(snan) %b) {
+; AARCH64-LABEL: max_nofpclass_s_v2f64:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm v0.2d, v0.2d, v1.2d
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <2 x double> @llvm.maximumnum.v2f64(<2 x double> %a, <2 x double> %b)
+  ret <2 x double> %c
+}
+
+define <3 x double> @max_nofpclass_s_v3f64(<3 x double> nofpclass(snan) %a, <3 x double> nofpclass(snan) %b) {
+; AARCH64-LABEL: max_nofpclass_s_v3f64:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    // kill: def $d3 killed $d3 def $q3
+; AARCH64-NEXT:    // kill: def $d0 killed $d0 def $q0
+; AARCH64-NEXT:    // kill: def $d4 killed $d4 def $q4
+; AARCH64-NEXT:    // kill: def $d1 killed $d1 def $q1
+; AARCH64-NEXT:    // kill: def $d2 killed $d2 def $q2
+; AARCH64-NEXT:    // kill: def $d5 killed $d5 def $q5
+; AARCH64-NEXT:    mov v0.d[1], v1.d[0]
+; AARCH64-NEXT:    mov v3.d[1], v4.d[0]
+; AARCH64-NEXT:    fminnm v2.2d, v2.2d, v2.2d
+; AARCH64-NEXT:    fminnm v1.2d, v3.2d, v3.2d
+; AARCH64-NEXT:    fminnm v0.2d, v0.2d, v0.2d
+; AARCH64-NEXT:    fmaxnm v0.2d, v0.2d, v1.2d
+; AARCH64-NEXT:    fminnm v1.2d, v5.2d, v5.2d
+; AARCH64-NEXT:    fmaxnm v2.2d, v2.2d, v1.2d
+; AARCH64-NEXT:    ext v1.16b, v0.16b, v0.16b, #8
+; AARCH64-NEXT:    // kill: def $d0 killed $d0 killed $q0
+; AARCH64-NEXT:    // kill: def $d1 killed $d1 killed $q1
+; AARCH64-NEXT:    // kill: def $d2 killed $d2 killed $q2
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <3 x double> @llvm.maximumnum.v3f64(<3 x double> %a, <3 x double> %b)
+  ret <3 x double> %c
+}
+
+define <4 x double> @max_nofpclass_s_v4f64(<4 x double> nofpclass(snan) %a, <4 x double> nofpclass(snan) %b) {
+; AARCH64-LABEL: max_nofpclass_s_v4f64:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v3.2d, v3.2d, v3.2d
+; AARCH64-NEXT:    fminnm v1.2d, v1.2d, v1.2d
+; AARCH64-NEXT:    fmaxnm v0.2d, v0.2d, v2.2d
+; AARCH64-NEXT:    fmaxnm v1.2d, v1.2d, v3.2d
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <4 x double> @llvm.maximumnum.v4f64(<4 x double> %a, <4 x double> %b)
+  ret <4 x double> %c
+}
+
+;;;;;;;;;;;;;;;;;; max_f32
+define float @max_nofpclass_s_f32(float nofpclass(snan) %a, float nofpclass(snan) %b) {
+; AARCH64-LABEL: max_nofpclass_s_f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm s0, s0, s1
+; AARCH64-NEXT:    ret
+entry:
+  %c = call float @llvm.maximumnum.f32(float %a, float %b)
+  ret float %c
+}
+
+define <2 x float> @max_nofpclass_s_v2f32(<2 x float> nofpclass(snan) %a, <2 x float> nofpclass(snan) %b) {
+; AARCH64-LABEL: max_nofpclass_s_v2f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm v0.2s, v0.2s, v1.2s
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <2 x float> @llvm.maximumnum.v2f32(<2 x float> %a, <2 x float> %b)
+  ret <2 x float> %c
+}
+
+define <3 x float> @max_nofpclass_s_v3f32(<3 x float> nofpclass(snan) %a, <3 x float> nofpclass(snan) %b) {
+; AARCH64-LABEL: max_nofpclass_s_v3f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm v0.4s, v0.4s, v1.4s
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <3 x float> @llvm.maximumnum.v3f32(<3 x float> %a, <3 x float> %b)
+  ret <3 x float> %c
+}
+
+define <4 x float> @max_nofpclass_s_v4f32(<4 x float> nofpclass(snan) %a, <4 x float> nofpclass(snan) %b) {
+; AARCH64-LABEL: max_nofpclass_s_v4f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm v0.4s, v0.4s, v1.4s
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <4 x float> @llvm.maximumnum.v4f32(<4 x float> %a, <4 x float> %b)
+  ret <4 x float> %c
+}
+
+define <5 x float> @max_nofpclass_s_v5f32(<5 x float> nofpclass(snan) %a, <5 x float> nofpclass(snan) %b) {
+; AARCH64-LABEL: max_nofpclass_s_v5f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    // kill: def $s0 killed $s0 def $q0
+; AARCH64-NEXT:    // kill: def $s5 killed $s5 def $q5
+; AARCH64-NEXT:    // kill: def $s1 killed $s1 def $q1
+; AARCH64-NEXT:    // kill: def $s6 killed $s6 def $q6
+; AARCH64-NEXT:    // kill: def $s2 killed $s2 def $q2
+; AARCH64-NEXT:    // kill: def $s7 killed $s7 def $q7
+; AARCH64-NEXT:    // kill: def $s3 killed $s3 def $q3
+; AARCH64-NEXT:    mov x8, sp
+; AARCH64-NEXT:    // kill: def $s4 killed $s4 def $q4
+; AARCH64-NEXT:    mov v0.s[1], v1.s[0]
+; AARCH64-NEXT:    mov v5.s[1], v6.s[0]
+; AARCH64-NEXT:    mov v0.s[2], v2.s[0]
+; AARCH64-NEXT:    mov v5.s[2], v7.s[0]
+; AARCH64-NEXT:    ldr s2, [sp, #8]
+; AARCH64-NEXT:    fminnm v2.4s, v2.4s, v2.4s
+; AARCH64-NEXT:    mov v0.s[3], v3.s[0]
+; AARCH64-NEXT:    ld1 { v5.s }[3], [x8]
+; AARCH64-NEXT:    fminnm v3.4s, v4.4s, v4.4s
+; AARCH64-NEXT:    fminnm v1.4s, v5.4s, v5.4s
+; AARCH64-NEXT:    fminnm v0.4s, v0.4s, v0.4s
+; AARCH64-NEXT:    fmaxnm v4.4s, v3.4s, v2.4s
+; AARCH64-NEXT:    // kill: def $s4 killed $s4 killed $q4
+; AARCH64-NEXT:    fmaxnm v0.4s, v0.4s, v1.4s
+; AARCH64-NEXT:    mov s1, v0.s[1]
+; AARCH64-NEXT:    mov s2, v0.s[2]
+; AARCH64-NEXT:    mov s3, v0.s[3]
+; AARCH64-NEXT:    // kill: def $s0 killed $s0 killed $q0
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <5 x float> @llvm.maximumnum.v5f32(<5 x float> %a, <5 x float> %b)
+  ret <5 x float> %c
+}
+
+define <8 x float> @max_nofpclass_s_v8f32(<8 x float> nofpclass(snan) %a, <8 x float> nofpclass(snan) %b) {
+; AARCH64-LABEL: max_nofpclass_s_v8f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v3.4s, v3.4s, v3.4s
+; AARCH64-NEXT:    fminnm v1.4s, v1.4s, v1.4s
+; AARCH64-NEXT:    fmaxnm v0.4s, v0.4s, v2.4s
+; AARCH64-NEXT:    fmaxnm v1.4s, v1.4s, v3.4s
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <8 x float> @llvm.maximumnum.v8f32(<8 x float> %a, <8 x float> %b)
+  ret <8 x float> %c
+}
+
+define <2 x half> @max_nofpclass_s_v2f16(<2 x half> nofpclass(snan) %a, <2 x half> nofpclass(snan) %b) {
+; AARCH64-LABEL: max_nofpclass_s_v2f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm v0.4h, v0.4h, v1.4h
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <2 x half> @llvm.maximumnum.v2f16(<2 x half> %a, <2 x half> %b)
+  ret <2 x half> %c
+}
+
+define <4 x half> @max_nofpclass_s_v4f16(<4 x half> nofpclass(snan) %a, <4 x half> nofpclass(snan) %b) {
+; AARCH64-LABEL: max_nofpclass_s_v4f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm v0.4h, v0.4h, v1.4h
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <4 x half> @llvm.maximumnum.v4f16(<4 x half> %a, <4 x half> %b)
+  ret <4 x half> %c
+}
+
+define <8 x half> @max_nofpclass_s_v8f16(<8 x half> nofpclass(snan) %a, <8 x half> nofpclass(snan) %b) {
+; AARCH64-LABEL: max_nofpclass_s_v8f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fmaxnm v0.8h, v0.8h, v1.8h
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <8 x half> @llvm.maximumnum.v8f16(<8 x half> %a, <8 x half> %b)
+  ret <8 x half> %c
+}
+
+define <9 x half> @max_nofpclass_s_v9f16(<9 x half> nofpclass(snan) %a, <9 x half> nofpclass(snan) %b) {
+; AARCH64-LABEL: max_nofpclass_s_v9f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    // kill: def $h0 killed $h0 def $q0
+; AARCH64-NEXT:    // kill: def $h1 killed $h1 def $q1
+; AARCH64-NEXT:    // kill: def $h2 killed $h2 def $q2
+; AARCH64-NEXT:    add x9, sp, #16
+; AARCH64-NEXT:    // kill: def $h3 killed $h3 def $q3
+; AARCH64-NEXT:    // kill: def $h4 killed $h4 def $q4
+; AARCH64-NEXT:    // kill: def $h5 killed $h5 def $q5
+; AARCH64-NEXT:    // kill: def $h6 killed $h6 def $q6
+; AARCH64-NEXT:    // kill: def $h7 killed $h7 def $q7
+; AARCH64-NEXT:    mov v0.h[1], v1.h[0]
+; AARCH64-NEXT:    ldr h1, [sp, #8]
+; AARCH64-NEXT:    ld1 { v1.h }[1], [x9]
+; AARCH64-NEXT:    add x9, sp, #24
+; AARCH64-NEXT:    mov v0.h[2], v2.h[0]
+; AARCH64-NEXT:    ldr h2, [sp]
+; AARCH64-NEXT:    ld1 { v1.h }[2], [x9]
+; AARCH64-NEXT:    add x9, sp, #32
+; AARCH64-NEXT:    fminnm v2.8h, v2.8h, v2.8h
+; AARCH64-NEXT:    mov v0.h[3], v3.h[0]
+; AARCH64-NEXT:    ld1 { v1.h }[3], [x9]
+; AARCH64-NEXT:    add x9, sp, #40
+; AARCH64-NEXT:    ldr h3, [sp, #72]
+; AARCH64-NEXT:    ld1 { v1.h }[4], [x9]
+; AARCH64-NEXT:    add x9, sp, #48
+; AARCH64-NEXT:    fminnm v3.8h, v3.8h, v3.8h
+; AARCH64-NEXT:    mov v0.h[4], v4.h[0]
+; AARCH64-NEXT:    ld1 { v1.h }[5], [x9]
+; AARCH64-NEXT:    add x9, sp, #56
+; AARCH64-NEXT:    fmaxnm v2.8h, v2.8h, v3.8h
+; AARCH64-NEXT:    mov v0.h[5], v5.h[0]
+; AARCH64-NEXT:    ld1 { v1.h }[6], [x9]
+; AARCH64-NEXT:    add x9, sp, #64
+; AARCH64-NEXT:    str h2, [x8, #16]
+; AARCH64-NEXT:    mov v0.h[6], v6.h[0]
+; AARCH64-NEXT:    ld1 { v1.h }[7], [x9]
+; AARCH64-NEXT:    fminnm v1.8h, v1.8h, v1.8h
+; AARCH64-NEXT:    mov v0.h[7], v7.h[0]
+; AARCH64-NEXT:    fminnm v0.8h, v0.8h, v0.8h
+; AARCH64-NEXT:    fmaxnm v0.8h, v0.8h, v1.8h
+; AARCH64-NEXT:    str q0, [x8]
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <9 x half> @llvm.maximumnum.v9f16(<9 x half> %a, <9 x half> %b)
+  ret <9 x half> %c
+}
+
+define <16 x half> @max_nofpclass_s_v16f16(<16 x half> nofpclass(snan) %a, <16 x half> nofpclass(snan) %b) {
+; AARCH64-LABEL: max_nofpclass_s_v16f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v3.8h, v3.8h, v3.8h
+; AARCH64-NEXT:    fminnm v1.8h, v1.8h, v1.8h
+; AARCH64-NEXT:    fmaxnm v0.8h, v0.8h, v2.8h
+; AARCH64-NEXT:    fmaxnm v1.8h, v1.8h, v3.8h
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <16 x half> @llvm.maximumnum.v16f16(<16 x half> %a, <16 x half> %b)
+  ret <16 x half> %c
+}
+
+;;;;;;;;;;;;;;;;  min_f64
+define double @min_nofpclass_s_f64(double nofpclass(snan) %a, double nofpclass(snan) %b) {
+; AARCH64-LABEL: min_nofpclass_s_f64:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm d0, d0, d1
+; AARCH64-NEXT:    ret
+entry:
+  %c = call double @llvm.minimumnum.f64(double %a, double %b)
+  ret double %c
+}
+
+define <2 x double> @min_nofpclass_s_v2f64(<2 x double> nofpclass(snan) %a, <2 x double> nofpclass(snan) %b) {
+; AARCH64-LABEL: min_nofpclass_s_v2f64:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v0.2d, v0.2d, v1.2d
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <2 x double> @llvm.minimumnum.v2f64(<2 x double> %a, <2 x double> %b)
+  ret <2 x double> %c
+}
+
+define <3 x double> @min_nofpclass_s_v3f64(<3 x double> nofpclass(snan) %a, <3 x double> nofpclass(snan) %b) {
+; AARCH64-LABEL: min_nofpclass_s_v3f64:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    // kill: def $d3 killed $d3 def $q3
+; AARCH64-NEXT:    // kill: def $d0 killed $d0 def $q0
+; AARCH64-NEXT:    // kill: def $d4 killed $d4 def $q4
+; AARCH64-NEXT:    // kill: def $d1 killed $d1 def $q1
+; AARCH64-NEXT:    // kill: def $d2 killed $d2 def $q2
+; AARCH64-NEXT:    // kill: def $d5 killed $d5 def $q5
+; AARCH64-NEXT:    mov v0.d[1], v1.d[0]
+; AARCH64-NEXT:    mov v3.d[1], v4.d[0]
+; AARCH64-NEXT:    fminnm v2.2d, v2.2d, v2.2d
+; AARCH64-NEXT:    fminnm v1.2d, v3.2d, v3.2d
+; AARCH64-NEXT:    fminnm v0.2d, v0.2d, v0.2d
+; AARCH64-NEXT:    fminnm v0.2d, v0.2d, v1.2d
+; AARCH64-NEXT:    fminnm v1.2d, v5.2d, v5.2d
+; AARCH64-NEXT:    fminnm v2.2d, v2.2d, v1.2d
+; AARCH64-NEXT:    ext v1.16b, v0.16b, v0.16b, #8
+; AARCH64-NEXT:    // kill: def $d0 killed $d0 killed $q0
+; AARCH64-NEXT:    // kill: def $d1 killed $d1 killed $q1
+; AARCH64-NEXT:    // kill: def $d2 killed $d2 killed $q2
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <3 x double> @llvm.minimumnum.v3f64(<3 x double> %a, <3 x double> %b)
+  ret <3 x double> %c
+}
+
+define <4 x double> @min_nofpclass_s_v4f64(<4 x double> nofpclass(snan) %a, <4 x double> nofpclass(snan) %b) {
+; AARCH64-LABEL: min_nofpclass_s_v4f64:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v3.2d, v3.2d, v3.2d
+; AARCH64-NEXT:    fminnm v1.2d, v1.2d, v1.2d
+; AARCH64-NEXT:    fminnm v0.2d, v0.2d, v2.2d
+; AARCH64-NEXT:    fminnm v1.2d, v1.2d, v3.2d
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <4 x double> @llvm.minimumnum.v4f64(<4 x double> %a, <4 x double> %b)
+  ret <4 x double> %c
+}
+
+define <2 x float> @min_nofpclass_s_v2f32(<2 x float> nofpclass(snan) %a, <2 x float> nofpclass(snan) %b) {
+; AARCH64-LABEL: min_nofpclass_s_v2f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v0.2s, v0.2s, v1.2s
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <2 x float> @llvm.minimumnum.v2f32(<2 x float> %a, <2 x float> %b)
+  ret <2 x float> %c
+}
+
+define <3 x float> @min_nofpclass_s_v3f32(<3 x float> nofpclass(snan) %a, <3 x float> nofpclass(snan) %b) {
+; AARCH64-LABEL: min_nofpclass_s_v3f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v0.4s, v0.4s, v1.4s
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <3 x float> @llvm.minimumnum.v3f32(<3 x float> %a, <3 x float> %b)
+  ret <3 x float> %c
+}
+
+define <4 x float> @min_nofpclass_s_v4f32(<4 x float> nofpclass(snan) %a, <4 x float> nofpclass(snan) %b) {
+; AARCH64-LABEL: min_nofpclass_s_v4f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v0.4s, v0.4s, v1.4s
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <4 x float> @llvm.minimumnum.v4f32(<4 x float> %a, <4 x float> %b)
+  ret <4 x float> %c
+}
+
+define <5 x float> @min_nofpclass_s_v5f32(<5 x float> nofpclass(snan) %a, <5 x float> nofpclass(snan) %b) {
+; AARCH64-LABEL: min_nofpclass_s_v5f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    // kill: def $s0 killed $s0 def $q0
+; AARCH64-NEXT:    // kill: def $s5 killed $s5 def $q5
+; AARCH64-NEXT:    // kill: def $s1 killed $s1 def $q1
+; AARCH64-NEXT:    // kill: def $s6 killed $s6 def $q6
+; AARCH64-NEXT:    // kill: def $s2 killed $s2 def $q2
+; AARCH64-NEXT:    // kill: def $s7 killed $s7 def $q7
+; AARCH64-NEXT:    // kill: def $s3 killed $s3 def $q3
+; AARCH64-NEXT:    mov x8, sp
+; AARCH64-NEXT:    // kill: def $s4 killed $s4 def $q4
+; AARCH64-NEXT:    mov v0.s[1], v1.s[0]
+; AARCH64-NEXT:    mov v5.s[1], v6.s[0]
+; AARCH64-NEXT:    mov v0.s[2], v2.s[0]
+; AARCH64-NEXT:    mov v5.s[2], v7.s[0]
+; AARCH64-NEXT:    ldr s2, [sp, #8]
+; AARCH64-NEXT:    fminnm v2.4s, v2.4s, v2.4s
+; AARCH64-NEXT:    mov v0.s[3], v3.s[0]
+; AARCH64-NEXT:    ld1 { v5.s }[3], [x8]
+; AARCH64-NEXT:    fminnm v3.4s, v4.4s, v4.4s
+; AARCH64-NEXT:    fminnm v1.4s, v5.4s, v5.4s
+; AARCH64-NEXT:    fminnm v0.4s, v0.4s, v0.4s
+; AARCH64-NEXT:    fminnm v4.4s, v3.4s, v2.4s
+; AARCH64-NEXT:    // kill: def $s4 killed $s4 killed $q4
+; AARCH64-NEXT:    fminnm v0.4s, v0.4s, v1.4s
+; AARCH64-NEXT:    mov s1, v0.s[1]
+; AARCH64-NEXT:    mov s2, v0.s[2]
+; AARCH64-NEXT:    mov s3, v0.s[3]
+; AARCH64-NEXT:    // kill: def $s0 killed $s0 killed $q0
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <5 x float> @llvm.minimumnum.v5f32(<5 x float> %a, <5 x float> %b)
+  ret <5 x float> %c
+}
+
+define <8 x float> @min_nofpclass_s_v8f32(<8 x float> nofpclass(snan) %a, <8 x float> nofpclass(snan) %b) {
+; AARCH64-LABEL: min_nofpclass_s_v8f32:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v3.4s, v3.4s, v3.4s
+; AARCH64-NEXT:    fminnm v1.4s, v1.4s, v1.4s
+; AARCH64-NEXT:    fminnm v0.4s, v0.4s, v2.4s
+; AARCH64-NEXT:    fminnm v1.4s, v1.4s, v3.4s
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <8 x float> @llvm.minimumnum.v8f32(<8 x float> %a, <8 x float> %b)
+  ret <8 x float> %c
+}
+
+;;;;;;;;;;;;;;;;;; min_f16
+define half @min_nofpclass_s_f16(half nofpclass(snan) %a, half nofpclass(snan) %b) {
+; AARCH64-LABEL: min_nofpclass_s_f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm h0, h0, h1
+; AARCH64-NEXT:    ret
+entry:
+  %c = call half @llvm.minimumnum.f16(half %a, half %b)
+  ret half %c
+}
+
+define <2 x half> @min_nofpclass_s_v2f16(<2 x half> nofpclass(snan) %a, <2 x half> nofpclass(snan) %b) {
+; AARCH64-LABEL: min_nofpclass_s_v2f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v0.4h, v0.4h, v1.4h
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <2 x half> @llvm.minimumnum.v2f16(<2 x half> %a, <2 x half> %b)
+  ret <2 x half> %c
+}
+
+define <4 x half> @min_nofpclass_s_v4f16(<4 x half> nofpclass(snan) %a, <4 x half> nofpclass(snan) %b) {
+; AARCH64-LABEL: min_nofpclass_s_v4f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v0.4h, v0.4h, v1.4h
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <4 x half> @llvm.minimumnum.v4f16(<4 x half> %a, <4 x half> %b)
+  ret <4 x half> %c
+}
+
+define <8 x half> @min_nofpclass_s_v8f16(<8 x half> nofpclass(snan) %a, <8 x half> nofpclass(snan) %b) {
+; AARCH64-LABEL: min_nofpclass_s_v8f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v0.8h, v0.8h, v1.8h
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <8 x half> @llvm.minimumnum.v8f16(<8 x half> %a, <8 x half> %b)
+  ret <8 x half> %c
+}
+
+define <9 x half> @min_nofpclass_s_v9f16(<9 x half> nofpclass(snan) %a, <9 x half> nofpclass(snan) %b) {
+; AARCH64-LABEL: min_nofpclass_s_v9f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    // kill: def $h0 killed $h0 def $q0
+; AARCH64-NEXT:    // kill: def $h1 killed $h1 def $q1
+; AARCH64-NEXT:    // kill: def $h2 killed $h2 def $q2
+; AARCH64-NEXT:    add x9, sp, #16
+; AARCH64-NEXT:    // kill: def $h3 killed $h3 def $q3
+; AARCH64-NEXT:    // kill: def $h4 killed $h4 def $q4
+; AARCH64-NEXT:    // kill: def $h5 killed $h5 def $q5
+; AARCH64-NEXT:    // kill: def $h6 killed $h6 def $q6
+; AARCH64-NEXT:    // kill: def $h7 killed $h7 def $q7
+; AARCH64-NEXT:    mov v0.h[1], v1.h[0]
+; AARCH64-NEXT:    ldr h1, [sp, #8]
+; AARCH64-NEXT:    ld1 { v1.h }[1], [x9]
+; AARCH64-NEXT:    add x9, sp, #24
+; AARCH64-NEXT:    mov v0.h[2], v2.h[0]
+; AARCH64-NEXT:    ldr h2, [sp]
+; AARCH64-NEXT:    ld1 { v1.h }[2], [x9]
+; AARCH64-NEXT:    add x9, sp, #32
+; AARCH64-NEXT:    fminnm v2.8h, v2.8h, v2.8h
+; AARCH64-NEXT:    mov v0.h[3], v3.h[0]
+; AARCH64-NEXT:    ld1 { v1.h }[3], [x9]
+; AARCH64-NEXT:    add x9, sp, #40
+; AARCH64-NEXT:    ldr h3, [sp, #72]
+; AARCH64-NEXT:    ld1 { v1.h }[4], [x9]
+; AARCH64-NEXT:    add x9, sp, #48
+; AARCH64-NEXT:    fminnm v3.8h, v3.8h, v3.8h
+; AARCH64-NEXT:    mov v0.h[4], v4.h[0]
+; AARCH64-NEXT:    ld1 { v1.h }[5], [x9]
+; AARCH64-NEXT:    add x9, sp, #56
+; AARCH64-NEXT:    fminnm v2.8h, v2.8h, v3.8h
+; AARCH64-NEXT:    mov v0.h[5], v5.h[0]
+; AARCH64-NEXT:    ld1 { v1.h }[6], [x9]
+; AARCH64-NEXT:    add x9, sp, #64
+; AARCH64-NEXT:    str h2, [x8, #16]
+; AARCH64-NEXT:    mov v0.h[6], v6.h[0]
+; AARCH64-NEXT:    ld1 { v1.h }[7], [x9]
+; AARCH64-NEXT:    fminnm v1.8h, v1.8h, v1.8h
+; AARCH64-NEXT:    mov v0.h[7], v7.h[0]
+; AARCH64-NEXT:    fminnm v0.8h, v0.8h, v0.8h
+; AARCH64-NEXT:    fminnm v0.8h, v0.8h, v1.8h
+; AARCH64-NEXT:    str q0, [x8]
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <9 x half> @llvm.minimumnum.v9f16(<9 x half> %a, <9 x half> %b)
+  ret <9 x half> %c
+}
+
+define <16 x half> @min_nofpclass_s_v16f16(<16 x half> nofpclass(snan) %a, <16 x half> nofpclass(snan) %b) {
+; AARCH64-LABEL: min_nofpclass_s_v16f16:
+; AARCH64:       // %bb.0: // %entry
+; AARCH64-NEXT:    fminnm v3.8h, v3.8h, v3.8h
+; AARCH64-NEXT:    fminnm v1.8h, v1.8h, v1.8h
+; AARCH64-NEXT:    fminnm v0.8h, v0.8h, v2.8h
+; AARCH64-NEXT:    fminnm v1.8h, v1.8h, v3.8h
+; AARCH64-NEXT:    ret
+entry:
+  %c = call <16 x half> @llvm.minimumnum.v16f16(<16 x half> %a, <16 x half> %b)
+  ret <16 x half> %c
+}
diff --git a/llvm/test/CodeGen/LoongArch/fp-maximumnum-minimumnum.ll b/llvm/test/CodeGen/LoongArch/fp-maximumnum-minimumnum.ll
index b4fdd954b856c..b8b47218c9670 100644
--- a/llvm/test/CodeGen/LoongArch/fp-maximumnum-minimumnum.ll
+++ b/llvm/test/CodeGen/LoongArch/fp-maximumnum-minimumnum.ll
@@ -100,6 +100,54 @@ define float @maximumnum_float_nnan(float %x, float %y) {
   ret float %z
 }
 
+define float @maximumnum_float_nofpclass(float nofpclass(nan) %x, float nofpclass(nan) %y) {
+; LA32F-LABEL: maximumnum_float_nofpclass:
+; LA32F:       # %bb.0:
+; LA32F-NEXT:    fmax.s $fa0, $fa0, $fa1
+; LA32F-NEXT:    ret
+;
+; LA32D-LABEL: maximumnum_float_nofpclass:
+; LA32D:       # %bb.0:
+; LA32D-NEXT:    fmax.s $fa0, $fa0, $fa1
+; LA32D-NEXT:    ret
+;
+; LA64F-LABEL: maximumnum_float_nofpclass:
+; LA64F:       # %bb.0:
+; LA64F-NEXT:    fmax.s $fa0, $fa0, $fa1
+; LA64F-NEXT:    ret
+;
+; LA64D-LABEL: maximumnum_float_nofpclass:
+; LA64D:       # %bb.0:
+; LA64D-NEXT:    fmax.s $fa0, $fa0, $fa1
+; LA64D-NEXT:    ret
+  %z = call float @llvm.maximumnum.f32(float %x, float %y)
+  ret float %z
+}
+
+define float @maximumnum_float_nofpclass_s(float nofpclass(snan) %x, float nofpclass(snan) %y) {
+; LA32F-LABEL: maximumnum_float_nofpclass_s:
+; LA32F:       # %bb.0:
+; LA32F-NEXT:    fmax.s $fa0, $fa0, $fa1
+; LA32F-NEXT:    ret
+;
+; LA32D-LABEL: maximumnum_float_nofpclass_s:
+; LA32D:       # %bb.0:
+; LA32D-NEXT:    fmax.s $fa0, $fa0, $fa1
+; LA32D-NEXT:    ret
+;
+; LA64F-LABEL: maximumnum_float_nofpclass_s:
+; LA64F:       # %bb.0:
+; LA64F-NEXT:    fmax.s $fa0, $fa0, $fa1
+; LA64F-NEXT:    ret
+;
+; LA64D-LABEL: maximumnum_float_nofpclass_s:
+; LA64D:       # %bb.0:
+; LA64D-NEXT:    fmax.s $fa0, $fa0, $fa1
+; LA64D-NEXT:    ret
+  %z = call float @llvm.maximumnum.f32(float %x, float %y)
+  ret float %z
+}
+
 
 define double @maximumnum_double(double %x, double %y) {
 ;
@@ -220,6 +268,79 @@ define double @maximumnum_double_nnan(double %x, double %y) {
   ret double %z
 }
 
+define double @maximumnum_double_nofpclass(double nofpclass(nan) %x, double nofpclass(nan) %y) {
+; LA32F-LABEL: maximumnum_double_nofpclass:
+; LA32F:       # %bb.0:
+; LA32F-NEXT:    addi.w $sp, $sp, -16
+; LA32F-NEXT:    .cfi_def_cfa_offset 16
+; LA32F-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
+; LA32F-NEXT:    .cfi_offset 1, -4
+; LA32F-NEXT:    bl %plt(fmaximum_num)
+; LA32F-NEXT:    ld.w $ra, $sp, 12 # 4-byte Folded Reload
+; LA32F-NEXT:    addi.w $sp, $sp, 16
+; LA32F-NEXT:    ret
+;
+; LA32D-LABEL: maximumnum_double_nofpclass:
+; LA32D:       # %bb.0:
+; LA32D-NEXT:    fmax.d $fa0, $fa0, $fa1
+; LA32D-NEXT:    ret
+;
+; LA64F-LABEL: maximumnum_double_nofpclass:
+; LA64F:       # %bb.0:
+; LA64F-NEXT:    addi.d $sp, $sp, -16
+; LA64F-NEXT:    .cfi_def_cfa_offset 16
+; LA64F-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
+; LA64F-NEXT:    .cfi_offset 1, -8
+; LA64F-NEXT:    bl %plt(fmaximum_num)
+; LA64F-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; LA64F-NEXT:    addi.d $sp, $sp, 16
+; LA64F-NEXT:    ret
+;
+; LA64D-LABEL: maximumnum_double_nofpclass:
+; LA64D:       # %bb.0:
+; LA64D-NEXT:    fmax.d $fa0, $fa0, $fa1
+; LA64D-NEXT:    ret
+  %z = call double @llvm.maximumnum.f64(double %x, double %y)
+  ret double %z
+}
+
+define double @maximumnum_double_nofpclass_s(double nofpclass(snan) %x, double nofpclass(snan) %y) {
+; LA32F-LABEL: maximumnum_double_nofpclass_s:
+; LA32F:       # %bb.0:
+; LA32F-NEXT:    addi.w $sp, $sp, -16
+; LA32F-NEXT:    .cfi_def_cfa_offset 16
+; LA32F-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
+; LA32F-NEXT:    .cfi_offset 1, -4
+; LA32F-NEXT:    bl %plt(fmaximum_num)
+; LA32F-NEXT:    ld.w $ra, $sp, 12 # 4-byte Folded Reload
+; LA32F-NEXT:    addi.w $sp, $sp, 16
+; LA32F-NEXT:    ret
+;
+; LA32D-LABEL: maximumnum_double_nofpclass_s:
+; LA32D:       # %bb.0:
+; LA32D-NEXT:    fmax.d $fa0, $fa0, $fa1
+; LA32D-NEXT:    ret
+;
+; LA64F-LABEL: maximumnum_double_nofpclass_s:
+; LA64F:       # %bb.0:
+; LA64F-NEXT:    addi.d $sp, $sp, -16
+; LA64F-NEXT:    .cfi_def_cfa_offset 16
+; LA64F-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
+; LA64F-NEXT:    .cfi_offset 1, -8
+; LA64F-NEXT:    bl %plt(fmaximum_num)
+; LA64F-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; LA64F-NEXT:    addi.d $sp, $sp, 16
+; LA64F-NEXT:    ret
+;
+; LA64D-LABEL: maximumnum_double_nofpclass_s:
+; LA64D:       # %bb.0:
+; LA64D-NEXT:    fmax.d $fa0, $fa0, $fa1
+; LA64D-NEXT:    ret
+  %z = call double @llvm.maximumnum.f64(double %x, double %y)
+  ret double %z
+}
+
+
 define float @minimumnum_float(float %x, float %y) {
 ;
 ; LA32F-LABEL: minimumnum_float:
@@ -311,6 +432,54 @@ define float @minimumnum_float_nnan(float %x, float %y) {
   ret float %z
 }
 
+define float @minimumnum_float_nofpclass(float nofpclass(nan) %x, float nofpclass(nan) %y) {
+; LA32F-LABEL: minimumnum_float_nofpclass:
+; LA32F:       # %bb.0:
+; LA32F-NEXT:    fmin.s $fa0, $fa0, $fa1
+; LA32F-NEXT:    ret
+;
+; LA32D-LABEL: minimumnum_float_nofpclass:
+; LA32D:       # %bb.0:
+; LA32D-NEXT:    fmin.s $fa0, $fa0, $fa1
+; LA32D-NEXT:    ret
+;
+; LA64F-LABEL: minimumnum_float_nofpclass:
+; LA64F:       # %bb.0:
+; LA64F-NEXT:    fmin.s $fa0, $fa0, $fa1
+; LA64F-NEXT:    ret
+;
+; LA64D-LABEL: minimumnum_float_nofpclass:
+; LA64D:       # %bb.0:
+; LA64D-NEXT:    fmin.s $fa0, $fa0, $fa1
+; LA64D-NEXT:    ret
+  %z = call float @llvm.minimumnum.f32(float %x, float %y)
+  ret float %z
+}
+
+define float @minimumnum_float_nofpclass_s(float nofpclass(snan) %x, float nofpclass(snan) %y) {
+; LA32F-LABEL: minimumnum_float_nofpclass_s:
+; LA32F:       # %bb.0:
+; LA32F-NEXT:    fmin.s $fa0, $fa0, $fa1
+; LA32F-NEXT:    ret
+;
+; LA32D-LABEL: minimumnum_float_nofpclass_s:
+; LA32D:       # %bb.0:
+; LA32D-NEXT:    fmin.s $fa0, $fa0, $fa1
+; LA32D-NEXT:    ret
+;
+; LA64F-LABEL: minimumnum_float_nofpclass_s:
+; LA64F:       # %bb.0:
+; LA64F-NEXT:    fmin.s $fa0, $fa0, $fa1
+; LA64F-NEXT:    ret
+;
+; LA64D-LABEL: minimumnum_float_nofpclass_s:
+; LA64D:       # %bb.0:
+; LA64D-NEXT:    fmin.s $fa0, $fa0, $fa1
+; LA64D-NEXT:    ret
+  %z = call float @llvm.minimumnum.f32(float %x, float %y)
+  ret float %z
+}
+
 define double @minimumnum_double(double %x, double %y) {
 ;
 ; LA32F-LABEL: minimumnum_double:
@@ -429,3 +598,75 @@ define double @minimumnum_double_nnan(double %x, double %y) {
   %z = call nnan double @llvm.minimumnum.f64(double %x, double %y)
   ret double %z
 }
+
+define double @minimumnum_double_nofpclass(double nofpclass(nan) %x, double nofpclass(nan) %y) {
+; LA32F-LABEL: minimumnum_double_nofpclass:
+; LA32F:       # %bb.0:
+; LA32F-NEXT:    addi.w $sp, $sp, -16
+; LA32F-NEXT:    .cfi_def_cfa_offset 16
+; LA32F-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
+; LA32F-NEXT:    .cfi_offset 1, -4
+; LA32F-NEXT:    bl %plt(fminimum_num)
+; LA32F-NEXT:    ld.w $ra, $sp, 12 # 4-byte Folded Reload
+; LA32F-NEXT:    addi.w $sp, $sp, 16
+; LA32F-NEXT:    ret
+;
+; LA32D-LABEL: minimumnum_double_nofpclass:
+; LA32D:       # %bb.0:
+; LA32D-NEXT:    fmin.d $fa0, $fa0, $fa1
+; LA32D-NEXT:    ret
+;
+; LA64F-LABEL: minimumnum_double_nofpclass:
+; LA64F:       # %bb.0:
+; LA64F-NEXT:    addi.d $sp, $sp, -16
+; LA64F-NEXT:    .cfi_def_cfa_offset 16
+; LA64F-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
+; LA64F-NEXT:    .cfi_offset 1, -8
+; LA64F-NEXT:    bl %plt(fminimum_num)
+; LA64F-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; LA64F-NEXT:    addi.d $sp, $sp, 16
+; LA64F-NEXT:    ret
+;
+; LA64D-LABEL: minimumnum_double_nofpclass:
+; LA64D:       # %bb.0:
+; LA64D-NEXT:    fmin.d $fa0, $fa0, $fa1
+; LA64D-NEXT:    ret
+  %z = call double @llvm.minimumnum.f64(double %x, double %y)
+  ret double %z
+}
+
+define double @minimumnum_double_nofpclass_s(double nofpclass(snan) %x, double nofpclass(snan) %y) {
+; LA32F-LABEL: minimumnum_double_nofpclass_s:
+; LA32F:       # %bb.0:
+; LA32F-NEXT:    addi.w $sp, $sp, -16
+; LA32F-NEXT:    .cfi_def_cfa_offset 16
+; LA32F-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
+; LA32F-NEXT:    .cfi_offset 1, -4
+; LA32F-NEXT:    bl %plt(fminimum_num)
+; LA32F-NEXT:    ld.w $ra, $sp, 12 # 4-byte Folded Reload
+; LA32F-NEXT:    addi.w $sp, $sp, 16
+; LA32F-NEXT:    ret
+;
+; LA32D-LABEL: minimumnum_double_nofpclass_s:
+; LA32D:       # %bb.0:
+; LA32D-NEXT:    fmin.d $fa0, $fa0, $fa1
+; LA32D-NEXT:    ret
+;
+; LA64F-LABEL: minimumnum_double_nofpclass_s:
+; LA64F:       # %bb.0:
+; LA64F-NEXT:    addi.d $sp, $sp, -16
+; LA64F-NEXT:    .cfi_def_cfa_offset 16
+; LA64F-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
+; LA64F-NEXT:    .cfi_offset 1, -8
+; LA64F-NEXT:    bl %plt(fminimum_num)
+; LA64F-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; LA64F-NEXT:    addi.d $sp, $sp, 16
+; LA64F-NEXT:    ret
+;
+; LA64D-LABEL: minimumnum_double_nofpclass_s:
+; LA64D:       # %bb.0:
+; LA64D-NEXT:    fmin.d $fa0, $fa0, $fa1
+; LA64D-NEXT:    ret
+  %z = call double @llvm.minimumnum.f64(double %x, double %y)
+  ret double %z
+}
diff --git a/llvm/test/CodeGen/Mips/fp-maximumnum-minimumnum.ll b/llvm/test/CodeGen/Mips/fp-maximumnum-minimumnum.ll
index bc81966ca0f5c..4e79cd5a635bd 100644
--- a/llvm/test/CodeGen/Mips/fp-maximumnum-minimumnum.ll
+++ b/llvm/test/CodeGen/Mips/fp-maximumnum-minimumnum.ll
@@ -37,6 +37,24 @@ define float @maximumnum_float_nnan(float %x, float %y) {
   ret float %z
 }
 
+define float @maximumnum_float_nofpclass(float nofpclass(nan) %x, float nofpclass(nan) %y) {
+; MIPS32R6-LABEL: maximumnum_float_nofpclass:
+; MIPS32R6:       # %bb.0:
+; MIPS32R6-NEXT:    jr $ra
+; MIPS32R6-NEXT:    max.s $f0, $f12, $f14
+  %z = call float @llvm.maximumnum.f32(float %x, float %y)
+  ret float %z
+}
+
+define float @maximumnum_float_nofpclass_s(float nofpclass(snan) %x, float nofpclass(snan) %y) {
+; MIPS32R6-LABEL: maximumnum_float_nofpclass_s:
+; MIPS32R6:       # %bb.0:
+; MIPS32R6-NEXT:    jr $ra
+; MIPS32R6-NEXT:    max.s $f0, $f12, $f14
+  %z = call float @llvm.maximumnum.f32(float %x, float %y)
+  ret float %z
+}
+
 
 define double @maximumnum_double(double %x, double %y) {
 ; MIPS32R6-LABEL: maximumnum_double:
@@ -69,6 +87,25 @@ define double @maximumnum_double_nnan(double %x, double %y) {
   ret double %z
 }
 
+define double @maximumnum_double_nofpclass(double nofpclass(nan) %x, double nofpclass(nan) %y) {
+; MIPS32R6-LABEL: maximumnum_double_nofpclass:
+; MIPS32R6:       # %bb.0:
+; MIPS32R6-NEXT:    jr $ra
+; MIPS32R6-NEXT:    max.d $f0, $f12, $f14
+  %z = call double @llvm.maximumnum.f64(double %x, double %y)
+  ret double %z
+}
+
+define double @maximumnum_double_nofpclass_s(double nofpclass(snan) %x, double nofpclass(snan) %y) {
+; MIPS32R6-LABEL: maximumnum_double_nofpclass_s:
+; MIPS32R6:       # %bb.0:
+; MIPS32R6-NEXT:    jr $ra
+; MIPS32R6-NEXT:    max.d $f0, $f12, $f14
+  %z = call double @llvm.maximumnum.f64(double %x, double %y)
+  ret double %z
+}
+
+
 define float @minimumnum_float(float %x, float %y) {
 ; MIPS32R6-LABEL: minimumnum_float:
 ; MIPS32R6:       # %bb.0:
@@ -100,6 +137,24 @@ define float @minimumnum_float_nnan(float %x, float %y) {
   ret float %z
 }
 
+define float @minimumnum_float_nofpclass(float nofpclass(nan) %x, float nofpclass(nan) %y) {
+; MIPS32R6-LABEL: minimumnum_float_nofpclass:
+; MIPS32R6:       # %bb.0:
+; MIPS32R6-NEXT:    jr $ra
+; MIPS32R6-NEXT:    min.s $f0, $f12, $f14
+  %z = call float @llvm.minimumnum.f32(float %x, float %y)
+  ret float %z
+}
+
+define float @minimumnum_float_nofpclass_s(float nofpclass(snan) %x, float nofpclass(snan) %y) {
+; MIPS32R6-LABEL: minimumnum_float_nofpclass_s:
+; MIPS32R6:       # %bb.0:
+; MIPS32R6-NEXT:    jr $ra
+; MIPS32R6-NEXT:    min.s $f0, $f12, $f14
+  %z = call float @llvm.minimumnum.f32(float %x, float %y)
+  ret float %z
+}
+
 define double @minimumnum_double(double %x, double %y) {
 ; MIPS32R6-LABEL: minimumnum_double:
 ; MIPS32R6:       # %bb.0:
@@ -130,3 +185,21 @@ define double @minimumnum_double_nnan(double %x, double %y) {
   %z = call nnan double @llvm.minimumnum.f64(double %x, double %y)
   ret double %z
 }
+
+define double @minimumnum_double_nofpclass(double nofpclass(nan) %x, double nofpclass(nan) %y) {
+; MIPS32R6-LABEL: minimumnum_double_nofpclass:
+; MIPS32R6:       # %bb.0:
+; MIPS32R6-NEXT:    jr $ra
+; MIPS32R6-NEXT:    min.d $f0, $f12, $f14
+  %z = call double @llvm.minimumnum.f64(double %x, double %y)
+  ret double %z
+}
+
+define double @minimumnum_double_nofpclass_s(double nofpclass(snan) %x, double nofpclass(snan) %y) {
+; MIPS32R6-LABEL: minimumnum_double_nofpclass_s:
+; MIPS32R6:       # %bb.0:
+; MIPS32R6-NEXT:    jr $ra
+; MIPS32R6-NEXT:    min.d $f0, $f12, $f14
+  %z = call double @llvm.minimumnum.f64(double %x, double %y)
+  ret double %z
+}

>From 87a63dec292d0b95ed0f9b49efbce23f13458b03 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Mon, 10 Mar 2025 08:49:59 +0800
Subject: [PATCH 2/2] support ISD::AssertFPNoClass

---
 llvm/include/llvm/CodeGen/ISDOpcodes.h        |  6 +++++
 .../include/llvm/Target/TargetSelectionDAG.td |  1 +
 .../SelectionDAG/LegalizeVectorTypes.cpp      |  3 +++
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |  4 ++++
 .../SelectionDAG/SelectionDAGBuilder.cpp      | 24 ++++++++++---------
 .../SelectionDAG/SelectionDAGDumper.cpp       |  1 +
 .../CodeGen/SelectionDAG/SelectionDAGISel.cpp |  1 +
 7 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index 59f31f8443947..bd2ec13e9313e 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 42a5fbec95174..40585e8fa2d30 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/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 9d42ec2fdf859..eb097b40e5206 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -128,6 +128,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:
@@ -4843,6 +4845,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 7fc97fadeff09..63265be2171ca 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -7384,6 +7384,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/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 0604db4c64608..beeb6a937de3f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -11885,20 +11885,22 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
           AssertOp = ISD::AssertSext;
         else if (Arg.hasAttribute(Attribute::ZExt))
           AssertOp = ISD::AssertZext;
-        if (Arg.hasAttribute(Attribute::NoFPClass)) {
-          SDNodeFlags InValFlags = InVals[i]->getFlags();
+        SDValue OutVal =
+            getCopyFromParts(DAG, dl, &InVals[i], NumParts, PartVT, VT, nullptr,
+                             NewRoot, F.getCallingConv(), AssertOp);
+        if (Arg.hasAttribute(Attribute::NoFPClass) &&
+            OutVal.getValueType().isFloatingPoint()) {
+          SDNodeFlags OutValFlags = OutVal->getFlags();
           bool NoSNaN = ((Arg.getNoFPClass() & llvm::fcSNan) == llvm::fcSNan);
           bool NoQNaN = ((Arg.getNoFPClass() & llvm::fcQNan) == llvm::fcQNan);
-          InValFlags.setNoSNaNs(NoSNaN);
-          InValFlags.setNoQNaNs(NoQNaN);
-          InValFlags.setNoInfs((Arg.getNoFPClass() & llvm::fcInf) ==
-                               llvm::fcInf);
-          InVals[i]->setFlags(InValFlags);
+          bool NoInf = ((Arg.getNoFPClass() & llvm::fcInf) == llvm::fcInf);
+          OutValFlags.setNoSNaNs(NoSNaN);
+          OutValFlags.setNoQNaNs(NoQNaN);
+          OutValFlags.setNoInfs(NoInf);
+          OutVal =
+              DAG.getNode(ISD::AssertNoFPClass, dl, VT, OutVal, OutValFlags);
         }
-
-        ArgValues.push_back(getCopyFromParts(DAG, dl, &InVals[i], NumParts,
-                                             PartVT, VT, nullptr, NewRoot,
-                                             F.getCallingConv(), AssertOp));
+        ArgValues.push_back(OutVal);
       }
 
       i += NumParts;
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 64ecff8d71f98..6a34ae6b1b772 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -118,6 +118,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 63ee2d78cfa1b..657ddce115649 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -3262,6 +3262,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);



More information about the llvm-commits mailing list