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_valid_timm 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_valid_timm 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_valid_timm 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.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -553,6 +553,11 @@ return CurDAG->getTargetConstant(MaskIdx, SDLoc(N), N->getValueType(0)); }]>; +def to_valid_timm : SDNodeXForm(N); + return CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(N), Subtarget->getGRLenVT()); +}]>; + //===----------------------------------------------------------------------===// // Instruction Formats //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td --- a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td @@ -145,11 +145,6 @@ def lsxsplati64 : PatFrag<(ops node:$e0), (v2i64 (build_vector node:$e0, node:$e0))>; -def to_valid_timm : SDNodeXForm(N); - return CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(N), Subtarget->getGRLenVT()); -}]>; - //===----------------------------------------------------------------------===// // Instruction class templates //===----------------------------------------------------------------------===// 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, 516 +; 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, 507 +; 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, 512 +; 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, 504 +; 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, 519 +; 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, 448 +; 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, 575 +; 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, 264 +; 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, 759 +; 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, 256 +; 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, 144 +; 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, 879 +; 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, 128 +; 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, 895 +; 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, 96 +; 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, 927 +; 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, 240 +; 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, 783 +; 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, 64 +; 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, 959 +; 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, 99 +; 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, 924 +; 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, 98 +; 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, 97 +; 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, 925 +; 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, 926 +; 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, 519 +; 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, 504 +; 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, 507 +; 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, 516 +; 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, 515 +; 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, 508 +; 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, 513 +; 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, 514 +; 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, 510 +; 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, 509 +; 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, 147 +; 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, 243 +; 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, 241 +; 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, 242 +; 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, 876 +; 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, 780 +; 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, 782 +; 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, 781 +; 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, 516 +; 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, 516 +; 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, 507 +; 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, 507 +; 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, 512 +; 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, 512 +; 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, 504 +; 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, 504 +; 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, 519 +; 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, 519 +; 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, 448 +; 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, 448 +; 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, 575 +; 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, 575 +; 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, 264 +; 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, 264 +; 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, 759 +; 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, 759 +; 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, 256 +; 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, 256 +; 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, 144 +; 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, 144 +; 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, 879 +; 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, 879 +; 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, 128 +; 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, 128 +; 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, 895 +; 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, 895 +; 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, 96 +; 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, 96 +; 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, 927 +; 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, 927 +; 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, 240 +; 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, 240 +; 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, 783 +; 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, 783 +; 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, 64 +; 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, 64 +; 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, 959 +; 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, 959 +; 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, 99 +; 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, 99 +; 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, 924 +; 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, 924 +; 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, 98 +; 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, 98 +; 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, 97 +; 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, 97 +; 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, 925 +; 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, 925 +; 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, 926 +; 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, 926 +; 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, 519 +; 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, 519 +; 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, 504 +; 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, 504 +; 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, 507 +; 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, 507 +; 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, 516 +; 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, 516 +; 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, 515 +; 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, 515 +; 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, 508 +; 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, 508 +; 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, 513 +; 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, 513 +; 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, 514 +; 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, 514 +; 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, 510 +; 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, 510 +; 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, 509 +; 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, 509 +; 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, 147 +; 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, 147 +; 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, 243 +; 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, 243 +; 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, 241 +; 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, 241 +; 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, 242 +; 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, 242 +; 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, 876 +; 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, 876 +; 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, 780 +; 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, 780 +; 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, 782 +; 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, 782 +; 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, 781 +; 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, 781 +; 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)