diff --git a/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td --- a/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td @@ -153,10 +153,11 @@ def : PatFpr; def : PatFpr; def : PatFpr; - def : Pat<(fdiv fpimm1, (fsqrt FPR32:$fj)), (FRSQRT_S FPR32:$fj)>; - def : Pat<(fcanonicalize FPR32:$fj), (FMAX_S $fj, $fj)>; +def : Pat<(is_fpclass FPR32:$fj, (i32 timm:$mask)), + (SLTU R0, (AND (MOVFR2GR_S (FCLASS_S FPR32:$fj)), + (to_fclass_mask timm:$mask)))>; /// Setcc diff --git a/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td --- a/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td @@ -142,15 +142,22 @@ def : PatFpr; def : PatFpr; def : PatFpr; - def : Pat<(fdiv fpimm1, (fsqrt FPR64:$fj)), (FRSQRT_D FPR64:$fj)>; - def : Pat<(fcopysign FPR64:$fj, FPR32:$fk), (FCOPYSIGN_D FPR64:$fj, (FCVT_D_S FPR32:$fk))>; def : Pat<(fcopysign FPR32:$fj, FPR64:$fk), (FCOPYSIGN_S FPR32:$fj, (FCVT_S_D FPR64:$fk))>; - def : Pat<(fcanonicalize FPR64:$fj), (FMAX_D $fj, $fj)>; +let Predicates = [IsLA32] in { +def : Pat<(is_fpclass FPR64:$fj, (i32 timm:$mask)), + (SLTU R0, (AND (MOVFR2GR_S_64 (FCLASS_D FPR64:$fj)), + (to_fclass_mask timm:$mask)))>; +} // Predicates = [IsLA32] +let Predicates = [IsLA64] in { +def : Pat<(is_fpclass FPR64:$fj, (i32 timm:$mask)), + (SLTU R0, (AND (MOVFR2GR_D (FCLASS_D FPR64:$fj)), + (to_fclass_mask timm:$mask)))>; +} // Predicates = [IsLA64] /// Setcc diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -170,6 +170,7 @@ setOperationAction(ISD::FMAXNUM_IEEE, MVT::f32, Legal); setOperationAction(ISD::STRICT_FSETCCS, MVT::f32, Legal); setOperationAction(ISD::STRICT_FSETCC, MVT::f32, Legal); + setOperationAction(ISD::IS_FPCLASS, MVT::f32, Legal); setOperationAction(ISD::FSIN, MVT::f32, Expand); setOperationAction(ISD::FCOS, MVT::f32, Expand); setOperationAction(ISD::FSINCOS, MVT::f32, Expand); @@ -202,6 +203,7 @@ setOperationAction(ISD::FMA, MVT::f64, Legal); setOperationAction(ISD::FMINNUM_IEEE, MVT::f64, Legal); setOperationAction(ISD::FMAXNUM_IEEE, MVT::f64, Legal); + setOperationAction(ISD::IS_FPCLASS, MVT::f64, Legal); setOperationAction(ISD::FSIN, MVT::f64, Expand); setOperationAction(ISD::FCOS, MVT::f64, Expand); setOperationAction(ISD::FSINCOS, MVT::f64, Expand); diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.h b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.h --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.h +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.h @@ -88,5 +88,20 @@ const LoongArchSubtarget &STI; }; +namespace LoongArch { + +// Mask assignments for floating-point. +static constexpr unsigned FClassMaskSignalingNaN = 0x001; +static constexpr unsigned FClassMaskQuietNaN = 0x002; +static constexpr unsigned FClassMaskNegativeInfinity = 0x004; +static constexpr unsigned FClassMaskNegativeNormal = 0x008; +static constexpr unsigned FClassMaskNegativeSubnormal = 0x010; +static constexpr unsigned FClassMaskNegativeZero = 0x020; +static constexpr unsigned FClassMaskPositiveInfinity = 0x040; +static constexpr unsigned FClassMaskPositiveNormal = 0x080; +static constexpr unsigned FClassMaskPositiveSubnormal = 0x100; +static constexpr unsigned FClassMaskPositiveZero = 0x200; +} // namespace LoongArch + } // end namespace llvm #endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHINSTRINFO_H diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -143,6 +143,32 @@ def loongarch_cpucfg : SDNode<"LoongArchISD::CPUCFG", SDTUnaryOp, [SDNPHasChain]>; +def to_fclass_mask: SDNodeXFormgetZExtValue(); + unsigned Mask = 0; + if (Check & fcSNan) + Mask |= LoongArch::FClassMaskSignalingNaN; + if (Check & fcQNan) + Mask |= LoongArch::FClassMaskQuietNaN; + if (Check & fcPosInf) + Mask |= LoongArch::FClassMaskPositiveInfinity; + if (Check & fcNegInf) + Mask |= LoongArch::FClassMaskNegativeInfinity; + if (Check & fcPosNormal) + Mask |= LoongArch::FClassMaskPositiveNormal; + if (Check & fcNegNormal) + Mask |= LoongArch::FClassMaskNegativeNormal; + if (Check & fcPosSubnormal) + Mask |= LoongArch::FClassMaskPositiveSubnormal; + if (Check & fcNegSubnormal) + Mask |= LoongArch::FClassMaskNegativeSubnormal; + if (Check & fcPosZero) + Mask |= LoongArch::FClassMaskPositiveZero; + if (Check & fcNegZero) + Mask |= LoongArch::FClassMaskNegativeZero; + return CurDAG->getTargetConstant(Mask, SDLoc(N), Subtarget->getGRLenVT()); +}]>; + //===----------------------------------------------------------------------===// // Operand and SDNode transformation definitions. //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/LoongArch/is_fpclass_f32.ll b/llvm/test/CodeGen/LoongArch/is_fpclass_f32.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/LoongArch/is_fpclass_f32.ll @@ -0,0 +1,843 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc --mtriple=loongarch32 --mattr=+f < %s | FileCheck %s +; RUN: llc --mtriple=loongarch64 --mattr=+f < %s | FileCheck %s + +define i1 @isnan_f(float %x) { +; CHECK-LABEL: isnan_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 3 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 3) ; "nan" + ret i1 %0 +} + +define i1 @isnot_nan_f(float %x) { +; CHECK-LABEL: isnot_nan_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 1020 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1020) ; 0x3fc = "zero|subnormal|normal|inf" + ret i1 %0 +} + +define i1 @issignaling_f(float %x) { +; CHECK-LABEL: issignaling_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 1 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1) ; "snan" + ret i1 %0 +} + +define i1 @not_issignaling_f(float %x) { +; CHECK-LABEL: not_issignaling_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 1022 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1022) ; ~"snan" + ret i1 %0 +} + +define i1 @isquiet_f(float %x) { +; CHECK-LABEL: isquiet_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 2 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 2) ; "qnan" + ret i1 %0 +} + +define i1 @not_isquiet_f(float %x) { +; CHECK-LABEL: not_isquiet_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 1021 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1021) ; ~"qnan" + ret i1 %0 +} + +define i1 @isinf_f(float %x) { +; CHECK-LABEL: isinf_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 68 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 516) ; 0x204 = "inf" + ret i1 %0 +} + +define i1 @not_isinf_f(float %x) { +; CHECK-LABEL: not_isinf_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 955 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 507) ; ~0x204 = "~inf" + ret i1 %0 +} + +define i1 @is_plus_inf_f(float %x) { +; CHECK-LABEL: is_plus_inf_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 64 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 512) ; 0x200 = "+inf" + ret i1 %0 +} + +define i1 @is_minus_inf_f(float %x) { +; CHECK-LABEL: is_minus_inf_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 4 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 4) ; "-inf" + ret i1 %0 +} + +define i1 @not_is_minus_inf_f(float %x) { +; CHECK-LABEL: not_is_minus_inf_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 1019 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1019) ; ~"-inf" + ret i1 %0 +} + +define i1 @isfinite_f(float %x) { +; CHECK-LABEL: isfinite_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 952 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 504) ; 0x1f8 = "finite" + ret i1 %0 +} + +define i1 @not_isfinite_f(float %x) { +; CHECK-LABEL: not_isfinite_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 71 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 519) ; ~0x1f8 = "~finite" + ret i1 %0 +} + +define i1 @is_plus_finite_f(float %x) { +; CHECK-LABEL: is_plus_finite_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 896 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 448) ; 0x1c0 = "+finite" + ret i1 %0 +} + +define i1 @not_is_plus_finite_f(float %x) { +; CHECK-LABEL: not_is_plus_finite_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 127 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 575) ; ~0x1c0 = ~"+finite" + ret i1 %0 +} + +define i1 @is_minus_finite_f(float %x) { +; CHECK-LABEL: is_minus_finite_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 56 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 56) ; 0x38 = "-finite" + ret i1 %0 +} + +define i1 @not_is_minus_finite_f(float %x) { +; CHECK-LABEL: not_is_minus_finite_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 967 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 967) ; ~0x38 = ~"-finite" + ret i1 %0 +} + +define i1 @isnormal_f(float %x) { +; CHECK-LABEL: isnormal_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 136 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 264) ; 0x108 = "normal" + ret i1 %0 +} + +define i1 @not_isnormal_f(float %x) { +; CHECK-LABEL: not_isnormal_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 887 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 759) ; ~0x108 = "~normal" + ret i1 %0 +} + +define i1 @is_plus_normal_f(float %x) { +; CHECK-LABEL: is_plus_normal_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 128 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 256) ; 0x100 = "+normal" + ret i1 %0 +} + +define i1 @issubnormal_f(float %x) { +; CHECK-LABEL: issubnormal_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 272 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 144) ; 0x90 = "subnormal" + ret i1 %0 +} + +define i1 @not_issubnormal_f(float %x) { +; CHECK-LABEL: not_issubnormal_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 751 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 879) ; ~0x90 = "~subnormal" + ret i1 %0 +} + +define i1 @is_plus_subnormal_f(float %x) { +; CHECK-LABEL: is_plus_subnormal_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 256 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 128) ; 0x80 = "+subnormal" + ret i1 %0 +} + +define i1 @not_is_plus_subnormal_f(float %x) { +; CHECK-LABEL: not_is_plus_subnormal_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 767 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 895) ; ~0x80 = ~"+subnormal" + ret i1 %0 +} + +define i1 @is_minus_subnormal_f(float %x) { +; CHECK-LABEL: is_minus_subnormal_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 16 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 16) ; 0x10 = "-subnormal" + ret i1 %0 +} + +define i1 @not_is_minus_subnormal_f(float %x) { +; CHECK-LABEL: not_is_minus_subnormal_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 1007 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1007) ; ~0x10 = ~"-subnormal" + ret i1 %0 +} + +define i1 @iszero_f(float %x) { +; CHECK-LABEL: iszero_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 544 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 96) ; 0x60 = "zero" + ret i1 %0 +} + +define i1 @not_iszero_f(float %x) { +; CHECK-LABEL: not_iszero_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 479 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 927) ; ~0x60 = "~zero" + ret i1 %0 +} + +define i1 @issubnormal_or_zero_f(float %x) { +; CHECK-LABEL: issubnormal_or_zero_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 816 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 240) ; 0xf0 = "subnormal|zero" + ret i1 %0 +} + +define i1 @not_issubnormal_or_zero_f(float %x) { +; CHECK-LABEL: not_issubnormal_or_zero_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 207 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 783) ; ~0xf0 = "~(subnormal|zero)" + ret i1 %0 +} + +define i1 @is_plus_zero_f(float %x) { +; CHECK-LABEL: is_plus_zero_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 512 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 64) ; 0x40 = "+zero" + ret i1 %0 +} + +define i1 @not_is_plus_zero_f(float %x) { +; CHECK-LABEL: not_is_plus_zero_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 511 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 959) ; ~0x40 = ~"+zero" + ret i1 %0 +} + +define i1 @is_minus_zero_f(float %x) { +; CHECK-LABEL: is_minus_zero_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 32 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 32) ; 0x20 = "-zero" + ret i1 %0 +} + +define i1 @not_is_minus_zero_f(float %x) { +; CHECK-LABEL: not_is_minus_zero_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 991 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 991) ; ~0x20 = ~"-zero" + ret i1 %0 +} + +define i1 @isnone_f(float %x) { +; CHECK-LABEL: isnone_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 0 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 0) + ret i1 %0 +} + +define i1 @isany_f(float %x) { +; CHECK-LABEL: isany_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 1023 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1023) + ret i1 %0 +} + +define i1 @iszero_or_nan_f(float %x) { +; CHECK-LABEL: iszero_or_nan_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 547 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 99) ; 0x60|0x3 = "zero|nan" + ret i1 %0 +} + +define i1 @not_iszero_or_nan_f(float %x) { +; CHECK-LABEL: not_iszero_or_nan_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 476 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 924) ; ~0x60 = "~(zero|nan)" + ret i1 %0 +} + +define i1 @iszero_or_qnan_f(float %x) { +; CHECK-LABEL: iszero_or_qnan_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 546 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 98) ; 0x60|0x2 = "zero|qnan" + ret i1 %0 +} + +define i1 @iszero_or_snan_f(float %x) { +; CHECK-LABEL: iszero_or_snan_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 545 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 97) ; 0x60|0x1 = "zero|snan" + ret i1 %0 +} + +define i1 @not_iszero_or_qnan_f(float %x) { +; CHECK-LABEL: not_iszero_or_qnan_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 477 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 925) ; ~(0x60|0x2) = "~(zero|qnan)" + ret i1 %0 +} + +define i1 @not_iszero_or_snan_f(float %x) { +; CHECK-LABEL: not_iszero_or_snan_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 478 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 926) ; ~(0x60|0x1) = "~(zero|snan)" + ret i1 %0 +} + +define i1 @isinf_or_nan_f(float %x) { +; CHECK-LABEL: isinf_or_nan_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 71 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 519) ; 0x204|0x3 = "inf|nan" + ret i1 %0 +} + +define i1 @not_isinf_or_nan_f(float %x) { +; CHECK-LABEL: not_isinf_or_nan_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 952 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 504) ; ~(0x204|0x3) = "~(inf|nan)" + ret i1 %0 +} + +define i1 @isfinite_or_nan_f(float %x) { +; CHECK-LABEL: isfinite_or_nan_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 955 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 507) ; 0x1f8|0x3 = "finite|nan" + ret i1 %0 +} + +define i1 @not_isfinite_or_nan_f(float %x) { +; CHECK-LABEL: not_isfinite_or_nan_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 68 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 516) ; ~(0x1f8|0x3) = "~(finite|nan)" + ret i1 %0 +} + +define i1 @is_plus_inf_or_nan_f(float %x) { +; CHECK-LABEL: is_plus_inf_or_nan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 67 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 515) ; 0x200|0x3 = "+inf|nan" + ret i1 %class +} + +define i1 @is_minus_inf_or_nan_f(float %x) { +; CHECK-LABEL: is_minus_inf_or_nan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 7 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 7) ; "-inf|nan" + ret i1 %class +} + +define i1 @not_is_plus_inf_or_nan_f(float %x) { +; CHECK-LABEL: not_is_plus_inf_or_nan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 956 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 508) ; ~(0x200|0x3) = "~(+inf|nan)" + ret i1 %class +} + +define i1 @not_is_minus_inf_or_nan_f(float %x) { +; CHECK-LABEL: not_is_minus_inf_or_nan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 1016 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1016) ; "~(-inf|nan)" + ret i1 %class +} + +define i1 @is_plus_inf_or_snan_f(float %x) { +; CHECK-LABEL: is_plus_inf_or_snan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 65 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 513) ; 0x200|0x1 = "+inf|snan" + ret i1 %class +} + +define i1 @is_plus_inf_or_qnan_f(float %x) { +; CHECK-LABEL: is_plus_inf_or_qnan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 66 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 514) ; 0x200|0x1 = "+inf|qnan" + ret i1 %class +} + +define i1 @not_is_plus_inf_or_snan_f(float %x) { +; CHECK-LABEL: not_is_plus_inf_or_snan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 958 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 510) ; ~(+inf|snan) + ret i1 %class +} + +define i1 @not_is_plus_inf_or_qnan_f(float %x) { +; CHECK-LABEL: not_is_plus_inf_or_qnan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 957 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 509) ; ~(+inf|qnan) + ret i1 %class +} + +define i1 @is_minus_inf_or_snan_f(float %x) { +; CHECK-LABEL: is_minus_inf_or_snan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 5 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 5) ; "-inf|snan" + ret i1 %class +} + +define i1 @is_minus_inf_or_qnan_f(float %x) { +; CHECK-LABEL: is_minus_inf_or_qnan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 6 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 6) ; "-inf|qnan" + ret i1 %class +} + +define i1 @not_is_minus_inf_or_snan_f(float %x) { +; CHECK-LABEL: not_is_minus_inf_or_snan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 1018 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1018) ; "~(-inf|snan)" + ret i1 %class +} + +define i1 @not_is_minus_inf_or_qnan_f(float %x) { +; CHECK-LABEL: not_is_minus_inf_or_qnan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 1017 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1017) ; "-inf|qnan" + ret i1 %class +} + +define i1 @issubnormal_or_nan_f(float %x) { +; CHECK-LABEL: issubnormal_or_nan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 275 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 147) ; 0x90|0x3 = "subnormal|nan" + ret i1 %class +} + +define i1 @issubnormal_or_zero_or_nan_f(float %x) { +; CHECK-LABEL: issubnormal_or_zero_or_nan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 819 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 243) ; 0xf0|0x3 = "subnormal|zero|nan" + ret i1 %class +} + +define i1 @issubnormal_or_zero_or_snan_f(float %x) { +; CHECK-LABEL: issubnormal_or_zero_or_snan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 817 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 241) ; 0x90|0x1 = "subnormal|snan" + ret i1 %class +} + +define i1 @issubnormal_or_zero_or_qnan_f(float %x) { +; CHECK-LABEL: issubnormal_or_zero_or_qnan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 818 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 242) ; 0x90|0x2 = "subnormal|qnan" + ret i1 %class +} + +define i1 @not_issubnormal_or_nan_f(float %x) { +; CHECK-LABEL: not_issubnormal_or_nan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 748 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 876) ; ~(0x90|0x3) = ~"subnormal|nan" + ret i1 %class +} + +define i1 @not_issubnormal_or_zero_or_nan_f(float %x) { +; CHECK-LABEL: not_issubnormal_or_zero_or_nan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 204 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 780) ; ~(0xf0|0x3) = ~"subnormal|zero|nan" + ret i1 %class +} + +define i1 @not_issubnormal_or_zero_or_snan_f(float %x) { +; CHECK-LABEL: not_issubnormal_or_zero_or_snan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 206 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 782) ; ~(0x90|0x1) = ~"subnormal|snan" + ret i1 %class +} + +define i1 @not_issubnormal_or_zero_or_qnan_f(float %x) { +; CHECK-LABEL: not_issubnormal_or_zero_or_qnan_f: +; CHECK: # %bb.0: +; CHECK-NEXT: fclass.s $fa0, $fa0 +; CHECK-NEXT: movfr2gr.s $a0, $fa0 +; CHECK-NEXT: and $a0, $a0, 205 +; CHECK-NEXT: sltu $a0, $zero, $a0 +; CHECK-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 781) ; ~(0x90|0x2) = ~"subnormal|qnan" + ret i1 %class +} + +declare i1 @llvm.is.fpclass.f32(float, i32) diff --git a/llvm/test/CodeGen/LoongArch/is_fpclass_f64.ll b/llvm/test/CodeGen/LoongArch/is_fpclass_f64.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/LoongArch/is_fpclass_f64.ll @@ -0,0 +1,1371 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=CHECK32 +; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=CHECK64 + +define i1 @isnan_d(double %x) { +; CHECK32-LABEL: isnan_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 3 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: isnan_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 3 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 3) ; "nan" + ret i1 %0 +} + +define i1 @isnot_nan_d(double %x) { +; CHECK32-LABEL: isnot_nan_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 1020 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: isnot_nan_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 1020 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1020) ; 0x3fc = "zero|subnormal|normal|inf" + ret i1 %0 +} + +define i1 @issignaling_d(double %x) { +; CHECK32-LABEL: issignaling_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 1 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: issignaling_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 1 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1) ; "snan" + ret i1 %0 +} + +define i1 @not_issignaling_d(double %x) { +; CHECK32-LABEL: not_issignaling_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 1022 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_issignaling_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 1022 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1022) ; ~"snan" + ret i1 %0 +} + +define i1 @isquiet_d(double %x) { +; CHECK32-LABEL: isquiet_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 2 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: isquiet_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 2 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 2) ; "qnan" + ret i1 %0 +} + +define i1 @not_isquiet_d(double %x) { +; CHECK32-LABEL: not_isquiet_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 1021 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_isquiet_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 1021 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1021) ; ~"qnan" + ret i1 %0 +} + +define i1 @isinf_d(double %x) { +; CHECK32-LABEL: isinf_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 68 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: isinf_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 68 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 516) ; 0x204 = "inf" + ret i1 %0 +} + +define i1 @not_isinf_d(double %x) { +; CHECK32-LABEL: not_isinf_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 955 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_isinf_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 955 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 507) ; ~0x204 = "~inf" + ret i1 %0 +} + +define i1 @is_plus_inf_d(double %x) { +; CHECK32-LABEL: is_plus_inf_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 64 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: is_plus_inf_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 64 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 512) ; 0x200 = "+inf" + ret i1 %0 +} + +define i1 @is_minus_inf_d(double %x) { +; CHECK32-LABEL: is_minus_inf_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 4 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: is_minus_inf_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 4 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 4) ; "-inf" + ret i1 %0 +} + +define i1 @not_is_minus_inf_d(double %x) { +; CHECK32-LABEL: not_is_minus_inf_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 1019 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_is_minus_inf_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 1019 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1019) ; ~"-inf" + ret i1 %0 +} + +define i1 @isfinite_d(double %x) { +; CHECK32-LABEL: isfinite_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 952 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: isfinite_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 952 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 504) ; 0x1f8 = "finite" + ret i1 %0 +} + +define i1 @not_isfinite_d(double %x) { +; CHECK32-LABEL: not_isfinite_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 71 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_isfinite_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 71 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 519) ; ~0x1f8 = "~finite" + ret i1 %0 +} + +define i1 @is_plus_finite_d(double %x) { +; CHECK32-LABEL: is_plus_finite_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 896 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: is_plus_finite_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 896 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 448) ; 0x1c0 = "+finite" + ret i1 %0 +} + +define i1 @not_is_plus_finite_d(double %x) { +; CHECK32-LABEL: not_is_plus_finite_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 127 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_is_plus_finite_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 127 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 575) ; ~0x1c0 = ~"+finite" + ret i1 %0 +} + +define i1 @is_minus_finite_d(double %x) { +; CHECK32-LABEL: is_minus_finite_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 56 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: is_minus_finite_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 56 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 56) ; 0x38 = "-finite" + ret i1 %0 +} + +define i1 @not_is_minus_finite_d(double %x) { +; CHECK32-LABEL: not_is_minus_finite_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 967 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_is_minus_finite_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 967 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 967) ; ~0x38 = ~"-finite" + ret i1 %0 +} + +define i1 @isnormal_d(double %x) { +; CHECK32-LABEL: isnormal_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 136 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: isnormal_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 136 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 264) ; 0x108 = "normal" + ret i1 %0 +} + +define i1 @not_isnormal_d(double %x) { +; CHECK32-LABEL: not_isnormal_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 887 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_isnormal_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 887 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 759) ; ~0x108 = "~normal" + ret i1 %0 +} + +define i1 @is_plus_normal_d(double %x) { +; CHECK32-LABEL: is_plus_normal_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 128 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: is_plus_normal_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 128 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 256) ; 0x100 = "+normal" + ret i1 %0 +} + +define i1 @issubnormal_d(double %x) { +; CHECK32-LABEL: issubnormal_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 272 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: issubnormal_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 272 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 144) ; 0x90 = "subnormal" + ret i1 %0 +} + +define i1 @not_issubnormal_d(double %x) { +; CHECK32-LABEL: not_issubnormal_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 751 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_issubnormal_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 751 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 879) ; ~0x90 = "~subnormal" + ret i1 %0 +} + +define i1 @is_plus_subnormal_d(double %x) { +; CHECK32-LABEL: is_plus_subnormal_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 256 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: is_plus_subnormal_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 256 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 128) ; 0x80 = "+subnormal" + ret i1 %0 +} + +define i1 @not_is_plus_subnormal_d(double %x) { +; CHECK32-LABEL: not_is_plus_subnormal_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 767 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_is_plus_subnormal_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 767 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 895) ; ~0x80 = ~"+subnormal" + ret i1 %0 +} + +define i1 @is_minus_subnormal_d(double %x) { +; CHECK32-LABEL: is_minus_subnormal_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 16 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: is_minus_subnormal_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 16 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 16) ; 0x10 = "-subnormal" + ret i1 %0 +} + +define i1 @not_is_minus_subnormal_d(double %x) { +; CHECK32-LABEL: not_is_minus_subnormal_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 1007 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_is_minus_subnormal_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 1007 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1007) ; ~0x10 = ~"-subnormal" + ret i1 %0 +} + +define i1 @iszero_d(double %x) { +; CHECK32-LABEL: iszero_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 544 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: iszero_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 544 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 96) ; 0x60 = "zero" + ret i1 %0 +} + +define i1 @not_iszero_d(double %x) { +; CHECK32-LABEL: not_iszero_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 479 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_iszero_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 479 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 927) ; ~0x60 = "~zero" + ret i1 %0 +} + +define i1 @issubnormal_or_zero_d(double %x) { +; CHECK32-LABEL: issubnormal_or_zero_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 816 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: issubnormal_or_zero_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 816 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 240) ; 0xf0 = "subnormal|zero" + ret i1 %0 +} + +define i1 @not_issubnormal_or_zero_d(double %x) { +; CHECK32-LABEL: not_issubnormal_or_zero_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 207 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_issubnormal_or_zero_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 207 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 783) ; ~0xf0 = "~(subnormal|zero)" + ret i1 %0 +} + +define i1 @is_plus_zero_d(double %x) { +; CHECK32-LABEL: is_plus_zero_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 512 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: is_plus_zero_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 512 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 64) ; 0x40 = "+zero" + ret i1 %0 +} + +define i1 @not_is_plus_zero_d(double %x) { +; CHECK32-LABEL: not_is_plus_zero_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 511 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_is_plus_zero_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 511 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 959) ; ~0x40 = ~"+zero" + ret i1 %0 +} + +define i1 @is_minus_zero_d(double %x) { +; CHECK32-LABEL: is_minus_zero_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 32 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: is_minus_zero_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 32 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 32) ; 0x20 = "-zero" + ret i1 %0 +} + +define i1 @not_is_minus_zero_d(double %x) { +; CHECK32-LABEL: not_is_minus_zero_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 991 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_is_minus_zero_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 991 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 991) ; ~0x20 = ~"-zero" + ret i1 %0 +} + +define i1 @isnone_d(double %x) { +; CHECK32-LABEL: isnone_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 0 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: isnone_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 0 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 0) + ret i1 %0 +} + +define i1 @isany_d(double %x) { +; CHECK32-LABEL: isany_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 1023 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: isany_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 1023 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1023) + ret i1 %0 +} + +define i1 @iszero_or_nan_d(double %x) { +; CHECK32-LABEL: iszero_or_nan_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 547 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: iszero_or_nan_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 547 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 99) ; 0x60|0x3 = "zero|nan" + ret i1 %0 +} + +define i1 @not_iszero_or_nan_d(double %x) { +; CHECK32-LABEL: not_iszero_or_nan_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 476 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_iszero_or_nan_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 476 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 924) ; ~0x60 = "~(zero|nan)" + ret i1 %0 +} + +define i1 @iszero_or_qnan_d(double %x) { +; CHECK32-LABEL: iszero_or_qnan_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 546 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: iszero_or_qnan_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 546 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 98) ; 0x60|0x2 = "zero|qnan" + ret i1 %0 +} + +define i1 @iszero_or_snan_d(double %x) { +; CHECK32-LABEL: iszero_or_snan_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 545 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: iszero_or_snan_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 545 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 97) ; 0x60|0x1 = "zero|snan" + ret i1 %0 +} + +define i1 @not_iszero_or_qnan_d(double %x) { +; CHECK32-LABEL: not_iszero_or_qnan_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 477 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_iszero_or_qnan_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 477 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 925) ; ~(0x60|0x2) = "~(zero|qnan)" + ret i1 %0 +} + +define i1 @not_iszero_or_snan_d(double %x) { +; CHECK32-LABEL: not_iszero_or_snan_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 478 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_iszero_or_snan_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 478 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 926) ; ~(0x60|0x1) = "~(zero|snan)" + ret i1 %0 +} + +define i1 @isinf_or_nan_d(double %x) { +; CHECK32-LABEL: isinf_or_nan_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 71 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: isinf_or_nan_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 71 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 519) ; 0x204|0x3 = "inf|nan" + ret i1 %0 +} + +define i1 @not_isinf_or_nan_d(double %x) { +; CHECK32-LABEL: not_isinf_or_nan_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 952 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_isinf_or_nan_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 952 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 504) ; ~(0x204|0x3) = "~(inf|nan)" + ret i1 %0 +} + +define i1 @isfinite_or_nan_d(double %x) { +; CHECK32-LABEL: isfinite_or_nan_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 955 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: isfinite_or_nan_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 955 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 507) ; 0x1f8|0x3 = "finite|nan" + ret i1 %0 +} + +define i1 @not_isfinite_or_nan_d(double %x) { +; CHECK32-LABEL: not_isfinite_or_nan_d: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 68 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_isfinite_or_nan_d: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 68 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret +entry: + %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 516) ; ~(0x1f8|0x3) = "~(finite|nan)" + ret i1 %0 +} + +define i1 @is_plus_inf_or_nan_d(double %x) { +; CHECK32-LABEL: is_plus_inf_or_nan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 67 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: is_plus_inf_or_nan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 67 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 515) ; 0x200|0x3 = "+inf|nan" + ret i1 %class +} + +define i1 @is_minus_inf_or_nan_d(double %x) { +; CHECK32-LABEL: is_minus_inf_or_nan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 7 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: is_minus_inf_or_nan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 7 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 7) ; "-inf|nan" + ret i1 %class +} + +define i1 @not_is_plus_inf_or_nan_d(double %x) { +; CHECK32-LABEL: not_is_plus_inf_or_nan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 956 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_is_plus_inf_or_nan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 956 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 508) ; ~(0x200|0x3) = "~(+inf|nan)" + ret i1 %class +} + +define i1 @not_is_minus_inf_or_nan_d(double %x) { +; CHECK32-LABEL: not_is_minus_inf_or_nan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 1016 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_is_minus_inf_or_nan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 1016 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1016) ; "~(-inf|nan)" + ret i1 %class +} + +define i1 @is_plus_inf_or_snan_d(double %x) { +; CHECK32-LABEL: is_plus_inf_or_snan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 65 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: is_plus_inf_or_snan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 65 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 513) ; 0x200|0x1 = "+inf|snan" + ret i1 %class +} + +define i1 @is_plus_inf_or_qnan_d(double %x) { +; CHECK32-LABEL: is_plus_inf_or_qnan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 66 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: is_plus_inf_or_qnan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 66 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 514) ; 0x200|0x1 = "+inf|qnan" + ret i1 %class +} + +define i1 @not_is_plus_inf_or_snan_d(double %x) { +; CHECK32-LABEL: not_is_plus_inf_or_snan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 958 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_is_plus_inf_or_snan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 958 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 510) ; ~(+inf|snan) + ret i1 %class +} + +define i1 @not_is_plus_inf_or_qnan_d(double %x) { +; CHECK32-LABEL: not_is_plus_inf_or_qnan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 957 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_is_plus_inf_or_qnan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 957 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 509) ; ~(+inf|qnan) + ret i1 %class +} + +define i1 @is_minus_inf_or_snan_d(double %x) { +; CHECK32-LABEL: is_minus_inf_or_snan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 5 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: is_minus_inf_or_snan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 5 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 5) ; "-inf|snan" + ret i1 %class +} + +define i1 @is_minus_inf_or_qnan_d(double %x) { +; CHECK32-LABEL: is_minus_inf_or_qnan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 6 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: is_minus_inf_or_qnan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 6 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 6) ; "-inf|qnan" + ret i1 %class +} + +define i1 @not_is_minus_inf_or_snan_d(double %x) { +; CHECK32-LABEL: not_is_minus_inf_or_snan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 1018 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_is_minus_inf_or_snan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 1018 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1018) ; "~(-inf|snan)" + ret i1 %class +} + +define i1 @not_is_minus_inf_or_qnan_d(double %x) { +; CHECK32-LABEL: not_is_minus_inf_or_qnan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 1017 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_is_minus_inf_or_qnan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 1017 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1017) ; "-inf|qnan" + ret i1 %class +} + +define i1 @issubnormal_or_nan_d(double %x) { +; CHECK32-LABEL: issubnormal_or_nan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 275 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: issubnormal_or_nan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 275 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 147) ; 0x90|0x3 = "subnormal|nan" + ret i1 %class +} + +define i1 @issubnormal_or_zero_or_nan_d(double %x) { +; CHECK32-LABEL: issubnormal_or_zero_or_nan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 819 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: issubnormal_or_zero_or_nan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 819 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 243) ; 0xf0|0x3 = "subnormal|zero|nan" + ret i1 %class +} + +define i1 @issubnormal_or_zero_or_snan_d(double %x) { +; CHECK32-LABEL: issubnormal_or_zero_or_snan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 817 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: issubnormal_or_zero_or_snan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 817 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 241) ; 0x90|0x1 = "subnormal|snan" + ret i1 %class +} + +define i1 @issubnormal_or_zero_or_qnan_d(double %x) { +; CHECK32-LABEL: issubnormal_or_zero_or_qnan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 818 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: issubnormal_or_zero_or_qnan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 818 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 242) ; 0x90|0x2 = "subnormal|qnan" + ret i1 %class +} + +define i1 @not_issubnormal_or_nan_d(double %x) { +; CHECK32-LABEL: not_issubnormal_or_nan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 748 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_issubnormal_or_nan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 748 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 876) ; ~(0x90|0x3) = ~"subnormal|nan" + ret i1 %class +} + +define i1 @not_issubnormal_or_zero_or_nan_d(double %x) { +; CHECK32-LABEL: not_issubnormal_or_zero_or_nan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 204 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_issubnormal_or_zero_or_nan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 204 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 780) ; ~(0xf0|0x3) = ~"subnormal|zero|nan" + ret i1 %class +} + +define i1 @not_issubnormal_or_zero_or_snan_d(double %x) { +; CHECK32-LABEL: not_issubnormal_or_zero_or_snan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 206 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_issubnormal_or_zero_or_snan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 206 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 782) ; ~(0x90|0x1) = ~"subnormal|snan" + ret i1 %class +} + +define i1 @not_issubnormal_or_zero_or_qnan_d(double %x) { +; CHECK32-LABEL: not_issubnormal_or_zero_or_qnan_d: +; CHECK32: # %bb.0: +; CHECK32-NEXT: fclass.d $fa0, $fa0 +; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +; CHECK32-NEXT: and $a0, $a0, 205 +; CHECK32-NEXT: sltu $a0, $zero, $a0 +; CHECK32-NEXT: ret +; +; CHECK64-LABEL: not_issubnormal_or_zero_or_qnan_d: +; CHECK64: # %bb.0: +; CHECK64-NEXT: fclass.d $fa0, $fa0 +; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +; CHECK64-NEXT: and $a0, $a0, 205 +; CHECK64-NEXT: sltu $a0, $zero, $a0 +; CHECK64-NEXT: ret + %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 781) ; ~(0x90|0x2) = ~"subnormal|qnan" + ret i1 %class +} + +declare i1 @llvm.is.fpclass.f64(double, i32)