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/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index b62cf08693f63..6482b4673331d 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,13 +416,17 @@ 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, - FastMathFlags = NoNaNs | NoInfs | NoSignedZeros | AllowReciprocal | - AllowContract | ApproximateFuncs | AllowReassociation, + NonNeg | NoSNaNs | NoQNaNs | NoInfs | SameSign, + FastMathFlags = NoSNaNs | NoQNaNs | NoInfs | NoSignedZeros | + AllowReciprocal | AllowContract | ApproximateFuncs | + AllowReassociation, }; /// Default constructor turns off all optimization flags. @@ -430,7 +434,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()); @@ -446,7 +451,12 @@ struct SDNodeFlags { void setDisjoint(bool b) { setFlag(b); } void setSameSign(bool b) { setFlag(b); } void setNonNeg(bool b) { setFlag(b); } - void setNoNaNs(bool b) { setFlag(b); } + void setNoNaNs(bool b) { + setFlag(b); + setFlag(b); + } + void setNoSNaNs(bool b) { setFlag(b); } + void setNoQNaNs(bool b) { setFlag(b); } void setNoInfs(bool b) { setFlag(b); } void setNoSignedZeros(bool b) { setFlag(b); } void setAllowReciprocal(bool b) { setFlag(b); } @@ -463,7 +473,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/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 8682c40898046..2dd32ac5eccb8 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -5603,7 +5603,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) @@ -7370,6 +7375,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(N2)->getVT(); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 8cae34d06c8ba..9dbbd759057b1 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -11827,10 +11827,25 @@ void SelectionDAGISel::LowerArguments(const Function &F) { AssertOp = ISD::AssertSext; else if (Arg.hasAttribute(Attribute::ZExt)) AssertOp = ISD::AssertZext; - - ArgValues.push_back(getCopyFromParts(DAG, dl, &InVals[i], NumParts, - PartVT, VT, nullptr, NewRoot, - F.getCallingConv(), AssertOp)); + 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); + bool NoInf = ((Arg.getNoFPClass() & llvm::fcInf) == llvm::fcInf); + bool NoNegZero = + ((Arg.getNoFPClass() & llvm::fcInf) == llvm::fcNegZero); + OutValFlags.setNoSNaNs(NoSNaN); + OutValFlags.setNoQNaNs(NoQNaN); + OutValFlags.setNoInfs(NoInf); + OutValFlags.setNoSignedZeros(NoNegZero); + OutVal = + DAG.getNode(ISD::AssertNoFPClass, dl, VT, OutVal, OutValFlags); + } + ArgValues.push_back(OutVal); } i += NumParts; 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); diff --git a/llvm/test/CodeGen/AArch64/fp-maximumnum-minimumnum.ll b/llvm/test/CodeGen/AArch64/fp-maximumnum-minimumnum.ll index c6b8e41f9bdfd..102dbbb16d92b 100644 --- a/llvm/test/CodeGen/AArch64/fp-maximumnum-minimumnum.ll +++ b/llvm/test/CodeGen/AArch64/fp-maximumnum-minimumnum.ll @@ -2237,3 +2237,2235 @@ 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 v3.d[1], v4.d[0] +; AARCH64-NEXT: mov v0.d[1], v1.d[0] +; AARCH64-NEXT: fmaxnm v2.2d, v2.2d, v5.2d +; AARCH64-NEXT: // kill: def $d2 killed $d2 killed $q2 +; AARCH64-NEXT: fmaxnm v0.2d, v0.2d, v3.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: 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: fmaxnm v1.2d, v1.2d, v3.2d +; AARCH64-NEXT: fmaxnm v0.2d, v0.2d, v2.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: fmaxnm v4.4s, v4.4s, v2.4s +; AARCH64-NEXT: // kill: def $s4 killed $s4 killed $q4 +; AARCH64-NEXT: mov v0.s[3], v3.s[0] +; AARCH64-NEXT: ld1 { v5.s }[3], [x8] +; AARCH64-NEXT: fmaxnm v0.4s, v0.4s, v5.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: fmaxnm v1.4s, v1.4s, v3.4s +; AARCH64-NEXT: fmaxnm v0.4s, v0.4s, v2.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) { +; FULLFP16-LABEL: max_nofpclass_v2f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fmaxnm v0.4h, v0.4h, v1.4h +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: max_nofpclass_v2f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: // kill: def $d1 killed $d1 def $q1 +; NOFULLFP16-NEXT: // kill: def $d0 killed $d0 def $q0 +; NOFULLFP16-NEXT: mov h2, v1.h[1] +; NOFULLFP16-NEXT: mov h3, v0.h[1] +; NOFULLFP16-NEXT: mov h4, v1.h[2] +; NOFULLFP16-NEXT: mov h5, v0.h[2] +; NOFULLFP16-NEXT: fcvt s6, h1 +; NOFULLFP16-NEXT: fcvt s7, h0 +; NOFULLFP16-NEXT: mov h1, v1.h[3] +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fmaxnm s2, s3, s2 +; NOFULLFP16-NEXT: fcvt s3, h4 +; NOFULLFP16-NEXT: fcvt s4, h5 +; NOFULLFP16-NEXT: fmaxnm s5, s7, s6 +; NOFULLFP16-NEXT: mov h6, v0.h[3] +; NOFULLFP16-NEXT: fmaxnm s3, s4, s3 +; NOFULLFP16-NEXT: fcvt h2, s2 +; NOFULLFP16-NEXT: fcvt h0, s5 +; NOFULLFP16-NEXT: fcvt s4, h6 +; NOFULLFP16-NEXT: mov v0.h[1], v2.h[0] +; NOFULLFP16-NEXT: fcvt h2, s3 +; NOFULLFP16-NEXT: fmaxnm s1, s4, s1 +; NOFULLFP16-NEXT: mov v0.h[2], v2.h[0] +; NOFULLFP16-NEXT: fcvt h1, s1 +; NOFULLFP16-NEXT: mov v0.h[3], v1.h[0] +; NOFULLFP16-NEXT: // kill: def $d0 killed $d0 killed $q0 +; NOFULLFP16-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) { +; FULLFP16-LABEL: max_nofpclass_v4f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fmaxnm v0.4h, v0.4h, v1.4h +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: max_nofpclass_v4f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: // kill: def $d1 killed $d1 def $q1 +; NOFULLFP16-NEXT: // kill: def $d0 killed $d0 def $q0 +; NOFULLFP16-NEXT: mov h2, v1.h[1] +; NOFULLFP16-NEXT: mov h3, v0.h[1] +; NOFULLFP16-NEXT: mov h4, v1.h[2] +; NOFULLFP16-NEXT: mov h5, v0.h[2] +; NOFULLFP16-NEXT: fcvt s6, h1 +; NOFULLFP16-NEXT: fcvt s7, h0 +; NOFULLFP16-NEXT: mov h1, v1.h[3] +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fmaxnm s2, s3, s2 +; NOFULLFP16-NEXT: fcvt s3, h4 +; NOFULLFP16-NEXT: fcvt s4, h5 +; NOFULLFP16-NEXT: fmaxnm s5, s7, s6 +; NOFULLFP16-NEXT: mov h6, v0.h[3] +; NOFULLFP16-NEXT: fmaxnm s3, s4, s3 +; NOFULLFP16-NEXT: fcvt h2, s2 +; NOFULLFP16-NEXT: fcvt h0, s5 +; NOFULLFP16-NEXT: fcvt s4, h6 +; NOFULLFP16-NEXT: mov v0.h[1], v2.h[0] +; NOFULLFP16-NEXT: fcvt h2, s3 +; NOFULLFP16-NEXT: fmaxnm s1, s4, s1 +; NOFULLFP16-NEXT: mov v0.h[2], v2.h[0] +; NOFULLFP16-NEXT: fcvt h1, s1 +; NOFULLFP16-NEXT: mov v0.h[3], v1.h[0] +; NOFULLFP16-NEXT: // kill: def $d0 killed $d0 killed $q0 +; NOFULLFP16-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) { +; FULLFP16-LABEL: max_nofpclass_v8f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fmaxnm v0.8h, v0.8h, v1.8h +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: max_nofpclass_v8f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: mov h2, v1.h[1] +; NOFULLFP16-NEXT: mov h3, v0.h[1] +; NOFULLFP16-NEXT: fcvt s4, h1 +; NOFULLFP16-NEXT: fcvt s5, h0 +; NOFULLFP16-NEXT: mov h6, v1.h[2] +; NOFULLFP16-NEXT: mov h7, v0.h[2] +; NOFULLFP16-NEXT: mov h16, v1.h[3] +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fmaxnm s4, s5, s4 +; NOFULLFP16-NEXT: mov h5, v0.h[3] +; NOFULLFP16-NEXT: fcvt s6, h6 +; NOFULLFP16-NEXT: fcvt s7, h7 +; NOFULLFP16-NEXT: fcvt s16, h16 +; NOFULLFP16-NEXT: fmaxnm s3, s3, s2 +; NOFULLFP16-NEXT: fcvt s5, h5 +; NOFULLFP16-NEXT: fcvt h2, s4 +; NOFULLFP16-NEXT: fmaxnm s4, s7, s6 +; NOFULLFP16-NEXT: mov h6, v1.h[4] +; NOFULLFP16-NEXT: mov h7, v0.h[4] +; NOFULLFP16-NEXT: fcvt h3, s3 +; NOFULLFP16-NEXT: fmaxnm s5, s5, s16 +; NOFULLFP16-NEXT: mov h16, v0.h[5] +; NOFULLFP16-NEXT: fcvt h4, s4 +; NOFULLFP16-NEXT: mov v2.h[1], v3.h[0] +; NOFULLFP16-NEXT: fcvt s3, h6 +; NOFULLFP16-NEXT: fcvt s6, h7 +; NOFULLFP16-NEXT: mov h7, v1.h[5] +; NOFULLFP16-NEXT: fcvt h5, s5 +; NOFULLFP16-NEXT: fcvt s16, h16 +; NOFULLFP16-NEXT: mov v2.h[2], v4.h[0] +; NOFULLFP16-NEXT: mov h4, v1.h[6] +; NOFULLFP16-NEXT: fmaxnm s3, s6, s3 +; NOFULLFP16-NEXT: mov h6, v0.h[6] +; NOFULLFP16-NEXT: fcvt s7, h7 +; NOFULLFP16-NEXT: mov h1, v1.h[7] +; NOFULLFP16-NEXT: mov h0, v0.h[7] +; NOFULLFP16-NEXT: mov v2.h[3], v5.h[0] +; NOFULLFP16-NEXT: fcvt s4, h4 +; NOFULLFP16-NEXT: fcvt h3, s3 +; NOFULLFP16-NEXT: fcvt s5, h6 +; NOFULLFP16-NEXT: fmaxnm s6, s16, s7 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fcvt s0, h0 +; NOFULLFP16-NEXT: mov v2.h[4], v3.h[0] +; NOFULLFP16-NEXT: fmaxnm s4, s5, s4 +; NOFULLFP16-NEXT: fcvt h3, s6 +; NOFULLFP16-NEXT: fmaxnm s0, s0, s1 +; NOFULLFP16-NEXT: mov v2.h[5], v3.h[0] +; NOFULLFP16-NEXT: fcvt h3, s4 +; NOFULLFP16-NEXT: fcvt h0, s0 +; NOFULLFP16-NEXT: mov v2.h[6], v3.h[0] +; NOFULLFP16-NEXT: mov v2.h[7], v0.h[0] +; NOFULLFP16-NEXT: mov v0.16b, v2.16b +; NOFULLFP16-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) { +; FULLFP16-LABEL: max_nofpclass_v9f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: // kill: def $h0 killed $h0 def $q0 +; FULLFP16-NEXT: // kill: def $h1 killed $h1 def $q1 +; FULLFP16-NEXT: // kill: def $h2 killed $h2 def $q2 +; FULLFP16-NEXT: add x9, sp, #16 +; FULLFP16-NEXT: // kill: def $h3 killed $h3 def $q3 +; FULLFP16-NEXT: // kill: def $h4 killed $h4 def $q4 +; FULLFP16-NEXT: // kill: def $h5 killed $h5 def $q5 +; FULLFP16-NEXT: // kill: def $h6 killed $h6 def $q6 +; FULLFP16-NEXT: // kill: def $h7 killed $h7 def $q7 +; FULLFP16-NEXT: mov v0.h[1], v1.h[0] +; FULLFP16-NEXT: ldr h1, [sp, #8] +; FULLFP16-NEXT: ld1 { v1.h }[1], [x9] +; FULLFP16-NEXT: add x9, sp, #24 +; FULLFP16-NEXT: mov v0.h[2], v2.h[0] +; FULLFP16-NEXT: ldr h2, [sp, #72] +; FULLFP16-NEXT: ld1 { v1.h }[2], [x9] +; FULLFP16-NEXT: add x9, sp, #32 +; FULLFP16-NEXT: mov v0.h[3], v3.h[0] +; FULLFP16-NEXT: ld1 { v1.h }[3], [x9] +; FULLFP16-NEXT: add x9, sp, #40 +; FULLFP16-NEXT: ldr h3, [sp] +; FULLFP16-NEXT: ld1 { v1.h }[4], [x9] +; FULLFP16-NEXT: add x9, sp, #48 +; FULLFP16-NEXT: fmaxnm v2.8h, v3.8h, v2.8h +; FULLFP16-NEXT: mov v0.h[4], v4.h[0] +; FULLFP16-NEXT: ld1 { v1.h }[5], [x9] +; FULLFP16-NEXT: add x9, sp, #56 +; FULLFP16-NEXT: str h2, [x8, #16] +; FULLFP16-NEXT: mov v0.h[5], v5.h[0] +; FULLFP16-NEXT: ld1 { v1.h }[6], [x9] +; FULLFP16-NEXT: add x9, sp, #64 +; FULLFP16-NEXT: mov v0.h[6], v6.h[0] +; FULLFP16-NEXT: ld1 { v1.h }[7], [x9] +; FULLFP16-NEXT: mov v0.h[7], v7.h[0] +; FULLFP16-NEXT: fmaxnm v0.8h, v0.8h, v1.8h +; FULLFP16-NEXT: str q0, [x8] +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: max_nofpclass_v9f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: // kill: def $h0 killed $h0 def $q0 +; NOFULLFP16-NEXT: // kill: def $h1 killed $h1 def $q1 +; NOFULLFP16-NEXT: // kill: def $h2 killed $h2 def $q2 +; NOFULLFP16-NEXT: add x9, sp, #16 +; NOFULLFP16-NEXT: // kill: def $h3 killed $h3 def $q3 +; NOFULLFP16-NEXT: // kill: def $h4 killed $h4 def $q4 +; NOFULLFP16-NEXT: // kill: def $h5 killed $h5 def $q5 +; NOFULLFP16-NEXT: // kill: def $h6 killed $h6 def $q6 +; NOFULLFP16-NEXT: // kill: def $h7 killed $h7 def $q7 +; NOFULLFP16-NEXT: mov v0.h[1], v1.h[0] +; NOFULLFP16-NEXT: ldr h1, [sp, #8] +; NOFULLFP16-NEXT: ld1 { v1.h }[1], [x9] +; NOFULLFP16-NEXT: add x9, sp, #24 +; NOFULLFP16-NEXT: mov v0.h[2], v2.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[2], [x9] +; NOFULLFP16-NEXT: add x9, sp, #32 +; NOFULLFP16-NEXT: mov v0.h[3], v3.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[3], [x9] +; NOFULLFP16-NEXT: add x9, sp, #40 +; NOFULLFP16-NEXT: ld1 { v1.h }[4], [x9] +; NOFULLFP16-NEXT: add x9, sp, #48 +; NOFULLFP16-NEXT: mov v0.h[4], v4.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[5], [x9] +; NOFULLFP16-NEXT: add x9, sp, #56 +; NOFULLFP16-NEXT: mov v0.h[5], v5.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[6], [x9] +; NOFULLFP16-NEXT: add x9, sp, #64 +; NOFULLFP16-NEXT: mov v0.h[6], v6.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[7], [x9] +; NOFULLFP16-NEXT: mov h2, v1.h[1] +; NOFULLFP16-NEXT: fcvt s4, h1 +; NOFULLFP16-NEXT: mov h6, v1.h[2] +; NOFULLFP16-NEXT: mov v0.h[7], v7.h[0] +; NOFULLFP16-NEXT: mov h16, v1.h[3] +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: mov h3, v0.h[1] +; NOFULLFP16-NEXT: fcvt s5, h0 +; NOFULLFP16-NEXT: mov h7, v0.h[2] +; NOFULLFP16-NEXT: mov h17, v0.h[3] +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fmaxnm s4, s5, s4 +; NOFULLFP16-NEXT: fcvt s5, h6 +; NOFULLFP16-NEXT: fcvt s6, h7 +; NOFULLFP16-NEXT: fcvt s7, h16 +; NOFULLFP16-NEXT: fcvt s16, h17 +; NOFULLFP16-NEXT: fmaxnm s3, s3, s2 +; NOFULLFP16-NEXT: fcvt h2, s4 +; NOFULLFP16-NEXT: mov h4, v1.h[4] +; NOFULLFP16-NEXT: fmaxnm s5, s6, s5 +; NOFULLFP16-NEXT: mov h6, v0.h[4] +; NOFULLFP16-NEXT: fmaxnm s7, s16, s7 +; NOFULLFP16-NEXT: mov h16, v1.h[5] +; NOFULLFP16-NEXT: fcvt h3, s3 +; NOFULLFP16-NEXT: fcvt s4, h4 +; NOFULLFP16-NEXT: fcvt s6, h6 +; NOFULLFP16-NEXT: fcvt h5, s5 +; NOFULLFP16-NEXT: fcvt s16, h16 +; NOFULLFP16-NEXT: mov v2.h[1], v3.h[0] +; NOFULLFP16-NEXT: mov h3, v0.h[5] +; NOFULLFP16-NEXT: fmaxnm s4, s6, s4 +; NOFULLFP16-NEXT: fcvt h6, s7 +; NOFULLFP16-NEXT: mov h7, v0.h[6] +; NOFULLFP16-NEXT: mov h0, v0.h[7] +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: mov v2.h[2], v5.h[0] +; NOFULLFP16-NEXT: mov h5, v1.h[6] +; NOFULLFP16-NEXT: mov h1, v1.h[7] +; NOFULLFP16-NEXT: fcvt h4, s4 +; NOFULLFP16-NEXT: fcvt s0, h0 +; NOFULLFP16-NEXT: fmaxnm s3, s3, s16 +; NOFULLFP16-NEXT: mov v2.h[3], v6.h[0] +; NOFULLFP16-NEXT: fcvt s5, h5 +; NOFULLFP16-NEXT: fcvt s6, h7 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fcvt h3, s3 +; NOFULLFP16-NEXT: mov v2.h[4], v4.h[0] +; NOFULLFP16-NEXT: fmaxnm s4, s6, s5 +; NOFULLFP16-NEXT: ldr h5, [sp] +; NOFULLFP16-NEXT: ldr h6, [sp, #72] +; NOFULLFP16-NEXT: fmaxnm s0, s0, s1 +; NOFULLFP16-NEXT: fcvt s6, h6 +; NOFULLFP16-NEXT: fcvt s5, h5 +; NOFULLFP16-NEXT: mov v2.h[5], v3.h[0] +; NOFULLFP16-NEXT: fcvt h3, s4 +; NOFULLFP16-NEXT: fcvt h0, s0 +; NOFULLFP16-NEXT: fmaxnm s1, s5, s6 +; NOFULLFP16-NEXT: mov v2.h[6], v3.h[0] +; NOFULLFP16-NEXT: fcvt h1, s1 +; NOFULLFP16-NEXT: mov v2.h[7], v0.h[0] +; NOFULLFP16-NEXT: str h1, [x8, #16] +; NOFULLFP16-NEXT: str q2, [x8] +; NOFULLFP16-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) { +; FULLFP16-LABEL: max_nofpclass_v16f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fmaxnm v1.8h, v1.8h, v3.8h +; FULLFP16-NEXT: fmaxnm v0.8h, v0.8h, v2.8h +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: max_nofpclass_v16f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: mov h6, v2.h[1] +; NOFULLFP16-NEXT: mov h7, v0.h[1] +; NOFULLFP16-NEXT: fcvt s4, h2 +; NOFULLFP16-NEXT: fcvt s5, h0 +; NOFULLFP16-NEXT: mov h16, v3.h[1] +; NOFULLFP16-NEXT: mov h17, v1.h[1] +; NOFULLFP16-NEXT: mov h18, v2.h[2] +; NOFULLFP16-NEXT: mov h19, v0.h[2] +; NOFULLFP16-NEXT: fcvt s20, h3 +; NOFULLFP16-NEXT: fcvt s21, h1 +; NOFULLFP16-NEXT: mov h22, v3.h[2] +; NOFULLFP16-NEXT: mov h23, v1.h[2] +; NOFULLFP16-NEXT: fcvt s6, h6 +; NOFULLFP16-NEXT: fcvt s7, h7 +; NOFULLFP16-NEXT: mov h24, v0.h[6] +; NOFULLFP16-NEXT: fmaxnm s4, s5, s4 +; NOFULLFP16-NEXT: fcvt s5, h16 +; NOFULLFP16-NEXT: fcvt s16, h17 +; NOFULLFP16-NEXT: fcvt s17, h18 +; NOFULLFP16-NEXT: fcvt s18, h19 +; NOFULLFP16-NEXT: mov h19, v0.h[3] +; NOFULLFP16-NEXT: fmaxnm s20, s21, s20 +; NOFULLFP16-NEXT: fcvt s21, h22 +; NOFULLFP16-NEXT: mov h22, v3.h[3] +; NOFULLFP16-NEXT: fmaxnm s6, s7, s6 +; NOFULLFP16-NEXT: mov h7, v2.h[3] +; NOFULLFP16-NEXT: mov h25, v1.h[6] +; NOFULLFP16-NEXT: fcvt h4, s4 +; NOFULLFP16-NEXT: fmaxnm s5, s16, s5 +; NOFULLFP16-NEXT: fcvt s16, h23 +; NOFULLFP16-NEXT: mov h23, v1.h[3] +; NOFULLFP16-NEXT: fmaxnm s17, s18, s17 +; NOFULLFP16-NEXT: fcvt s18, h19 +; NOFULLFP16-NEXT: fcvt h6, s6 +; NOFULLFP16-NEXT: fcvt s7, h7 +; NOFULLFP16-NEXT: fcvt h19, s5 +; NOFULLFP16-NEXT: fcvt h5, s20 +; NOFULLFP16-NEXT: fmaxnm s16, s16, s21 +; NOFULLFP16-NEXT: fcvt s20, h23 +; NOFULLFP16-NEXT: fcvt h17, s17 +; NOFULLFP16-NEXT: mov h21, v2.h[4] +; NOFULLFP16-NEXT: mov h23, v1.h[4] +; NOFULLFP16-NEXT: mov v4.h[1], v6.h[0] +; NOFULLFP16-NEXT: fcvt s6, h22 +; NOFULLFP16-NEXT: mov h22, v0.h[4] +; NOFULLFP16-NEXT: fmaxnm s7, s18, s7 +; NOFULLFP16-NEXT: mov h18, v3.h[4] +; NOFULLFP16-NEXT: mov v5.h[1], v19.h[0] +; NOFULLFP16-NEXT: fcvt h16, s16 +; NOFULLFP16-NEXT: fmaxnm s6, s20, s6 +; NOFULLFP16-NEXT: mov v4.h[2], v17.h[0] +; NOFULLFP16-NEXT: fcvt s17, h21 +; NOFULLFP16-NEXT: fcvt s19, h22 +; NOFULLFP16-NEXT: fcvt h7, s7 +; NOFULLFP16-NEXT: fcvt s18, h18 +; NOFULLFP16-NEXT: fcvt s20, h23 +; NOFULLFP16-NEXT: mov h21, v2.h[5] +; NOFULLFP16-NEXT: mov h22, v0.h[5] +; NOFULLFP16-NEXT: mov v5.h[2], v16.h[0] +; NOFULLFP16-NEXT: mov h16, v3.h[5] +; NOFULLFP16-NEXT: mov h23, v1.h[5] +; NOFULLFP16-NEXT: fcvt h6, s6 +; NOFULLFP16-NEXT: mov h0, v0.h[7] +; NOFULLFP16-NEXT: mov h1, v1.h[7] +; NOFULLFP16-NEXT: fmaxnm s17, s19, s17 +; NOFULLFP16-NEXT: mov h19, v2.h[6] +; NOFULLFP16-NEXT: mov v4.h[3], v7.h[0] +; NOFULLFP16-NEXT: fmaxnm s18, s20, s18 +; NOFULLFP16-NEXT: mov h20, v3.h[6] +; NOFULLFP16-NEXT: fcvt s7, h21 +; NOFULLFP16-NEXT: fcvt s21, h22 +; NOFULLFP16-NEXT: fcvt s22, h24 +; NOFULLFP16-NEXT: mov h2, v2.h[7] +; NOFULLFP16-NEXT: mov v5.h[3], v6.h[0] +; NOFULLFP16-NEXT: fcvt s6, h16 +; NOFULLFP16-NEXT: fcvt s16, h23 +; NOFULLFP16-NEXT: fcvt h17, s17 +; NOFULLFP16-NEXT: fcvt s19, h19 +; NOFULLFP16-NEXT: fcvt s23, h25 +; NOFULLFP16-NEXT: fcvt h18, s18 +; NOFULLFP16-NEXT: fcvt s20, h20 +; NOFULLFP16-NEXT: mov h3, v3.h[7] +; NOFULLFP16-NEXT: fmaxnm s7, s21, s7 +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: fcvt s0, h0 +; NOFULLFP16-NEXT: fmaxnm s6, s16, s6 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: mov v4.h[4], v17.h[0] +; NOFULLFP16-NEXT: fmaxnm s16, s22, s19 +; NOFULLFP16-NEXT: mov v5.h[4], v18.h[0] +; NOFULLFP16-NEXT: fmaxnm s17, s23, s20 +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fcvt h7, s7 +; NOFULLFP16-NEXT: fmaxnm s0, s0, s2 +; NOFULLFP16-NEXT: fcvt h6, s6 +; NOFULLFP16-NEXT: fcvt h2, s16 +; NOFULLFP16-NEXT: fmaxnm s1, s1, s3 +; NOFULLFP16-NEXT: mov v4.h[5], v7.h[0] +; NOFULLFP16-NEXT: fcvt h0, s0 +; NOFULLFP16-NEXT: mov v5.h[5], v6.h[0] +; NOFULLFP16-NEXT: fcvt h6, s17 +; NOFULLFP16-NEXT: fcvt h1, s1 +; NOFULLFP16-NEXT: mov v4.h[6], v2.h[0] +; NOFULLFP16-NEXT: mov v5.h[6], v6.h[0] +; NOFULLFP16-NEXT: mov v4.h[7], v0.h[0] +; NOFULLFP16-NEXT: mov v5.h[7], v1.h[0] +; NOFULLFP16-NEXT: mov v0.16b, v4.16b +; NOFULLFP16-NEXT: mov v1.16b, v5.16b +; NOFULLFP16-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 v3.d[1], v4.d[0] +; AARCH64-NEXT: mov v0.d[1], v1.d[0] +; AARCH64-NEXT: fminnm v2.2d, v2.2d, v5.2d +; AARCH64-NEXT: // kill: def $d2 killed $d2 killed $q2 +; AARCH64-NEXT: fminnm v0.2d, v0.2d, v3.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: 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 v1.2d, v1.2d, v3.2d +; AARCH64-NEXT: fminnm v0.2d, v0.2d, v2.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 v4.4s, v4.4s, v2.4s +; AARCH64-NEXT: // kill: def $s4 killed $s4 killed $q4 +; AARCH64-NEXT: mov v0.s[3], v3.s[0] +; AARCH64-NEXT: ld1 { v5.s }[3], [x8] +; AARCH64-NEXT: fminnm v0.4s, v0.4s, v5.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 v1.4s, v1.4s, v3.4s +; AARCH64-NEXT: fminnm v0.4s, v0.4s, v2.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) { +; FULLFP16-LABEL: min_nofpclass_f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fminnm h0, h0, h1 +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: min_nofpclass_f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fcvt s0, h0 +; NOFULLFP16-NEXT: fminnm s0, s0, s1 +; NOFULLFP16-NEXT: fcvt h0, s0 +; NOFULLFP16-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) { +; FULLFP16-LABEL: min_nofpclass_v2f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fminnm v0.4h, v0.4h, v1.4h +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: min_nofpclass_v2f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: // kill: def $d1 killed $d1 def $q1 +; NOFULLFP16-NEXT: // kill: def $d0 killed $d0 def $q0 +; NOFULLFP16-NEXT: mov h2, v1.h[1] +; NOFULLFP16-NEXT: mov h3, v0.h[1] +; NOFULLFP16-NEXT: mov h4, v1.h[2] +; NOFULLFP16-NEXT: mov h5, v0.h[2] +; NOFULLFP16-NEXT: fcvt s6, h1 +; NOFULLFP16-NEXT: fcvt s7, h0 +; NOFULLFP16-NEXT: mov h1, v1.h[3] +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fminnm s2, s3, s2 +; NOFULLFP16-NEXT: fcvt s3, h4 +; NOFULLFP16-NEXT: fcvt s4, h5 +; NOFULLFP16-NEXT: fminnm s5, s7, s6 +; NOFULLFP16-NEXT: mov h6, v0.h[3] +; NOFULLFP16-NEXT: fminnm s3, s4, s3 +; NOFULLFP16-NEXT: fcvt h2, s2 +; NOFULLFP16-NEXT: fcvt h0, s5 +; NOFULLFP16-NEXT: fcvt s4, h6 +; NOFULLFP16-NEXT: mov v0.h[1], v2.h[0] +; NOFULLFP16-NEXT: fcvt h2, s3 +; NOFULLFP16-NEXT: fminnm s1, s4, s1 +; NOFULLFP16-NEXT: mov v0.h[2], v2.h[0] +; NOFULLFP16-NEXT: fcvt h1, s1 +; NOFULLFP16-NEXT: mov v0.h[3], v1.h[0] +; NOFULLFP16-NEXT: // kill: def $d0 killed $d0 killed $q0 +; NOFULLFP16-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) { +; FULLFP16-LABEL: min_nofpclass_v4f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fminnm v0.4h, v0.4h, v1.4h +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: min_nofpclass_v4f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: // kill: def $d1 killed $d1 def $q1 +; NOFULLFP16-NEXT: // kill: def $d0 killed $d0 def $q0 +; NOFULLFP16-NEXT: mov h2, v1.h[1] +; NOFULLFP16-NEXT: mov h3, v0.h[1] +; NOFULLFP16-NEXT: mov h4, v1.h[2] +; NOFULLFP16-NEXT: mov h5, v0.h[2] +; NOFULLFP16-NEXT: fcvt s6, h1 +; NOFULLFP16-NEXT: fcvt s7, h0 +; NOFULLFP16-NEXT: mov h1, v1.h[3] +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fminnm s2, s3, s2 +; NOFULLFP16-NEXT: fcvt s3, h4 +; NOFULLFP16-NEXT: fcvt s4, h5 +; NOFULLFP16-NEXT: fminnm s5, s7, s6 +; NOFULLFP16-NEXT: mov h6, v0.h[3] +; NOFULLFP16-NEXT: fminnm s3, s4, s3 +; NOFULLFP16-NEXT: fcvt h2, s2 +; NOFULLFP16-NEXT: fcvt h0, s5 +; NOFULLFP16-NEXT: fcvt s4, h6 +; NOFULLFP16-NEXT: mov v0.h[1], v2.h[0] +; NOFULLFP16-NEXT: fcvt h2, s3 +; NOFULLFP16-NEXT: fminnm s1, s4, s1 +; NOFULLFP16-NEXT: mov v0.h[2], v2.h[0] +; NOFULLFP16-NEXT: fcvt h1, s1 +; NOFULLFP16-NEXT: mov v0.h[3], v1.h[0] +; NOFULLFP16-NEXT: // kill: def $d0 killed $d0 killed $q0 +; NOFULLFP16-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) { +; FULLFP16-LABEL: min_nofpclass_v8f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fminnm v0.8h, v0.8h, v1.8h +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: min_nofpclass_v8f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: mov h2, v1.h[1] +; NOFULLFP16-NEXT: mov h3, v0.h[1] +; NOFULLFP16-NEXT: fcvt s4, h1 +; NOFULLFP16-NEXT: fcvt s5, h0 +; NOFULLFP16-NEXT: mov h6, v1.h[2] +; NOFULLFP16-NEXT: mov h7, v0.h[2] +; NOFULLFP16-NEXT: mov h16, v1.h[3] +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fminnm s4, s5, s4 +; NOFULLFP16-NEXT: mov h5, v0.h[3] +; NOFULLFP16-NEXT: fcvt s6, h6 +; NOFULLFP16-NEXT: fcvt s7, h7 +; NOFULLFP16-NEXT: fcvt s16, h16 +; NOFULLFP16-NEXT: fminnm s3, s3, s2 +; NOFULLFP16-NEXT: fcvt s5, h5 +; NOFULLFP16-NEXT: fcvt h2, s4 +; NOFULLFP16-NEXT: fminnm s4, s7, s6 +; NOFULLFP16-NEXT: mov h6, v1.h[4] +; NOFULLFP16-NEXT: mov h7, v0.h[4] +; NOFULLFP16-NEXT: fcvt h3, s3 +; NOFULLFP16-NEXT: fminnm s5, s5, s16 +; NOFULLFP16-NEXT: mov h16, v0.h[5] +; NOFULLFP16-NEXT: fcvt h4, s4 +; NOFULLFP16-NEXT: mov v2.h[1], v3.h[0] +; NOFULLFP16-NEXT: fcvt s3, h6 +; NOFULLFP16-NEXT: fcvt s6, h7 +; NOFULLFP16-NEXT: mov h7, v1.h[5] +; NOFULLFP16-NEXT: fcvt h5, s5 +; NOFULLFP16-NEXT: fcvt s16, h16 +; NOFULLFP16-NEXT: mov v2.h[2], v4.h[0] +; NOFULLFP16-NEXT: mov h4, v1.h[6] +; NOFULLFP16-NEXT: fminnm s3, s6, s3 +; NOFULLFP16-NEXT: mov h6, v0.h[6] +; NOFULLFP16-NEXT: fcvt s7, h7 +; NOFULLFP16-NEXT: mov h1, v1.h[7] +; NOFULLFP16-NEXT: mov h0, v0.h[7] +; NOFULLFP16-NEXT: mov v2.h[3], v5.h[0] +; NOFULLFP16-NEXT: fcvt s4, h4 +; NOFULLFP16-NEXT: fcvt h3, s3 +; NOFULLFP16-NEXT: fcvt s5, h6 +; NOFULLFP16-NEXT: fminnm s6, s16, s7 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fcvt s0, h0 +; NOFULLFP16-NEXT: mov v2.h[4], v3.h[0] +; NOFULLFP16-NEXT: fminnm s4, s5, s4 +; NOFULLFP16-NEXT: fcvt h3, s6 +; NOFULLFP16-NEXT: fminnm s0, s0, s1 +; NOFULLFP16-NEXT: mov v2.h[5], v3.h[0] +; NOFULLFP16-NEXT: fcvt h3, s4 +; NOFULLFP16-NEXT: fcvt h0, s0 +; NOFULLFP16-NEXT: mov v2.h[6], v3.h[0] +; NOFULLFP16-NEXT: mov v2.h[7], v0.h[0] +; NOFULLFP16-NEXT: mov v0.16b, v2.16b +; NOFULLFP16-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) { +; FULLFP16-LABEL: min_nofpclass_v9f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: // kill: def $h0 killed $h0 def $q0 +; FULLFP16-NEXT: // kill: def $h1 killed $h1 def $q1 +; FULLFP16-NEXT: // kill: def $h2 killed $h2 def $q2 +; FULLFP16-NEXT: add x9, sp, #16 +; FULLFP16-NEXT: // kill: def $h3 killed $h3 def $q3 +; FULLFP16-NEXT: // kill: def $h4 killed $h4 def $q4 +; FULLFP16-NEXT: // kill: def $h5 killed $h5 def $q5 +; FULLFP16-NEXT: // kill: def $h6 killed $h6 def $q6 +; FULLFP16-NEXT: // kill: def $h7 killed $h7 def $q7 +; FULLFP16-NEXT: mov v0.h[1], v1.h[0] +; FULLFP16-NEXT: ldr h1, [sp, #8] +; FULLFP16-NEXT: ld1 { v1.h }[1], [x9] +; FULLFP16-NEXT: add x9, sp, #24 +; FULLFP16-NEXT: mov v0.h[2], v2.h[0] +; FULLFP16-NEXT: ldr h2, [sp, #72] +; FULLFP16-NEXT: ld1 { v1.h }[2], [x9] +; FULLFP16-NEXT: add x9, sp, #32 +; FULLFP16-NEXT: mov v0.h[3], v3.h[0] +; FULLFP16-NEXT: ld1 { v1.h }[3], [x9] +; FULLFP16-NEXT: add x9, sp, #40 +; FULLFP16-NEXT: ldr h3, [sp] +; FULLFP16-NEXT: ld1 { v1.h }[4], [x9] +; FULLFP16-NEXT: add x9, sp, #48 +; FULLFP16-NEXT: fminnm v2.8h, v3.8h, v2.8h +; FULLFP16-NEXT: mov v0.h[4], v4.h[0] +; FULLFP16-NEXT: ld1 { v1.h }[5], [x9] +; FULLFP16-NEXT: add x9, sp, #56 +; FULLFP16-NEXT: str h2, [x8, #16] +; FULLFP16-NEXT: mov v0.h[5], v5.h[0] +; FULLFP16-NEXT: ld1 { v1.h }[6], [x9] +; FULLFP16-NEXT: add x9, sp, #64 +; FULLFP16-NEXT: mov v0.h[6], v6.h[0] +; FULLFP16-NEXT: ld1 { v1.h }[7], [x9] +; FULLFP16-NEXT: mov v0.h[7], v7.h[0] +; FULLFP16-NEXT: fminnm v0.8h, v0.8h, v1.8h +; FULLFP16-NEXT: str q0, [x8] +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: min_nofpclass_v9f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: // kill: def $h0 killed $h0 def $q0 +; NOFULLFP16-NEXT: // kill: def $h1 killed $h1 def $q1 +; NOFULLFP16-NEXT: // kill: def $h2 killed $h2 def $q2 +; NOFULLFP16-NEXT: add x9, sp, #16 +; NOFULLFP16-NEXT: // kill: def $h3 killed $h3 def $q3 +; NOFULLFP16-NEXT: // kill: def $h4 killed $h4 def $q4 +; NOFULLFP16-NEXT: // kill: def $h5 killed $h5 def $q5 +; NOFULLFP16-NEXT: // kill: def $h6 killed $h6 def $q6 +; NOFULLFP16-NEXT: // kill: def $h7 killed $h7 def $q7 +; NOFULLFP16-NEXT: mov v0.h[1], v1.h[0] +; NOFULLFP16-NEXT: ldr h1, [sp, #8] +; NOFULLFP16-NEXT: ld1 { v1.h }[1], [x9] +; NOFULLFP16-NEXT: add x9, sp, #24 +; NOFULLFP16-NEXT: mov v0.h[2], v2.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[2], [x9] +; NOFULLFP16-NEXT: add x9, sp, #32 +; NOFULLFP16-NEXT: mov v0.h[3], v3.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[3], [x9] +; NOFULLFP16-NEXT: add x9, sp, #40 +; NOFULLFP16-NEXT: ld1 { v1.h }[4], [x9] +; NOFULLFP16-NEXT: add x9, sp, #48 +; NOFULLFP16-NEXT: mov v0.h[4], v4.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[5], [x9] +; NOFULLFP16-NEXT: add x9, sp, #56 +; NOFULLFP16-NEXT: mov v0.h[5], v5.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[6], [x9] +; NOFULLFP16-NEXT: add x9, sp, #64 +; NOFULLFP16-NEXT: mov v0.h[6], v6.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[7], [x9] +; NOFULLFP16-NEXT: mov h2, v1.h[1] +; NOFULLFP16-NEXT: fcvt s4, h1 +; NOFULLFP16-NEXT: mov h6, v1.h[2] +; NOFULLFP16-NEXT: mov v0.h[7], v7.h[0] +; NOFULLFP16-NEXT: mov h16, v1.h[3] +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: mov h3, v0.h[1] +; NOFULLFP16-NEXT: fcvt s5, h0 +; NOFULLFP16-NEXT: mov h7, v0.h[2] +; NOFULLFP16-NEXT: mov h17, v0.h[3] +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fminnm s4, s5, s4 +; NOFULLFP16-NEXT: fcvt s5, h6 +; NOFULLFP16-NEXT: fcvt s6, h7 +; NOFULLFP16-NEXT: fcvt s7, h16 +; NOFULLFP16-NEXT: fcvt s16, h17 +; NOFULLFP16-NEXT: fminnm s3, s3, s2 +; NOFULLFP16-NEXT: fcvt h2, s4 +; NOFULLFP16-NEXT: mov h4, v1.h[4] +; NOFULLFP16-NEXT: fminnm s5, s6, s5 +; NOFULLFP16-NEXT: mov h6, v0.h[4] +; NOFULLFP16-NEXT: fminnm s7, s16, s7 +; NOFULLFP16-NEXT: mov h16, v1.h[5] +; NOFULLFP16-NEXT: fcvt h3, s3 +; NOFULLFP16-NEXT: fcvt s4, h4 +; NOFULLFP16-NEXT: fcvt s6, h6 +; NOFULLFP16-NEXT: fcvt h5, s5 +; NOFULLFP16-NEXT: fcvt s16, h16 +; NOFULLFP16-NEXT: mov v2.h[1], v3.h[0] +; NOFULLFP16-NEXT: mov h3, v0.h[5] +; NOFULLFP16-NEXT: fminnm s4, s6, s4 +; NOFULLFP16-NEXT: fcvt h6, s7 +; NOFULLFP16-NEXT: mov h7, v0.h[6] +; NOFULLFP16-NEXT: mov h0, v0.h[7] +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: mov v2.h[2], v5.h[0] +; NOFULLFP16-NEXT: mov h5, v1.h[6] +; NOFULLFP16-NEXT: mov h1, v1.h[7] +; NOFULLFP16-NEXT: fcvt h4, s4 +; NOFULLFP16-NEXT: fcvt s0, h0 +; NOFULLFP16-NEXT: fminnm s3, s3, s16 +; NOFULLFP16-NEXT: mov v2.h[3], v6.h[0] +; NOFULLFP16-NEXT: fcvt s5, h5 +; NOFULLFP16-NEXT: fcvt s6, h7 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fcvt h3, s3 +; NOFULLFP16-NEXT: mov v2.h[4], v4.h[0] +; NOFULLFP16-NEXT: fminnm s4, s6, s5 +; NOFULLFP16-NEXT: ldr h5, [sp] +; NOFULLFP16-NEXT: ldr h6, [sp, #72] +; NOFULLFP16-NEXT: fminnm s0, s0, s1 +; NOFULLFP16-NEXT: fcvt s6, h6 +; NOFULLFP16-NEXT: fcvt s5, h5 +; NOFULLFP16-NEXT: mov v2.h[5], v3.h[0] +; NOFULLFP16-NEXT: fcvt h3, s4 +; NOFULLFP16-NEXT: fcvt h0, s0 +; NOFULLFP16-NEXT: fminnm s1, s5, s6 +; NOFULLFP16-NEXT: mov v2.h[6], v3.h[0] +; NOFULLFP16-NEXT: fcvt h1, s1 +; NOFULLFP16-NEXT: mov v2.h[7], v0.h[0] +; NOFULLFP16-NEXT: str h1, [x8, #16] +; NOFULLFP16-NEXT: str q2, [x8] +; NOFULLFP16-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) { +; FULLFP16-LABEL: min_nofpclass_v16f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fminnm v1.8h, v1.8h, v3.8h +; FULLFP16-NEXT: fminnm v0.8h, v0.8h, v2.8h +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: min_nofpclass_v16f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: mov h6, v2.h[1] +; NOFULLFP16-NEXT: mov h7, v0.h[1] +; NOFULLFP16-NEXT: fcvt s4, h2 +; NOFULLFP16-NEXT: fcvt s5, h0 +; NOFULLFP16-NEXT: mov h16, v3.h[1] +; NOFULLFP16-NEXT: mov h17, v1.h[1] +; NOFULLFP16-NEXT: mov h18, v2.h[2] +; NOFULLFP16-NEXT: mov h19, v0.h[2] +; NOFULLFP16-NEXT: fcvt s20, h3 +; NOFULLFP16-NEXT: fcvt s21, h1 +; NOFULLFP16-NEXT: mov h22, v3.h[2] +; NOFULLFP16-NEXT: mov h23, v1.h[2] +; NOFULLFP16-NEXT: fcvt s6, h6 +; NOFULLFP16-NEXT: fcvt s7, h7 +; NOFULLFP16-NEXT: mov h24, v0.h[6] +; NOFULLFP16-NEXT: fminnm s4, s5, s4 +; NOFULLFP16-NEXT: fcvt s5, h16 +; NOFULLFP16-NEXT: fcvt s16, h17 +; NOFULLFP16-NEXT: fcvt s17, h18 +; NOFULLFP16-NEXT: fcvt s18, h19 +; NOFULLFP16-NEXT: mov h19, v0.h[3] +; NOFULLFP16-NEXT: fminnm s20, s21, s20 +; NOFULLFP16-NEXT: fcvt s21, h22 +; NOFULLFP16-NEXT: mov h22, v3.h[3] +; NOFULLFP16-NEXT: fminnm s6, s7, s6 +; NOFULLFP16-NEXT: mov h7, v2.h[3] +; NOFULLFP16-NEXT: mov h25, v1.h[6] +; NOFULLFP16-NEXT: fcvt h4, s4 +; NOFULLFP16-NEXT: fminnm s5, s16, s5 +; NOFULLFP16-NEXT: fcvt s16, h23 +; NOFULLFP16-NEXT: mov h23, v1.h[3] +; NOFULLFP16-NEXT: fminnm s17, s18, s17 +; NOFULLFP16-NEXT: fcvt s18, h19 +; NOFULLFP16-NEXT: fcvt h6, s6 +; NOFULLFP16-NEXT: fcvt s7, h7 +; NOFULLFP16-NEXT: fcvt h19, s5 +; NOFULLFP16-NEXT: fcvt h5, s20 +; NOFULLFP16-NEXT: fminnm s16, s16, s21 +; NOFULLFP16-NEXT: fcvt s20, h23 +; NOFULLFP16-NEXT: fcvt h17, s17 +; NOFULLFP16-NEXT: mov h21, v2.h[4] +; NOFULLFP16-NEXT: mov h23, v1.h[4] +; NOFULLFP16-NEXT: mov v4.h[1], v6.h[0] +; NOFULLFP16-NEXT: fcvt s6, h22 +; NOFULLFP16-NEXT: mov h22, v0.h[4] +; NOFULLFP16-NEXT: fminnm s7, s18, s7 +; NOFULLFP16-NEXT: mov h18, v3.h[4] +; NOFULLFP16-NEXT: mov v5.h[1], v19.h[0] +; NOFULLFP16-NEXT: fcvt h16, s16 +; NOFULLFP16-NEXT: fminnm s6, s20, s6 +; NOFULLFP16-NEXT: mov v4.h[2], v17.h[0] +; NOFULLFP16-NEXT: fcvt s17, h21 +; NOFULLFP16-NEXT: fcvt s19, h22 +; NOFULLFP16-NEXT: fcvt h7, s7 +; NOFULLFP16-NEXT: fcvt s18, h18 +; NOFULLFP16-NEXT: fcvt s20, h23 +; NOFULLFP16-NEXT: mov h21, v2.h[5] +; NOFULLFP16-NEXT: mov h22, v0.h[5] +; NOFULLFP16-NEXT: mov v5.h[2], v16.h[0] +; NOFULLFP16-NEXT: mov h16, v3.h[5] +; NOFULLFP16-NEXT: mov h23, v1.h[5] +; NOFULLFP16-NEXT: fcvt h6, s6 +; NOFULLFP16-NEXT: mov h0, v0.h[7] +; NOFULLFP16-NEXT: mov h1, v1.h[7] +; NOFULLFP16-NEXT: fminnm s17, s19, s17 +; NOFULLFP16-NEXT: mov h19, v2.h[6] +; NOFULLFP16-NEXT: mov v4.h[3], v7.h[0] +; NOFULLFP16-NEXT: fminnm s18, s20, s18 +; NOFULLFP16-NEXT: mov h20, v3.h[6] +; NOFULLFP16-NEXT: fcvt s7, h21 +; NOFULLFP16-NEXT: fcvt s21, h22 +; NOFULLFP16-NEXT: fcvt s22, h24 +; NOFULLFP16-NEXT: mov h2, v2.h[7] +; NOFULLFP16-NEXT: mov v5.h[3], v6.h[0] +; NOFULLFP16-NEXT: fcvt s6, h16 +; NOFULLFP16-NEXT: fcvt s16, h23 +; NOFULLFP16-NEXT: fcvt h17, s17 +; NOFULLFP16-NEXT: fcvt s19, h19 +; NOFULLFP16-NEXT: fcvt s23, h25 +; NOFULLFP16-NEXT: fcvt h18, s18 +; NOFULLFP16-NEXT: fcvt s20, h20 +; NOFULLFP16-NEXT: mov h3, v3.h[7] +; NOFULLFP16-NEXT: fminnm s7, s21, s7 +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: fcvt s0, h0 +; NOFULLFP16-NEXT: fminnm s6, s16, s6 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: mov v4.h[4], v17.h[0] +; NOFULLFP16-NEXT: fminnm s16, s22, s19 +; NOFULLFP16-NEXT: mov v5.h[4], v18.h[0] +; NOFULLFP16-NEXT: fminnm s17, s23, s20 +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fcvt h7, s7 +; NOFULLFP16-NEXT: fminnm s0, s0, s2 +; NOFULLFP16-NEXT: fcvt h6, s6 +; NOFULLFP16-NEXT: fcvt h2, s16 +; NOFULLFP16-NEXT: fminnm s1, s1, s3 +; NOFULLFP16-NEXT: mov v4.h[5], v7.h[0] +; NOFULLFP16-NEXT: fcvt h0, s0 +; NOFULLFP16-NEXT: mov v5.h[5], v6.h[0] +; NOFULLFP16-NEXT: fcvt h6, s17 +; NOFULLFP16-NEXT: fcvt h1, s1 +; NOFULLFP16-NEXT: mov v4.h[6], v2.h[0] +; NOFULLFP16-NEXT: mov v5.h[6], v6.h[0] +; NOFULLFP16-NEXT: mov v4.h[7], v0.h[0] +; NOFULLFP16-NEXT: mov v5.h[7], v1.h[0] +; NOFULLFP16-NEXT: mov v0.16b, v4.16b +; NOFULLFP16-NEXT: mov v1.16b, v5.16b +; NOFULLFP16-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 v3.d[1], v4.d[0] +; AARCH64-NEXT: mov v0.d[1], v1.d[0] +; AARCH64-NEXT: fmaxnm v2.2d, v2.2d, v5.2d +; AARCH64-NEXT: // kill: def $d2 killed $d2 killed $q2 +; AARCH64-NEXT: fmaxnm v0.2d, v0.2d, v3.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: 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: fmaxnm v1.2d, v1.2d, v3.2d +; AARCH64-NEXT: fmaxnm v0.2d, v0.2d, v2.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: fmaxnm v4.4s, v4.4s, v2.4s +; AARCH64-NEXT: // kill: def $s4 killed $s4 killed $q4 +; AARCH64-NEXT: mov v0.s[3], v3.s[0] +; AARCH64-NEXT: ld1 { v5.s }[3], [x8] +; AARCH64-NEXT: fmaxnm v0.4s, v0.4s, v5.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: fmaxnm v1.4s, v1.4s, v3.4s +; AARCH64-NEXT: fmaxnm v0.4s, v0.4s, v2.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) { +; FULLFP16-LABEL: max_nofpclass_s_v2f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fmaxnm v0.4h, v0.4h, v1.4h +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: max_nofpclass_s_v2f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: // kill: def $d1 killed $d1 def $q1 +; NOFULLFP16-NEXT: // kill: def $d0 killed $d0 def $q0 +; NOFULLFP16-NEXT: mov h2, v1.h[1] +; NOFULLFP16-NEXT: mov h3, v0.h[1] +; NOFULLFP16-NEXT: mov h4, v1.h[2] +; NOFULLFP16-NEXT: mov h5, v0.h[2] +; NOFULLFP16-NEXT: fcvt s6, h1 +; NOFULLFP16-NEXT: fcvt s7, h0 +; NOFULLFP16-NEXT: mov h1, v1.h[3] +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fmaxnm s2, s3, s2 +; NOFULLFP16-NEXT: fcvt s3, h4 +; NOFULLFP16-NEXT: fcvt s4, h5 +; NOFULLFP16-NEXT: fmaxnm s5, s7, s6 +; NOFULLFP16-NEXT: mov h6, v0.h[3] +; NOFULLFP16-NEXT: fmaxnm s3, s4, s3 +; NOFULLFP16-NEXT: fcvt h2, s2 +; NOFULLFP16-NEXT: fcvt h0, s5 +; NOFULLFP16-NEXT: fcvt s4, h6 +; NOFULLFP16-NEXT: mov v0.h[1], v2.h[0] +; NOFULLFP16-NEXT: fcvt h2, s3 +; NOFULLFP16-NEXT: fmaxnm s1, s4, s1 +; NOFULLFP16-NEXT: mov v0.h[2], v2.h[0] +; NOFULLFP16-NEXT: fcvt h1, s1 +; NOFULLFP16-NEXT: mov v0.h[3], v1.h[0] +; NOFULLFP16-NEXT: // kill: def $d0 killed $d0 killed $q0 +; NOFULLFP16-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) { +; FULLFP16-LABEL: max_nofpclass_s_v4f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fmaxnm v0.4h, v0.4h, v1.4h +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: max_nofpclass_s_v4f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: // kill: def $d1 killed $d1 def $q1 +; NOFULLFP16-NEXT: // kill: def $d0 killed $d0 def $q0 +; NOFULLFP16-NEXT: mov h2, v1.h[1] +; NOFULLFP16-NEXT: mov h3, v0.h[1] +; NOFULLFP16-NEXT: mov h4, v1.h[2] +; NOFULLFP16-NEXT: mov h5, v0.h[2] +; NOFULLFP16-NEXT: fcvt s6, h1 +; NOFULLFP16-NEXT: fcvt s7, h0 +; NOFULLFP16-NEXT: mov h1, v1.h[3] +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fmaxnm s2, s3, s2 +; NOFULLFP16-NEXT: fcvt s3, h4 +; NOFULLFP16-NEXT: fcvt s4, h5 +; NOFULLFP16-NEXT: fmaxnm s5, s7, s6 +; NOFULLFP16-NEXT: mov h6, v0.h[3] +; NOFULLFP16-NEXT: fmaxnm s3, s4, s3 +; NOFULLFP16-NEXT: fcvt h2, s2 +; NOFULLFP16-NEXT: fcvt h0, s5 +; NOFULLFP16-NEXT: fcvt s4, h6 +; NOFULLFP16-NEXT: mov v0.h[1], v2.h[0] +; NOFULLFP16-NEXT: fcvt h2, s3 +; NOFULLFP16-NEXT: fmaxnm s1, s4, s1 +; NOFULLFP16-NEXT: mov v0.h[2], v2.h[0] +; NOFULLFP16-NEXT: fcvt h1, s1 +; NOFULLFP16-NEXT: mov v0.h[3], v1.h[0] +; NOFULLFP16-NEXT: // kill: def $d0 killed $d0 killed $q0 +; NOFULLFP16-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) { +; FULLFP16-LABEL: max_nofpclass_s_v8f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fmaxnm v0.8h, v0.8h, v1.8h +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: max_nofpclass_s_v8f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: mov h2, v1.h[1] +; NOFULLFP16-NEXT: mov h3, v0.h[1] +; NOFULLFP16-NEXT: fcvt s4, h1 +; NOFULLFP16-NEXT: fcvt s5, h0 +; NOFULLFP16-NEXT: mov h6, v1.h[2] +; NOFULLFP16-NEXT: mov h7, v0.h[2] +; NOFULLFP16-NEXT: mov h16, v1.h[3] +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fmaxnm s4, s5, s4 +; NOFULLFP16-NEXT: mov h5, v0.h[3] +; NOFULLFP16-NEXT: fcvt s6, h6 +; NOFULLFP16-NEXT: fcvt s7, h7 +; NOFULLFP16-NEXT: fcvt s16, h16 +; NOFULLFP16-NEXT: fmaxnm s3, s3, s2 +; NOFULLFP16-NEXT: fcvt s5, h5 +; NOFULLFP16-NEXT: fcvt h2, s4 +; NOFULLFP16-NEXT: fmaxnm s4, s7, s6 +; NOFULLFP16-NEXT: mov h6, v1.h[4] +; NOFULLFP16-NEXT: mov h7, v0.h[4] +; NOFULLFP16-NEXT: fcvt h3, s3 +; NOFULLFP16-NEXT: fmaxnm s5, s5, s16 +; NOFULLFP16-NEXT: mov h16, v0.h[5] +; NOFULLFP16-NEXT: fcvt h4, s4 +; NOFULLFP16-NEXT: mov v2.h[1], v3.h[0] +; NOFULLFP16-NEXT: fcvt s3, h6 +; NOFULLFP16-NEXT: fcvt s6, h7 +; NOFULLFP16-NEXT: mov h7, v1.h[5] +; NOFULLFP16-NEXT: fcvt h5, s5 +; NOFULLFP16-NEXT: fcvt s16, h16 +; NOFULLFP16-NEXT: mov v2.h[2], v4.h[0] +; NOFULLFP16-NEXT: mov h4, v1.h[6] +; NOFULLFP16-NEXT: fmaxnm s3, s6, s3 +; NOFULLFP16-NEXT: mov h6, v0.h[6] +; NOFULLFP16-NEXT: fcvt s7, h7 +; NOFULLFP16-NEXT: mov h1, v1.h[7] +; NOFULLFP16-NEXT: mov h0, v0.h[7] +; NOFULLFP16-NEXT: mov v2.h[3], v5.h[0] +; NOFULLFP16-NEXT: fcvt s4, h4 +; NOFULLFP16-NEXT: fcvt h3, s3 +; NOFULLFP16-NEXT: fcvt s5, h6 +; NOFULLFP16-NEXT: fmaxnm s6, s16, s7 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fcvt s0, h0 +; NOFULLFP16-NEXT: mov v2.h[4], v3.h[0] +; NOFULLFP16-NEXT: fmaxnm s4, s5, s4 +; NOFULLFP16-NEXT: fcvt h3, s6 +; NOFULLFP16-NEXT: fmaxnm s0, s0, s1 +; NOFULLFP16-NEXT: mov v2.h[5], v3.h[0] +; NOFULLFP16-NEXT: fcvt h3, s4 +; NOFULLFP16-NEXT: fcvt h0, s0 +; NOFULLFP16-NEXT: mov v2.h[6], v3.h[0] +; NOFULLFP16-NEXT: mov v2.h[7], v0.h[0] +; NOFULLFP16-NEXT: mov v0.16b, v2.16b +; NOFULLFP16-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) { +; FULLFP16-LABEL: max_nofpclass_s_v9f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: // kill: def $h0 killed $h0 def $q0 +; FULLFP16-NEXT: // kill: def $h1 killed $h1 def $q1 +; FULLFP16-NEXT: // kill: def $h2 killed $h2 def $q2 +; FULLFP16-NEXT: add x9, sp, #16 +; FULLFP16-NEXT: // kill: def $h3 killed $h3 def $q3 +; FULLFP16-NEXT: // kill: def $h4 killed $h4 def $q4 +; FULLFP16-NEXT: // kill: def $h5 killed $h5 def $q5 +; FULLFP16-NEXT: // kill: def $h6 killed $h6 def $q6 +; FULLFP16-NEXT: // kill: def $h7 killed $h7 def $q7 +; FULLFP16-NEXT: mov v0.h[1], v1.h[0] +; FULLFP16-NEXT: ldr h1, [sp, #8] +; FULLFP16-NEXT: ld1 { v1.h }[1], [x9] +; FULLFP16-NEXT: add x9, sp, #24 +; FULLFP16-NEXT: mov v0.h[2], v2.h[0] +; FULLFP16-NEXT: ldr h2, [sp, #72] +; FULLFP16-NEXT: ld1 { v1.h }[2], [x9] +; FULLFP16-NEXT: add x9, sp, #32 +; FULLFP16-NEXT: mov v0.h[3], v3.h[0] +; FULLFP16-NEXT: ld1 { v1.h }[3], [x9] +; FULLFP16-NEXT: add x9, sp, #40 +; FULLFP16-NEXT: ldr h3, [sp] +; FULLFP16-NEXT: ld1 { v1.h }[4], [x9] +; FULLFP16-NEXT: add x9, sp, #48 +; FULLFP16-NEXT: fmaxnm v2.8h, v3.8h, v2.8h +; FULLFP16-NEXT: mov v0.h[4], v4.h[0] +; FULLFP16-NEXT: ld1 { v1.h }[5], [x9] +; FULLFP16-NEXT: add x9, sp, #56 +; FULLFP16-NEXT: str h2, [x8, #16] +; FULLFP16-NEXT: mov v0.h[5], v5.h[0] +; FULLFP16-NEXT: ld1 { v1.h }[6], [x9] +; FULLFP16-NEXT: add x9, sp, #64 +; FULLFP16-NEXT: mov v0.h[6], v6.h[0] +; FULLFP16-NEXT: ld1 { v1.h }[7], [x9] +; FULLFP16-NEXT: mov v0.h[7], v7.h[0] +; FULLFP16-NEXT: fmaxnm v0.8h, v0.8h, v1.8h +; FULLFP16-NEXT: str q0, [x8] +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: max_nofpclass_s_v9f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: // kill: def $h0 killed $h0 def $q0 +; NOFULLFP16-NEXT: // kill: def $h1 killed $h1 def $q1 +; NOFULLFP16-NEXT: // kill: def $h2 killed $h2 def $q2 +; NOFULLFP16-NEXT: add x9, sp, #16 +; NOFULLFP16-NEXT: // kill: def $h3 killed $h3 def $q3 +; NOFULLFP16-NEXT: // kill: def $h4 killed $h4 def $q4 +; NOFULLFP16-NEXT: // kill: def $h5 killed $h5 def $q5 +; NOFULLFP16-NEXT: // kill: def $h6 killed $h6 def $q6 +; NOFULLFP16-NEXT: // kill: def $h7 killed $h7 def $q7 +; NOFULLFP16-NEXT: mov v0.h[1], v1.h[0] +; NOFULLFP16-NEXT: ldr h1, [sp, #8] +; NOFULLFP16-NEXT: ld1 { v1.h }[1], [x9] +; NOFULLFP16-NEXT: add x9, sp, #24 +; NOFULLFP16-NEXT: mov v0.h[2], v2.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[2], [x9] +; NOFULLFP16-NEXT: add x9, sp, #32 +; NOFULLFP16-NEXT: mov v0.h[3], v3.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[3], [x9] +; NOFULLFP16-NEXT: add x9, sp, #40 +; NOFULLFP16-NEXT: ld1 { v1.h }[4], [x9] +; NOFULLFP16-NEXT: add x9, sp, #48 +; NOFULLFP16-NEXT: mov v0.h[4], v4.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[5], [x9] +; NOFULLFP16-NEXT: add x9, sp, #56 +; NOFULLFP16-NEXT: mov v0.h[5], v5.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[6], [x9] +; NOFULLFP16-NEXT: add x9, sp, #64 +; NOFULLFP16-NEXT: mov v0.h[6], v6.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[7], [x9] +; NOFULLFP16-NEXT: mov h2, v1.h[1] +; NOFULLFP16-NEXT: fcvt s4, h1 +; NOFULLFP16-NEXT: mov h6, v1.h[2] +; NOFULLFP16-NEXT: mov v0.h[7], v7.h[0] +; NOFULLFP16-NEXT: mov h16, v1.h[3] +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: mov h3, v0.h[1] +; NOFULLFP16-NEXT: fcvt s5, h0 +; NOFULLFP16-NEXT: mov h7, v0.h[2] +; NOFULLFP16-NEXT: mov h17, v0.h[3] +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fmaxnm s4, s5, s4 +; NOFULLFP16-NEXT: fcvt s5, h6 +; NOFULLFP16-NEXT: fcvt s6, h7 +; NOFULLFP16-NEXT: fcvt s7, h16 +; NOFULLFP16-NEXT: fcvt s16, h17 +; NOFULLFP16-NEXT: fmaxnm s3, s3, s2 +; NOFULLFP16-NEXT: fcvt h2, s4 +; NOFULLFP16-NEXT: mov h4, v1.h[4] +; NOFULLFP16-NEXT: fmaxnm s5, s6, s5 +; NOFULLFP16-NEXT: mov h6, v0.h[4] +; NOFULLFP16-NEXT: fmaxnm s7, s16, s7 +; NOFULLFP16-NEXT: mov h16, v1.h[5] +; NOFULLFP16-NEXT: fcvt h3, s3 +; NOFULLFP16-NEXT: fcvt s4, h4 +; NOFULLFP16-NEXT: fcvt s6, h6 +; NOFULLFP16-NEXT: fcvt h5, s5 +; NOFULLFP16-NEXT: fcvt s16, h16 +; NOFULLFP16-NEXT: mov v2.h[1], v3.h[0] +; NOFULLFP16-NEXT: mov h3, v0.h[5] +; NOFULLFP16-NEXT: fmaxnm s4, s6, s4 +; NOFULLFP16-NEXT: fcvt h6, s7 +; NOFULLFP16-NEXT: mov h7, v0.h[6] +; NOFULLFP16-NEXT: mov h0, v0.h[7] +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: mov v2.h[2], v5.h[0] +; NOFULLFP16-NEXT: mov h5, v1.h[6] +; NOFULLFP16-NEXT: mov h1, v1.h[7] +; NOFULLFP16-NEXT: fcvt h4, s4 +; NOFULLFP16-NEXT: fcvt s0, h0 +; NOFULLFP16-NEXT: fmaxnm s3, s3, s16 +; NOFULLFP16-NEXT: mov v2.h[3], v6.h[0] +; NOFULLFP16-NEXT: fcvt s5, h5 +; NOFULLFP16-NEXT: fcvt s6, h7 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fcvt h3, s3 +; NOFULLFP16-NEXT: mov v2.h[4], v4.h[0] +; NOFULLFP16-NEXT: fmaxnm s4, s6, s5 +; NOFULLFP16-NEXT: ldr h5, [sp] +; NOFULLFP16-NEXT: ldr h6, [sp, #72] +; NOFULLFP16-NEXT: fmaxnm s0, s0, s1 +; NOFULLFP16-NEXT: fcvt s6, h6 +; NOFULLFP16-NEXT: fcvt s5, h5 +; NOFULLFP16-NEXT: mov v2.h[5], v3.h[0] +; NOFULLFP16-NEXT: fcvt h3, s4 +; NOFULLFP16-NEXT: fcvt h0, s0 +; NOFULLFP16-NEXT: fmaxnm s1, s5, s6 +; NOFULLFP16-NEXT: mov v2.h[6], v3.h[0] +; NOFULLFP16-NEXT: fcvt h1, s1 +; NOFULLFP16-NEXT: mov v2.h[7], v0.h[0] +; NOFULLFP16-NEXT: str h1, [x8, #16] +; NOFULLFP16-NEXT: str q2, [x8] +; NOFULLFP16-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) { +; FULLFP16-LABEL: max_nofpclass_s_v16f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fmaxnm v1.8h, v1.8h, v3.8h +; FULLFP16-NEXT: fmaxnm v0.8h, v0.8h, v2.8h +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: max_nofpclass_s_v16f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: mov h6, v2.h[1] +; NOFULLFP16-NEXT: mov h7, v0.h[1] +; NOFULLFP16-NEXT: fcvt s4, h2 +; NOFULLFP16-NEXT: fcvt s5, h0 +; NOFULLFP16-NEXT: mov h16, v3.h[1] +; NOFULLFP16-NEXT: mov h17, v1.h[1] +; NOFULLFP16-NEXT: mov h18, v2.h[2] +; NOFULLFP16-NEXT: mov h19, v0.h[2] +; NOFULLFP16-NEXT: fcvt s20, h3 +; NOFULLFP16-NEXT: fcvt s21, h1 +; NOFULLFP16-NEXT: mov h22, v3.h[2] +; NOFULLFP16-NEXT: mov h23, v1.h[2] +; NOFULLFP16-NEXT: fcvt s6, h6 +; NOFULLFP16-NEXT: fcvt s7, h7 +; NOFULLFP16-NEXT: mov h24, v0.h[6] +; NOFULLFP16-NEXT: fmaxnm s4, s5, s4 +; NOFULLFP16-NEXT: fcvt s5, h16 +; NOFULLFP16-NEXT: fcvt s16, h17 +; NOFULLFP16-NEXT: fcvt s17, h18 +; NOFULLFP16-NEXT: fcvt s18, h19 +; NOFULLFP16-NEXT: mov h19, v0.h[3] +; NOFULLFP16-NEXT: fmaxnm s20, s21, s20 +; NOFULLFP16-NEXT: fcvt s21, h22 +; NOFULLFP16-NEXT: mov h22, v3.h[3] +; NOFULLFP16-NEXT: fmaxnm s6, s7, s6 +; NOFULLFP16-NEXT: mov h7, v2.h[3] +; NOFULLFP16-NEXT: mov h25, v1.h[6] +; NOFULLFP16-NEXT: fcvt h4, s4 +; NOFULLFP16-NEXT: fmaxnm s5, s16, s5 +; NOFULLFP16-NEXT: fcvt s16, h23 +; NOFULLFP16-NEXT: mov h23, v1.h[3] +; NOFULLFP16-NEXT: fmaxnm s17, s18, s17 +; NOFULLFP16-NEXT: fcvt s18, h19 +; NOFULLFP16-NEXT: fcvt h6, s6 +; NOFULLFP16-NEXT: fcvt s7, h7 +; NOFULLFP16-NEXT: fcvt h19, s5 +; NOFULLFP16-NEXT: fcvt h5, s20 +; NOFULLFP16-NEXT: fmaxnm s16, s16, s21 +; NOFULLFP16-NEXT: fcvt s20, h23 +; NOFULLFP16-NEXT: fcvt h17, s17 +; NOFULLFP16-NEXT: mov h21, v2.h[4] +; NOFULLFP16-NEXT: mov h23, v1.h[4] +; NOFULLFP16-NEXT: mov v4.h[1], v6.h[0] +; NOFULLFP16-NEXT: fcvt s6, h22 +; NOFULLFP16-NEXT: mov h22, v0.h[4] +; NOFULLFP16-NEXT: fmaxnm s7, s18, s7 +; NOFULLFP16-NEXT: mov h18, v3.h[4] +; NOFULLFP16-NEXT: mov v5.h[1], v19.h[0] +; NOFULLFP16-NEXT: fcvt h16, s16 +; NOFULLFP16-NEXT: fmaxnm s6, s20, s6 +; NOFULLFP16-NEXT: mov v4.h[2], v17.h[0] +; NOFULLFP16-NEXT: fcvt s17, h21 +; NOFULLFP16-NEXT: fcvt s19, h22 +; NOFULLFP16-NEXT: fcvt h7, s7 +; NOFULLFP16-NEXT: fcvt s18, h18 +; NOFULLFP16-NEXT: fcvt s20, h23 +; NOFULLFP16-NEXT: mov h21, v2.h[5] +; NOFULLFP16-NEXT: mov h22, v0.h[5] +; NOFULLFP16-NEXT: mov v5.h[2], v16.h[0] +; NOFULLFP16-NEXT: mov h16, v3.h[5] +; NOFULLFP16-NEXT: mov h23, v1.h[5] +; NOFULLFP16-NEXT: fcvt h6, s6 +; NOFULLFP16-NEXT: mov h0, v0.h[7] +; NOFULLFP16-NEXT: mov h1, v1.h[7] +; NOFULLFP16-NEXT: fmaxnm s17, s19, s17 +; NOFULLFP16-NEXT: mov h19, v2.h[6] +; NOFULLFP16-NEXT: mov v4.h[3], v7.h[0] +; NOFULLFP16-NEXT: fmaxnm s18, s20, s18 +; NOFULLFP16-NEXT: mov h20, v3.h[6] +; NOFULLFP16-NEXT: fcvt s7, h21 +; NOFULLFP16-NEXT: fcvt s21, h22 +; NOFULLFP16-NEXT: fcvt s22, h24 +; NOFULLFP16-NEXT: mov h2, v2.h[7] +; NOFULLFP16-NEXT: mov v5.h[3], v6.h[0] +; NOFULLFP16-NEXT: fcvt s6, h16 +; NOFULLFP16-NEXT: fcvt s16, h23 +; NOFULLFP16-NEXT: fcvt h17, s17 +; NOFULLFP16-NEXT: fcvt s19, h19 +; NOFULLFP16-NEXT: fcvt s23, h25 +; NOFULLFP16-NEXT: fcvt h18, s18 +; NOFULLFP16-NEXT: fcvt s20, h20 +; NOFULLFP16-NEXT: mov h3, v3.h[7] +; NOFULLFP16-NEXT: fmaxnm s7, s21, s7 +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: fcvt s0, h0 +; NOFULLFP16-NEXT: fmaxnm s6, s16, s6 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: mov v4.h[4], v17.h[0] +; NOFULLFP16-NEXT: fmaxnm s16, s22, s19 +; NOFULLFP16-NEXT: mov v5.h[4], v18.h[0] +; NOFULLFP16-NEXT: fmaxnm s17, s23, s20 +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fcvt h7, s7 +; NOFULLFP16-NEXT: fmaxnm s0, s0, s2 +; NOFULLFP16-NEXT: fcvt h6, s6 +; NOFULLFP16-NEXT: fcvt h2, s16 +; NOFULLFP16-NEXT: fmaxnm s1, s1, s3 +; NOFULLFP16-NEXT: mov v4.h[5], v7.h[0] +; NOFULLFP16-NEXT: fcvt h0, s0 +; NOFULLFP16-NEXT: mov v5.h[5], v6.h[0] +; NOFULLFP16-NEXT: fcvt h6, s17 +; NOFULLFP16-NEXT: fcvt h1, s1 +; NOFULLFP16-NEXT: mov v4.h[6], v2.h[0] +; NOFULLFP16-NEXT: mov v5.h[6], v6.h[0] +; NOFULLFP16-NEXT: mov v4.h[7], v0.h[0] +; NOFULLFP16-NEXT: mov v5.h[7], v1.h[0] +; NOFULLFP16-NEXT: mov v0.16b, v4.16b +; NOFULLFP16-NEXT: mov v1.16b, v5.16b +; NOFULLFP16-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 v3.d[1], v4.d[0] +; AARCH64-NEXT: mov v0.d[1], v1.d[0] +; AARCH64-NEXT: fminnm v2.2d, v2.2d, v5.2d +; AARCH64-NEXT: // kill: def $d2 killed $d2 killed $q2 +; AARCH64-NEXT: fminnm v0.2d, v0.2d, v3.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: 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 v1.2d, v1.2d, v3.2d +; AARCH64-NEXT: fminnm v0.2d, v0.2d, v2.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 v4.4s, v4.4s, v2.4s +; AARCH64-NEXT: // kill: def $s4 killed $s4 killed $q4 +; AARCH64-NEXT: mov v0.s[3], v3.s[0] +; AARCH64-NEXT: ld1 { v5.s }[3], [x8] +; AARCH64-NEXT: fminnm v0.4s, v0.4s, v5.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 v1.4s, v1.4s, v3.4s +; AARCH64-NEXT: fminnm v0.4s, v0.4s, v2.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) { +; FULLFP16-LABEL: min_nofpclass_s_f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fminnm h0, h0, h1 +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: min_nofpclass_s_f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fcvt s0, h0 +; NOFULLFP16-NEXT: fminnm s0, s0, s1 +; NOFULLFP16-NEXT: fcvt h0, s0 +; NOFULLFP16-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) { +; FULLFP16-LABEL: min_nofpclass_s_v2f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fminnm v0.4h, v0.4h, v1.4h +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: min_nofpclass_s_v2f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: // kill: def $d1 killed $d1 def $q1 +; NOFULLFP16-NEXT: // kill: def $d0 killed $d0 def $q0 +; NOFULLFP16-NEXT: mov h2, v1.h[1] +; NOFULLFP16-NEXT: mov h3, v0.h[1] +; NOFULLFP16-NEXT: mov h4, v1.h[2] +; NOFULLFP16-NEXT: mov h5, v0.h[2] +; NOFULLFP16-NEXT: fcvt s6, h1 +; NOFULLFP16-NEXT: fcvt s7, h0 +; NOFULLFP16-NEXT: mov h1, v1.h[3] +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fminnm s2, s3, s2 +; NOFULLFP16-NEXT: fcvt s3, h4 +; NOFULLFP16-NEXT: fcvt s4, h5 +; NOFULLFP16-NEXT: fminnm s5, s7, s6 +; NOFULLFP16-NEXT: mov h6, v0.h[3] +; NOFULLFP16-NEXT: fminnm s3, s4, s3 +; NOFULLFP16-NEXT: fcvt h2, s2 +; NOFULLFP16-NEXT: fcvt h0, s5 +; NOFULLFP16-NEXT: fcvt s4, h6 +; NOFULLFP16-NEXT: mov v0.h[1], v2.h[0] +; NOFULLFP16-NEXT: fcvt h2, s3 +; NOFULLFP16-NEXT: fminnm s1, s4, s1 +; NOFULLFP16-NEXT: mov v0.h[2], v2.h[0] +; NOFULLFP16-NEXT: fcvt h1, s1 +; NOFULLFP16-NEXT: mov v0.h[3], v1.h[0] +; NOFULLFP16-NEXT: // kill: def $d0 killed $d0 killed $q0 +; NOFULLFP16-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) { +; FULLFP16-LABEL: min_nofpclass_s_v4f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fminnm v0.4h, v0.4h, v1.4h +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: min_nofpclass_s_v4f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: // kill: def $d1 killed $d1 def $q1 +; NOFULLFP16-NEXT: // kill: def $d0 killed $d0 def $q0 +; NOFULLFP16-NEXT: mov h2, v1.h[1] +; NOFULLFP16-NEXT: mov h3, v0.h[1] +; NOFULLFP16-NEXT: mov h4, v1.h[2] +; NOFULLFP16-NEXT: mov h5, v0.h[2] +; NOFULLFP16-NEXT: fcvt s6, h1 +; NOFULLFP16-NEXT: fcvt s7, h0 +; NOFULLFP16-NEXT: mov h1, v1.h[3] +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fminnm s2, s3, s2 +; NOFULLFP16-NEXT: fcvt s3, h4 +; NOFULLFP16-NEXT: fcvt s4, h5 +; NOFULLFP16-NEXT: fminnm s5, s7, s6 +; NOFULLFP16-NEXT: mov h6, v0.h[3] +; NOFULLFP16-NEXT: fminnm s3, s4, s3 +; NOFULLFP16-NEXT: fcvt h2, s2 +; NOFULLFP16-NEXT: fcvt h0, s5 +; NOFULLFP16-NEXT: fcvt s4, h6 +; NOFULLFP16-NEXT: mov v0.h[1], v2.h[0] +; NOFULLFP16-NEXT: fcvt h2, s3 +; NOFULLFP16-NEXT: fminnm s1, s4, s1 +; NOFULLFP16-NEXT: mov v0.h[2], v2.h[0] +; NOFULLFP16-NEXT: fcvt h1, s1 +; NOFULLFP16-NEXT: mov v0.h[3], v1.h[0] +; NOFULLFP16-NEXT: // kill: def $d0 killed $d0 killed $q0 +; NOFULLFP16-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) { +; FULLFP16-LABEL: min_nofpclass_s_v8f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fminnm v0.8h, v0.8h, v1.8h +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: min_nofpclass_s_v8f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: mov h2, v1.h[1] +; NOFULLFP16-NEXT: mov h3, v0.h[1] +; NOFULLFP16-NEXT: fcvt s4, h1 +; NOFULLFP16-NEXT: fcvt s5, h0 +; NOFULLFP16-NEXT: mov h6, v1.h[2] +; NOFULLFP16-NEXT: mov h7, v0.h[2] +; NOFULLFP16-NEXT: mov h16, v1.h[3] +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fminnm s4, s5, s4 +; NOFULLFP16-NEXT: mov h5, v0.h[3] +; NOFULLFP16-NEXT: fcvt s6, h6 +; NOFULLFP16-NEXT: fcvt s7, h7 +; NOFULLFP16-NEXT: fcvt s16, h16 +; NOFULLFP16-NEXT: fminnm s3, s3, s2 +; NOFULLFP16-NEXT: fcvt s5, h5 +; NOFULLFP16-NEXT: fcvt h2, s4 +; NOFULLFP16-NEXT: fminnm s4, s7, s6 +; NOFULLFP16-NEXT: mov h6, v1.h[4] +; NOFULLFP16-NEXT: mov h7, v0.h[4] +; NOFULLFP16-NEXT: fcvt h3, s3 +; NOFULLFP16-NEXT: fminnm s5, s5, s16 +; NOFULLFP16-NEXT: mov h16, v0.h[5] +; NOFULLFP16-NEXT: fcvt h4, s4 +; NOFULLFP16-NEXT: mov v2.h[1], v3.h[0] +; NOFULLFP16-NEXT: fcvt s3, h6 +; NOFULLFP16-NEXT: fcvt s6, h7 +; NOFULLFP16-NEXT: mov h7, v1.h[5] +; NOFULLFP16-NEXT: fcvt h5, s5 +; NOFULLFP16-NEXT: fcvt s16, h16 +; NOFULLFP16-NEXT: mov v2.h[2], v4.h[0] +; NOFULLFP16-NEXT: mov h4, v1.h[6] +; NOFULLFP16-NEXT: fminnm s3, s6, s3 +; NOFULLFP16-NEXT: mov h6, v0.h[6] +; NOFULLFP16-NEXT: fcvt s7, h7 +; NOFULLFP16-NEXT: mov h1, v1.h[7] +; NOFULLFP16-NEXT: mov h0, v0.h[7] +; NOFULLFP16-NEXT: mov v2.h[3], v5.h[0] +; NOFULLFP16-NEXT: fcvt s4, h4 +; NOFULLFP16-NEXT: fcvt h3, s3 +; NOFULLFP16-NEXT: fcvt s5, h6 +; NOFULLFP16-NEXT: fminnm s6, s16, s7 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fcvt s0, h0 +; NOFULLFP16-NEXT: mov v2.h[4], v3.h[0] +; NOFULLFP16-NEXT: fminnm s4, s5, s4 +; NOFULLFP16-NEXT: fcvt h3, s6 +; NOFULLFP16-NEXT: fminnm s0, s0, s1 +; NOFULLFP16-NEXT: mov v2.h[5], v3.h[0] +; NOFULLFP16-NEXT: fcvt h3, s4 +; NOFULLFP16-NEXT: fcvt h0, s0 +; NOFULLFP16-NEXT: mov v2.h[6], v3.h[0] +; NOFULLFP16-NEXT: mov v2.h[7], v0.h[0] +; NOFULLFP16-NEXT: mov v0.16b, v2.16b +; NOFULLFP16-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) { +; FULLFP16-LABEL: min_nofpclass_s_v9f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: // kill: def $h0 killed $h0 def $q0 +; FULLFP16-NEXT: // kill: def $h1 killed $h1 def $q1 +; FULLFP16-NEXT: // kill: def $h2 killed $h2 def $q2 +; FULLFP16-NEXT: add x9, sp, #16 +; FULLFP16-NEXT: // kill: def $h3 killed $h3 def $q3 +; FULLFP16-NEXT: // kill: def $h4 killed $h4 def $q4 +; FULLFP16-NEXT: // kill: def $h5 killed $h5 def $q5 +; FULLFP16-NEXT: // kill: def $h6 killed $h6 def $q6 +; FULLFP16-NEXT: // kill: def $h7 killed $h7 def $q7 +; FULLFP16-NEXT: mov v0.h[1], v1.h[0] +; FULLFP16-NEXT: ldr h1, [sp, #8] +; FULLFP16-NEXT: ld1 { v1.h }[1], [x9] +; FULLFP16-NEXT: add x9, sp, #24 +; FULLFP16-NEXT: mov v0.h[2], v2.h[0] +; FULLFP16-NEXT: ldr h2, [sp, #72] +; FULLFP16-NEXT: ld1 { v1.h }[2], [x9] +; FULLFP16-NEXT: add x9, sp, #32 +; FULLFP16-NEXT: mov v0.h[3], v3.h[0] +; FULLFP16-NEXT: ld1 { v1.h }[3], [x9] +; FULLFP16-NEXT: add x9, sp, #40 +; FULLFP16-NEXT: ldr h3, [sp] +; FULLFP16-NEXT: ld1 { v1.h }[4], [x9] +; FULLFP16-NEXT: add x9, sp, #48 +; FULLFP16-NEXT: fminnm v2.8h, v3.8h, v2.8h +; FULLFP16-NEXT: mov v0.h[4], v4.h[0] +; FULLFP16-NEXT: ld1 { v1.h }[5], [x9] +; FULLFP16-NEXT: add x9, sp, #56 +; FULLFP16-NEXT: str h2, [x8, #16] +; FULLFP16-NEXT: mov v0.h[5], v5.h[0] +; FULLFP16-NEXT: ld1 { v1.h }[6], [x9] +; FULLFP16-NEXT: add x9, sp, #64 +; FULLFP16-NEXT: mov v0.h[6], v6.h[0] +; FULLFP16-NEXT: ld1 { v1.h }[7], [x9] +; FULLFP16-NEXT: mov v0.h[7], v7.h[0] +; FULLFP16-NEXT: fminnm v0.8h, v0.8h, v1.8h +; FULLFP16-NEXT: str q0, [x8] +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: min_nofpclass_s_v9f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: // kill: def $h0 killed $h0 def $q0 +; NOFULLFP16-NEXT: // kill: def $h1 killed $h1 def $q1 +; NOFULLFP16-NEXT: // kill: def $h2 killed $h2 def $q2 +; NOFULLFP16-NEXT: add x9, sp, #16 +; NOFULLFP16-NEXT: // kill: def $h3 killed $h3 def $q3 +; NOFULLFP16-NEXT: // kill: def $h4 killed $h4 def $q4 +; NOFULLFP16-NEXT: // kill: def $h5 killed $h5 def $q5 +; NOFULLFP16-NEXT: // kill: def $h6 killed $h6 def $q6 +; NOFULLFP16-NEXT: // kill: def $h7 killed $h7 def $q7 +; NOFULLFP16-NEXT: mov v0.h[1], v1.h[0] +; NOFULLFP16-NEXT: ldr h1, [sp, #8] +; NOFULLFP16-NEXT: ld1 { v1.h }[1], [x9] +; NOFULLFP16-NEXT: add x9, sp, #24 +; NOFULLFP16-NEXT: mov v0.h[2], v2.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[2], [x9] +; NOFULLFP16-NEXT: add x9, sp, #32 +; NOFULLFP16-NEXT: mov v0.h[3], v3.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[3], [x9] +; NOFULLFP16-NEXT: add x9, sp, #40 +; NOFULLFP16-NEXT: ld1 { v1.h }[4], [x9] +; NOFULLFP16-NEXT: add x9, sp, #48 +; NOFULLFP16-NEXT: mov v0.h[4], v4.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[5], [x9] +; NOFULLFP16-NEXT: add x9, sp, #56 +; NOFULLFP16-NEXT: mov v0.h[5], v5.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[6], [x9] +; NOFULLFP16-NEXT: add x9, sp, #64 +; NOFULLFP16-NEXT: mov v0.h[6], v6.h[0] +; NOFULLFP16-NEXT: ld1 { v1.h }[7], [x9] +; NOFULLFP16-NEXT: mov h2, v1.h[1] +; NOFULLFP16-NEXT: fcvt s4, h1 +; NOFULLFP16-NEXT: mov h6, v1.h[2] +; NOFULLFP16-NEXT: mov v0.h[7], v7.h[0] +; NOFULLFP16-NEXT: mov h16, v1.h[3] +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: mov h3, v0.h[1] +; NOFULLFP16-NEXT: fcvt s5, h0 +; NOFULLFP16-NEXT: mov h7, v0.h[2] +; NOFULLFP16-NEXT: mov h17, v0.h[3] +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fminnm s4, s5, s4 +; NOFULLFP16-NEXT: fcvt s5, h6 +; NOFULLFP16-NEXT: fcvt s6, h7 +; NOFULLFP16-NEXT: fcvt s7, h16 +; NOFULLFP16-NEXT: fcvt s16, h17 +; NOFULLFP16-NEXT: fminnm s3, s3, s2 +; NOFULLFP16-NEXT: fcvt h2, s4 +; NOFULLFP16-NEXT: mov h4, v1.h[4] +; NOFULLFP16-NEXT: fminnm s5, s6, s5 +; NOFULLFP16-NEXT: mov h6, v0.h[4] +; NOFULLFP16-NEXT: fminnm s7, s16, s7 +; NOFULLFP16-NEXT: mov h16, v1.h[5] +; NOFULLFP16-NEXT: fcvt h3, s3 +; NOFULLFP16-NEXT: fcvt s4, h4 +; NOFULLFP16-NEXT: fcvt s6, h6 +; NOFULLFP16-NEXT: fcvt h5, s5 +; NOFULLFP16-NEXT: fcvt s16, h16 +; NOFULLFP16-NEXT: mov v2.h[1], v3.h[0] +; NOFULLFP16-NEXT: mov h3, v0.h[5] +; NOFULLFP16-NEXT: fminnm s4, s6, s4 +; NOFULLFP16-NEXT: fcvt h6, s7 +; NOFULLFP16-NEXT: mov h7, v0.h[6] +; NOFULLFP16-NEXT: mov h0, v0.h[7] +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: mov v2.h[2], v5.h[0] +; NOFULLFP16-NEXT: mov h5, v1.h[6] +; NOFULLFP16-NEXT: mov h1, v1.h[7] +; NOFULLFP16-NEXT: fcvt h4, s4 +; NOFULLFP16-NEXT: fcvt s0, h0 +; NOFULLFP16-NEXT: fminnm s3, s3, s16 +; NOFULLFP16-NEXT: mov v2.h[3], v6.h[0] +; NOFULLFP16-NEXT: fcvt s5, h5 +; NOFULLFP16-NEXT: fcvt s6, h7 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: fcvt h3, s3 +; NOFULLFP16-NEXT: mov v2.h[4], v4.h[0] +; NOFULLFP16-NEXT: fminnm s4, s6, s5 +; NOFULLFP16-NEXT: ldr h5, [sp] +; NOFULLFP16-NEXT: ldr h6, [sp, #72] +; NOFULLFP16-NEXT: fminnm s0, s0, s1 +; NOFULLFP16-NEXT: fcvt s6, h6 +; NOFULLFP16-NEXT: fcvt s5, h5 +; NOFULLFP16-NEXT: mov v2.h[5], v3.h[0] +; NOFULLFP16-NEXT: fcvt h3, s4 +; NOFULLFP16-NEXT: fcvt h0, s0 +; NOFULLFP16-NEXT: fminnm s1, s5, s6 +; NOFULLFP16-NEXT: mov v2.h[6], v3.h[0] +; NOFULLFP16-NEXT: fcvt h1, s1 +; NOFULLFP16-NEXT: mov v2.h[7], v0.h[0] +; NOFULLFP16-NEXT: str h1, [x8, #16] +; NOFULLFP16-NEXT: str q2, [x8] +; NOFULLFP16-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) { +; FULLFP16-LABEL: min_nofpclass_s_v16f16: +; FULLFP16: // %bb.0: // %entry +; FULLFP16-NEXT: fminnm v1.8h, v1.8h, v3.8h +; FULLFP16-NEXT: fminnm v0.8h, v0.8h, v2.8h +; FULLFP16-NEXT: ret +; +; NOFULLFP16-LABEL: min_nofpclass_s_v16f16: +; NOFULLFP16: // %bb.0: // %entry +; NOFULLFP16-NEXT: mov h6, v2.h[1] +; NOFULLFP16-NEXT: mov h7, v0.h[1] +; NOFULLFP16-NEXT: fcvt s4, h2 +; NOFULLFP16-NEXT: fcvt s5, h0 +; NOFULLFP16-NEXT: mov h16, v3.h[1] +; NOFULLFP16-NEXT: mov h17, v1.h[1] +; NOFULLFP16-NEXT: mov h18, v2.h[2] +; NOFULLFP16-NEXT: mov h19, v0.h[2] +; NOFULLFP16-NEXT: fcvt s20, h3 +; NOFULLFP16-NEXT: fcvt s21, h1 +; NOFULLFP16-NEXT: mov h22, v3.h[2] +; NOFULLFP16-NEXT: mov h23, v1.h[2] +; NOFULLFP16-NEXT: fcvt s6, h6 +; NOFULLFP16-NEXT: fcvt s7, h7 +; NOFULLFP16-NEXT: mov h24, v0.h[6] +; NOFULLFP16-NEXT: fminnm s4, s5, s4 +; NOFULLFP16-NEXT: fcvt s5, h16 +; NOFULLFP16-NEXT: fcvt s16, h17 +; NOFULLFP16-NEXT: fcvt s17, h18 +; NOFULLFP16-NEXT: fcvt s18, h19 +; NOFULLFP16-NEXT: mov h19, v0.h[3] +; NOFULLFP16-NEXT: fminnm s20, s21, s20 +; NOFULLFP16-NEXT: fcvt s21, h22 +; NOFULLFP16-NEXT: mov h22, v3.h[3] +; NOFULLFP16-NEXT: fminnm s6, s7, s6 +; NOFULLFP16-NEXT: mov h7, v2.h[3] +; NOFULLFP16-NEXT: mov h25, v1.h[6] +; NOFULLFP16-NEXT: fcvt h4, s4 +; NOFULLFP16-NEXT: fminnm s5, s16, s5 +; NOFULLFP16-NEXT: fcvt s16, h23 +; NOFULLFP16-NEXT: mov h23, v1.h[3] +; NOFULLFP16-NEXT: fminnm s17, s18, s17 +; NOFULLFP16-NEXT: fcvt s18, h19 +; NOFULLFP16-NEXT: fcvt h6, s6 +; NOFULLFP16-NEXT: fcvt s7, h7 +; NOFULLFP16-NEXT: fcvt h19, s5 +; NOFULLFP16-NEXT: fcvt h5, s20 +; NOFULLFP16-NEXT: fminnm s16, s16, s21 +; NOFULLFP16-NEXT: fcvt s20, h23 +; NOFULLFP16-NEXT: fcvt h17, s17 +; NOFULLFP16-NEXT: mov h21, v2.h[4] +; NOFULLFP16-NEXT: mov h23, v1.h[4] +; NOFULLFP16-NEXT: mov v4.h[1], v6.h[0] +; NOFULLFP16-NEXT: fcvt s6, h22 +; NOFULLFP16-NEXT: mov h22, v0.h[4] +; NOFULLFP16-NEXT: fminnm s7, s18, s7 +; NOFULLFP16-NEXT: mov h18, v3.h[4] +; NOFULLFP16-NEXT: mov v5.h[1], v19.h[0] +; NOFULLFP16-NEXT: fcvt h16, s16 +; NOFULLFP16-NEXT: fminnm s6, s20, s6 +; NOFULLFP16-NEXT: mov v4.h[2], v17.h[0] +; NOFULLFP16-NEXT: fcvt s17, h21 +; NOFULLFP16-NEXT: fcvt s19, h22 +; NOFULLFP16-NEXT: fcvt h7, s7 +; NOFULLFP16-NEXT: fcvt s18, h18 +; NOFULLFP16-NEXT: fcvt s20, h23 +; NOFULLFP16-NEXT: mov h21, v2.h[5] +; NOFULLFP16-NEXT: mov h22, v0.h[5] +; NOFULLFP16-NEXT: mov v5.h[2], v16.h[0] +; NOFULLFP16-NEXT: mov h16, v3.h[5] +; NOFULLFP16-NEXT: mov h23, v1.h[5] +; NOFULLFP16-NEXT: fcvt h6, s6 +; NOFULLFP16-NEXT: mov h0, v0.h[7] +; NOFULLFP16-NEXT: mov h1, v1.h[7] +; NOFULLFP16-NEXT: fminnm s17, s19, s17 +; NOFULLFP16-NEXT: mov h19, v2.h[6] +; NOFULLFP16-NEXT: mov v4.h[3], v7.h[0] +; NOFULLFP16-NEXT: fminnm s18, s20, s18 +; NOFULLFP16-NEXT: mov h20, v3.h[6] +; NOFULLFP16-NEXT: fcvt s7, h21 +; NOFULLFP16-NEXT: fcvt s21, h22 +; NOFULLFP16-NEXT: fcvt s22, h24 +; NOFULLFP16-NEXT: mov h2, v2.h[7] +; NOFULLFP16-NEXT: mov v5.h[3], v6.h[0] +; NOFULLFP16-NEXT: fcvt s6, h16 +; NOFULLFP16-NEXT: fcvt s16, h23 +; NOFULLFP16-NEXT: fcvt h17, s17 +; NOFULLFP16-NEXT: fcvt s19, h19 +; NOFULLFP16-NEXT: fcvt s23, h25 +; NOFULLFP16-NEXT: fcvt h18, s18 +; NOFULLFP16-NEXT: fcvt s20, h20 +; NOFULLFP16-NEXT: mov h3, v3.h[7] +; NOFULLFP16-NEXT: fminnm s7, s21, s7 +; NOFULLFP16-NEXT: fcvt s2, h2 +; NOFULLFP16-NEXT: fcvt s0, h0 +; NOFULLFP16-NEXT: fminnm s6, s16, s6 +; NOFULLFP16-NEXT: fcvt s1, h1 +; NOFULLFP16-NEXT: mov v4.h[4], v17.h[0] +; NOFULLFP16-NEXT: fminnm s16, s22, s19 +; NOFULLFP16-NEXT: mov v5.h[4], v18.h[0] +; NOFULLFP16-NEXT: fminnm s17, s23, s20 +; NOFULLFP16-NEXT: fcvt s3, h3 +; NOFULLFP16-NEXT: fcvt h7, s7 +; NOFULLFP16-NEXT: fminnm s0, s0, s2 +; NOFULLFP16-NEXT: fcvt h6, s6 +; NOFULLFP16-NEXT: fcvt h2, s16 +; NOFULLFP16-NEXT: fminnm s1, s1, s3 +; NOFULLFP16-NEXT: mov v4.h[5], v7.h[0] +; NOFULLFP16-NEXT: fcvt h0, s0 +; NOFULLFP16-NEXT: mov v5.h[5], v6.h[0] +; NOFULLFP16-NEXT: fcvt h6, s17 +; NOFULLFP16-NEXT: fcvt h1, s1 +; NOFULLFP16-NEXT: mov v4.h[6], v2.h[0] +; NOFULLFP16-NEXT: mov v5.h[6], v6.h[0] +; NOFULLFP16-NEXT: mov v4.h[7], v0.h[0] +; NOFULLFP16-NEXT: mov v5.h[7], v1.h[0] +; NOFULLFP16-NEXT: mov v0.16b, v4.16b +; NOFULLFP16-NEXT: mov v1.16b, v5.16b +; NOFULLFP16-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 607e50cb5a6c6..704ff592996fc 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) { ; @@ -223,6 +271,81 @@ 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: pcaddu18i $ra, %call36(fmaximum_num) +; LA64F-NEXT: jirl $ra, $ra, 0 +; 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: pcaddu18i $ra, %call36(fmaximum_num) +; LA64F-NEXT: jirl $ra, $ra, 0 +; 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: @@ -314,6 +437,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: @@ -435,3 +606,77 @@ 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: pcaddu18i $ra, %call36(fminimum_num) +; LA64F-NEXT: jirl $ra, $ra, 0 +; 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: pcaddu18i $ra, %call36(fminimum_num) +; LA64F-NEXT: jirl $ra, $ra, 0 +; 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 +}