https://github.com/QuantumSegfault updated https://github.com/llvm/llvm-project/pull/197258
>From aa6a24a9c9cf85b10c2bfd99ef337198a63d1c45 Mon Sep 17 00:00:00 2001 From: Demetrius Kanios <[email protected]> Date: Tue, 12 May 2026 00:42:59 -0700 Subject: [PATCH] Implement floating-point comparisons --- .../GISel/WebAssemblyLegalizerInfo.cpp | 308 +++++++++++ .../GlobalISel/instructions/fcmp.ll | 436 ++++++++++++++++ .../GlobalISel/instructions/fmaximum.ll | 32 ++ .../GlobalISel/instructions/fmaximumnum.ll | 219 ++++++++ .../GlobalISel/instructions/fmaxnum.ll | 55 ++ .../GlobalISel/instructions/fminimum.ll | 32 ++ .../GlobalISel/instructions/fminimumnum.ll | 225 ++++++++ .../GlobalISel/instructions/fminnum.ll | 55 ++ .../GlobalISel/instructions/is_fpclass.ll | 490 ++++++++++++++++++ 9 files changed, 1852 insertions(+) create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fcmp.ll create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fmaximum.ll create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fmaximumnum.ll create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fmaxnum.ll create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fminimum.ll create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fminimumnum.ll create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fminnum.ll create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/is_fpclass.ll diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp index d91ec459397ba..045c939383cf4 100644 --- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp +++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp @@ -103,6 +103,23 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo( .minScalar(0, s32) .scalarSameSizeAs(1, 0); + getActionDefinitionsBuilder(G_FCMP) + .customForCartesianProduct({i32}, {f32, f64}) + .clampScalar(0, s32, s32); + + getActionDefinitionsBuilder({G_FMINIMUM, G_FMAXIMUM}) + .legalFor({f32, f64}) + .minScalar(0, s32); + + getActionDefinitionsBuilder( + {G_FMINNUM, G_FMAXNUM, G_FMINIMUMNUM, G_FMAXIMUMNUM}) + .customFor({f32, f64}) + .minScalar(0, s32); + + getActionDefinitionsBuilder(G_IS_FPCLASS) + .lowerForCartesianProduct({i32}, {f32, f64}) + .clampScalar(0, s32, s32); + getActionDefinitionsBuilder(G_FPEXT) .legalFor({{f64, f32}}) .clampScalar(0, s64, s64) @@ -153,6 +170,11 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo( bool WebAssemblyLegalizerInfo::legalizeCustom( LegalizerHelper &Helper, MachineInstr &MI, LostDebugLocObserver &LocObserver) const { + MachineRegisterInfo &MRI = *Helper.MIRBuilder.getMRI(); + auto &MIRBuilder = Helper.MIRBuilder; + + const LLT i1 = LLT::integer(1); + switch (MI.getOpcode()) { case TargetOpcode::G_SEXT_INREG: { assert(MI.getOperand(2).isImm() && "Expected immediate"); @@ -168,6 +190,292 @@ bool WebAssemblyLegalizerInfo::legalizeCustom( return Helper.lower(MI, 0, DstType) != LegalizerHelper::UnableToLegalize; } + case TargetOpcode::G_FCMP: { + Register LHS = MI.getOperand(2).getReg(); + Register RHS = MI.getOperand(3).getReg(); + CmpInst::Predicate Pred = + static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()); + + Register Result = MI.getOperand(0).getReg(); + + switch (Pred) { + case CmpInst::FCMP_FALSE: + MIRBuilder.buildBoolExt(Result, MIRBuilder.buildConstant(i1, 0), false); + break; + case CmpInst::FCMP_OEQ: + return true; + case CmpInst::FCMP_OGT: + return true; + case CmpInst::FCMP_OGE: + return true; + case CmpInst::FCMP_OLT: + return true; + case CmpInst::FCMP_OLE: + return true; + case CmpInst::FCMP_ONE: { + MIRBuilder.buildBoolExt( + Result, + MIRBuilder.buildOr( + i1, + MIRBuilder.buildFCmp(CmpInst::FCMP_OLT, i1, LHS, RHS).getReg(0), + MIRBuilder.buildFCmp(CmpInst::FCMP_OGT, i1, LHS, RHS).getReg(0)), + false); + break; + } + case CmpInst::FCMP_ORD: { + MIRBuilder.buildBoolExt( + Result, + MIRBuilder.buildAnd( + i1, + MIRBuilder.buildFCmp(CmpInst::FCMP_OEQ, i1, RHS, RHS).getReg(0), + MIRBuilder.buildFCmp(CmpInst::FCMP_OEQ, i1, LHS, LHS).getReg(0)), + false); + break; + } + case CmpInst::FCMP_UNO: { + MIRBuilder.buildBoolExt( + Result, + MIRBuilder.buildOr( + i1, + MIRBuilder.buildFCmp(CmpInst::FCMP_UNE, i1, RHS, RHS).getReg(0), + MIRBuilder.buildFCmp(CmpInst::FCMP_UNE, i1, LHS, LHS).getReg(0)), + false); + break; + } + case CmpInst::FCMP_UEQ: { + MIRBuilder.buildBoolExt( + Result, + MIRBuilder.buildNot( + i1, + MIRBuilder.buildFCmp(CmpInst::FCMP_ONE, i1, LHS, RHS).getReg(0)), + false); + break; + } + case CmpInst::FCMP_UGT: { + MIRBuilder.buildBoolExt( + Result, + MIRBuilder.buildNot( + i1, + MIRBuilder.buildFCmp(CmpInst::FCMP_OLE, i1, LHS, RHS).getReg(0)), + false); + break; + } + case CmpInst::FCMP_UGE: { + MIRBuilder.buildBoolExt( + Result, + MIRBuilder.buildNot( + i1, + MIRBuilder.buildFCmp(CmpInst::FCMP_OLT, i1, LHS, RHS).getReg(0)), + false); + break; + } + case CmpInst::FCMP_ULT: { + MIRBuilder.buildBoolExt( + Result, + MIRBuilder.buildNot( + i1, + MIRBuilder.buildFCmp(CmpInst::FCMP_OGE, i1, LHS, RHS).getReg(0)), + false); + break; + } + case CmpInst::FCMP_ULE: { + MIRBuilder.buildBoolExt( + Result, + MIRBuilder.buildNot( + i1, + MIRBuilder.buildFCmp(CmpInst::FCMP_OGT, i1, LHS, RHS).getReg(0)), + false); + break; + } + case CmpInst::FCMP_UNE: + return true; + case CmpInst::FCMP_TRUE: + MIRBuilder.buildBoolExt(Result, MIRBuilder.buildConstant(i1, 1), false); + break; + default: + llvm_unreachable("Unknown FCMP predicate"); + } + + MI.eraseFromParent(); + + return true; + } + case TargetOpcode::G_FMINNUM: { + // We can only use G_FMINIMUM if we can be sure no NaN is present. + // This is because G_FMINIMUM propogates NaN, while G_FMINNUM says that + // the non-NaN operand must result. + if (!MI.getFlag(MachineInstr::MIFlag::FmNoNans)) + return Helper.libcall(MI, LocObserver) != + LegalizerHelper::UnableToLegalize; + + // this respects minnum signed zero handling. G_FMINNUM has undefined zeros + // handling, so G_FMINIMUM's specific choice of zero is irrelavent. + MIRBuilder.buildInstr(TargetOpcode::G_FMINIMUM) + .addDef(MI.getOperand(0).getReg()) + .addUse(MI.getOperand(1).getReg()) + .addUse(MI.getOperand(2).getReg()) + .setMIFlags(MI.getFlags()); + + MI.eraseFromParent(); + return true; + } + case TargetOpcode::G_FMAXNUM: { + // We can only use G_FMAXIMUM if we can be sure no NaN is present. + // This is because G_FMAXIMUM propogates NaN, while G_MAXNUM says that + // the non-NaN operand must result. + if (!MI.getFlag(MachineInstr::MIFlag::FmNoNans)) + return Helper.libcall(MI, LocObserver) != + LegalizerHelper::UnableToLegalize; + + // this respects maxnum signed zero handling. G_FMAXNUM has undefined zeros + // handling, so G_FMAXIMUM's specific choice of zero is irrelavent. + MIRBuilder.buildInstr(TargetOpcode::G_FMAXIMUM) + .addDef(MI.getOperand(0).getReg()) + .addUse(MI.getOperand(1).getReg()) + .addUse(MI.getOperand(2).getReg()) + .setMIFlags(MI.getFlags()); + + MI.eraseFromParent(); + return true; + } + case WebAssembly::G_FMINIMUMNUM: { + // This is a stripped down version of fminimumnum handling for SelectionDAG + // TargetLowering + Register Result = MI.getOperand(0).getReg(); + LLT ResultTy = MRI.getType(Result); + + if (MI.getFlag(MachineInstr::MIFlag::FmNoNans)) { + MIRBuilder.buildInstr(TargetOpcode::G_FMINIMUM) + .addDef(MI.getOperand(0).getReg()) + .addUse(MI.getOperand(1).getReg()) + .addUse(MI.getOperand(2).getReg()) + .setMIFlags(MI.getFlags()); + } else { + Register LHS = MI.getOperand(1).getReg(); + Register RHS = MI.getOperand(2).getReg(); + + LHS = MIRBuilder + .buildSelect(ResultTy, + MIRBuilder.buildFCmp(CmpInst::Predicate::FCMP_UNO, + i1, LHS, LHS), + RHS, LHS) + ->getOperand(0) + .getReg(); + RHS = MIRBuilder + .buildSelect(ResultTy, + MIRBuilder.buildFCmp(CmpInst::Predicate::FCMP_UNO, + i1, RHS, RHS), + LHS, RHS) + ->getOperand(0) + .getReg(); + + if (MI.getFlag(MachineInstr::MIFlag::FmNsz)) { + MIRBuilder.buildSelect( + Result, + MIRBuilder.buildFCmp(CmpInst::Predicate::FCMP_OLT, i1, LHS, RHS), + LHS, RHS); + } else { + Register MinMax = + MIRBuilder + .buildSelect(ResultTy, + MIRBuilder.buildFCmp(CmpInst::Predicate::FCMP_OLT, + i1, LHS, RHS), + LHS, RHS) + ->getOperand(0) + .getReg(); + + Register IsZero = + MIRBuilder + .buildFCmp(CmpInst::Predicate::FCMP_OEQ, i1, MinMax, + MIRBuilder.buildFConstant(ResultTy, 0.0)) + ->getOperand(0) + .getReg(); + + Register RetZero = + MIRBuilder + .buildSelect(ResultTy, + MIRBuilder.buildIsFPClass(i1, LHS, fcNegZero), LHS, + MinMax) + .setMIFlags(MI.getFlags()) + ->getOperand(0) + .getReg(); + MIRBuilder.buildSelect(Result, IsZero, RetZero, MinMax) + .setMIFlags(MI.getFlags()); + } + } + + MI.eraseFromParent(); + return true; + } + case WebAssembly::G_FMAXIMUMNUM: { + // This is a stripped down version of fmaximumnum handling for SelectionDAG + // TargetLowering + Register Result = MI.getOperand(0).getReg(); + LLT ResultTy = MRI.getType(Result); + + if (MI.getFlag(MachineInstr::MIFlag::FmNoNans)) { + MIRBuilder.buildInstr(TargetOpcode::G_FMINIMUM) + .addDef(MI.getOperand(0).getReg()) + .addUse(MI.getOperand(1).getReg()) + .addUse(MI.getOperand(2).getReg()) + .setMIFlags(MI.getFlags()); + } else { + Register LHS = MI.getOperand(1).getReg(); + Register RHS = MI.getOperand(2).getReg(); + + LHS = MIRBuilder + .buildSelect(ResultTy, + MIRBuilder.buildFCmp(CmpInst::Predicate::FCMP_UNO, + i1, LHS, LHS), + RHS, LHS) + ->getOperand(0) + .getReg(); + RHS = MIRBuilder + .buildSelect(ResultTy, + MIRBuilder.buildFCmp(CmpInst::Predicate::FCMP_UNO, + i1, RHS, RHS), + LHS, RHS) + ->getOperand(0) + .getReg(); + + if (MI.getFlag(MachineInstr::MIFlag::FmNsz)) { + MIRBuilder.buildSelect( + Result, + MIRBuilder.buildFCmp(CmpInst::Predicate::FCMP_OGT, i1, LHS, RHS), + LHS, RHS); + } else { + Register MinMax = + MIRBuilder + .buildSelect(ResultTy, + MIRBuilder.buildFCmp(CmpInst::Predicate::FCMP_OGT, + i1, LHS, RHS), + LHS, RHS) + ->getOperand(0) + .getReg(); + + Register IsZero = + MIRBuilder + .buildFCmp(CmpInst::Predicate::FCMP_OEQ, i1, MinMax, + MIRBuilder.buildFConstant(ResultTy, 0.0)) + ->getOperand(0) + .getReg(); + + Register RetZero = + MIRBuilder + .buildSelect(ResultTy, + MIRBuilder.buildIsFPClass(i1, LHS, fcPosZero), LHS, + MinMax) + .setMIFlags(MI.getFlags()) + ->getOperand(0) + .getReg(); + MIRBuilder.buildSelect(Result, IsZero, RetZero, MinMax) + .setMIFlags(MI.getFlags()); + } + } + + MI.eraseFromParent(); + return true; + } default: break; } diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fcmp.ll b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fcmp.ll new file mode 100644 index 0000000000000..e92e523e44cd3 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fcmp.ll @@ -0,0 +1,436 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc < %s -O0 --global-isel -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s + +target triple = "wasm32-unknown-unknown" + +define i1 @fcmp_false_f32(float %x, float %y) { +; CHECK-LABEL: fcmp_false_f32: +; CHECK: .functype fcmp_false_f32 (f32, f32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: i32.const $push0=, 0 +; CHECK-NEXT: return $pop0 + %a = fcmp false float %x, %y + ret i1 %a +} + +define i1 @fcmp_oeq_f32(float %x, float %y) { +; CHECK-LABEL: fcmp_oeq_f32: +; CHECK: .functype fcmp_oeq_f32 (f32, f32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f32.eq $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp oeq float %x, %y + ret i1 %a +} + +define i1 @fcmp_ogt_f32(float %x, float %y) { +; CHECK-LABEL: fcmp_ogt_f32: +; CHECK: .functype fcmp_ogt_f32 (f32, f32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f32.gt $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp ogt float %x, %y + ret i1 %a +} + +define i1 @fcmp_oge_f32(float %x, float %y) { +; CHECK-LABEL: fcmp_oge_f32: +; CHECK: .functype fcmp_oge_f32 (f32, f32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f32.ge $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp oge float %x, %y + ret i1 %a +} + +define i1 @fcmp_olt_f32(float %x, float %y) { +; CHECK-LABEL: fcmp_olt_f32: +; CHECK: .functype fcmp_olt_f32 (f32, f32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f32.lt $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp olt float %x, %y + ret i1 %a +} + +define i1 @fcmp_ole_f32(float %x, float %y) { +; CHECK-LABEL: fcmp_ole_f32: +; CHECK: .functype fcmp_ole_f32 (f32, f32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f32.le $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp ole float %x, %y + ret i1 %a +} + +define i1 @fcmp_one_f32(float %x, float %y) { +; CHECK-LABEL: fcmp_one_f32: +; CHECK: .functype fcmp_one_f32 (f32, f32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 0 +; CHECK-NEXT: local.get $push3=, 1 +; CHECK-NEXT: f32.lt $push2=, $pop4, $pop3 +; CHECK-NEXT: local.get $push6=, 0 +; CHECK-NEXT: local.get $push5=, 1 +; CHECK-NEXT: f32.gt $push1=, $pop6, $pop5 +; CHECK-NEXT: i32.or $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp one float %x, %y + ret i1 %a +} + +define i1 @fcmp_ord_f32(float %x, float %y) { +; CHECK-LABEL: fcmp_ord_f32: +; CHECK: .functype fcmp_ord_f32 (f32, f32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 1 +; CHECK-NEXT: local.get $push3=, 1 +; CHECK-NEXT: f32.eq $push2=, $pop4, $pop3 +; CHECK-NEXT: local.get $push6=, 0 +; CHECK-NEXT: local.get $push5=, 0 +; CHECK-NEXT: f32.eq $push1=, $pop6, $pop5 +; CHECK-NEXT: i32.and $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp ord float %x, %y + ret i1 %a +} + +define i1 @fcmp_ueq_f32(float %x, float %y) { +; CHECK-LABEL: fcmp_ueq_f32: +; CHECK: .functype fcmp_ueq_f32 (f32, f32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push8=, 0 +; CHECK-NEXT: local.get $push7=, 1 +; CHECK-NEXT: f32.lt $push5=, $pop8, $pop7 +; CHECK-NEXT: local.get $push10=, 0 +; CHECK-NEXT: local.get $push9=, 1 +; CHECK-NEXT: f32.gt $push4=, $pop10, $pop9 +; CHECK-NEXT: i32.or $push3=, $pop5, $pop4 +; CHECK-NEXT: i32.const $push2=, 1 +; CHECK-NEXT: i32.xor $push1=, $pop3, $pop2 +; CHECK-NEXT: i32.const $push6=, 1 +; CHECK-NEXT: i32.and $push0=, $pop1, $pop6 +; CHECK-NEXT: return $pop0 + %a = fcmp ueq float %x, %y + ret i1 %a +} + +define i1 @fcmp_ugt_f32(float %x, float %y) { +; CHECK-LABEL: fcmp_ugt_f32: +; CHECK: .functype fcmp_ugt_f32 (f32, f32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 0 +; CHECK-NEXT: local.get $push3=, 1 +; CHECK-NEXT: f32.le $push2=, $pop4, $pop3 +; CHECK-NEXT: i32.const $push1=, 1 +; CHECK-NEXT: i32.xor $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp ugt float %x, %y + ret i1 %a +} + +define i1 @fcmp_uge_f32(float %x, float %y) { +; CHECK-LABEL: fcmp_uge_f32: +; CHECK: .functype fcmp_uge_f32 (f32, f32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 0 +; CHECK-NEXT: local.get $push3=, 1 +; CHECK-NEXT: f32.lt $push2=, $pop4, $pop3 +; CHECK-NEXT: i32.const $push1=, 1 +; CHECK-NEXT: i32.xor $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp uge float %x, %y + ret i1 %a +} + +define i1 @fcmp_ult_f32(float %x, float %y) { +; CHECK-LABEL: fcmp_ult_f32: +; CHECK: .functype fcmp_ult_f32 (f32, f32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 0 +; CHECK-NEXT: local.get $push3=, 1 +; CHECK-NEXT: f32.ge $push2=, $pop4, $pop3 +; CHECK-NEXT: i32.const $push1=, 1 +; CHECK-NEXT: i32.xor $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp ult float %x, %y + ret i1 %a +} + +define i1 @fcmp_ule_f32(float %x, float %y) { +; CHECK-LABEL: fcmp_ule_f32: +; CHECK: .functype fcmp_ule_f32 (f32, f32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 0 +; CHECK-NEXT: local.get $push3=, 1 +; CHECK-NEXT: f32.gt $push2=, $pop4, $pop3 +; CHECK-NEXT: i32.const $push1=, 1 +; CHECK-NEXT: i32.xor $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp ule float %x, %y + ret i1 %a +} + +define i1 @fcmp_une_f32(float %x, float %y) { +; CHECK-LABEL: fcmp_une_f32: +; CHECK: .functype fcmp_une_f32 (f32, f32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f32.ne $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp une float %x, %y + ret i1 %a +} + +define i1 @fcmp_uno_f32(float %x, float %y) { +; CHECK-LABEL: fcmp_uno_f32: +; CHECK: .functype fcmp_uno_f32 (f32, f32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 1 +; CHECK-NEXT: local.get $push3=, 1 +; CHECK-NEXT: f32.ne $push2=, $pop4, $pop3 +; CHECK-NEXT: local.get $push6=, 0 +; CHECK-NEXT: local.get $push5=, 0 +; CHECK-NEXT: f32.ne $push1=, $pop6, $pop5 +; CHECK-NEXT: i32.or $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp uno float %x, %y + ret i1 %a +} + +define i1 @fcmp_true_f32(float %x, float %y) { +; CHECK-LABEL: fcmp_true_f32: +; CHECK: .functype fcmp_true_f32 (f32, f32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: i32.const $push0=, 1 +; CHECK-NEXT: return $pop0 + %a = fcmp true float %x, %y + ret i1 %a +} + +define i1 @fcmp_false_f64(double %x, double %y) { +; CHECK-LABEL: fcmp_false_f64: +; CHECK: .functype fcmp_false_f64 (f64, f64) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: i32.const $push0=, 0 +; CHECK-NEXT: return $pop0 + %a = fcmp false double %x, %y + ret i1 %a +} + +define i1 @fcmp_oeq_f64(double %x, double %y) { +; CHECK-LABEL: fcmp_oeq_f64: +; CHECK: .functype fcmp_oeq_f64 (f64, f64) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f64.eq $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp oeq double %x, %y + ret i1 %a +} + +define i1 @fcmp_ogt_f64(double %x, double %y) { +; CHECK-LABEL: fcmp_ogt_f64: +; CHECK: .functype fcmp_ogt_f64 (f64, f64) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f64.gt $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp ogt double %x, %y + ret i1 %a +} + +define i1 @fcmp_oge_f64(double %x, double %y) { +; CHECK-LABEL: fcmp_oge_f64: +; CHECK: .functype fcmp_oge_f64 (f64, f64) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f64.ge $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp oge double %x, %y + ret i1 %a +} + +define i1 @fcmp_olt_f64(double %x, double %y) { +; CHECK-LABEL: fcmp_olt_f64: +; CHECK: .functype fcmp_olt_f64 (f64, f64) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f64.lt $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp olt double %x, %y + ret i1 %a +} + +define i1 @fcmp_ole_f64(double %x, double %y) { +; CHECK-LABEL: fcmp_ole_f64: +; CHECK: .functype fcmp_ole_f64 (f64, f64) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f64.le $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp ole double %x, %y + ret i1 %a +} + +define i1 @fcmp_one_f64(double %x, double %y) { +; CHECK-LABEL: fcmp_one_f64: +; CHECK: .functype fcmp_one_f64 (f64, f64) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 0 +; CHECK-NEXT: local.get $push3=, 1 +; CHECK-NEXT: f64.lt $push2=, $pop4, $pop3 +; CHECK-NEXT: local.get $push6=, 0 +; CHECK-NEXT: local.get $push5=, 1 +; CHECK-NEXT: f64.gt $push1=, $pop6, $pop5 +; CHECK-NEXT: i32.or $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp one double %x, %y + ret i1 %a +} + +define i1 @fcmp_ord_f64(double %x, double %y) { +; CHECK-LABEL: fcmp_ord_f64: +; CHECK: .functype fcmp_ord_f64 (f64, f64) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 1 +; CHECK-NEXT: local.get $push3=, 1 +; CHECK-NEXT: f64.eq $push2=, $pop4, $pop3 +; CHECK-NEXT: local.get $push6=, 0 +; CHECK-NEXT: local.get $push5=, 0 +; CHECK-NEXT: f64.eq $push1=, $pop6, $pop5 +; CHECK-NEXT: i32.and $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp ord double %x, %y + ret i1 %a +} + +define i1 @fcmp_ueq_f64(double %x, double %y) { +; CHECK-LABEL: fcmp_ueq_f64: +; CHECK: .functype fcmp_ueq_f64 (f64, f64) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push8=, 0 +; CHECK-NEXT: local.get $push7=, 1 +; CHECK-NEXT: f64.lt $push5=, $pop8, $pop7 +; CHECK-NEXT: local.get $push10=, 0 +; CHECK-NEXT: local.get $push9=, 1 +; CHECK-NEXT: f64.gt $push4=, $pop10, $pop9 +; CHECK-NEXT: i32.or $push3=, $pop5, $pop4 +; CHECK-NEXT: i32.const $push2=, 1 +; CHECK-NEXT: i32.xor $push1=, $pop3, $pop2 +; CHECK-NEXT: i32.const $push6=, 1 +; CHECK-NEXT: i32.and $push0=, $pop1, $pop6 +; CHECK-NEXT: return $pop0 + %a = fcmp ueq double %x, %y + ret i1 %a +} + +define i1 @fcmp_ugt_f64(double %x, double %y) { +; CHECK-LABEL: fcmp_ugt_f64: +; CHECK: .functype fcmp_ugt_f64 (f64, f64) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 0 +; CHECK-NEXT: local.get $push3=, 1 +; CHECK-NEXT: f64.le $push2=, $pop4, $pop3 +; CHECK-NEXT: i32.const $push1=, 1 +; CHECK-NEXT: i32.xor $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp ugt double %x, %y + ret i1 %a +} + +define i1 @fcmp_uge_f64(double %x, double %y) { +; CHECK-LABEL: fcmp_uge_f64: +; CHECK: .functype fcmp_uge_f64 (f64, f64) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 0 +; CHECK-NEXT: local.get $push3=, 1 +; CHECK-NEXT: f64.lt $push2=, $pop4, $pop3 +; CHECK-NEXT: i32.const $push1=, 1 +; CHECK-NEXT: i32.xor $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp uge double %x, %y + ret i1 %a +} + +define i1 @fcmp_ult_f64(double %x, double %y) { +; CHECK-LABEL: fcmp_ult_f64: +; CHECK: .functype fcmp_ult_f64 (f64, f64) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 0 +; CHECK-NEXT: local.get $push3=, 1 +; CHECK-NEXT: f64.ge $push2=, $pop4, $pop3 +; CHECK-NEXT: i32.const $push1=, 1 +; CHECK-NEXT: i32.xor $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp ult double %x, %y + ret i1 %a +} + +define i1 @fcmp_ule_f64(double %x, double %y) { +; CHECK-LABEL: fcmp_ule_f64: +; CHECK: .functype fcmp_ule_f64 (f64, f64) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 0 +; CHECK-NEXT: local.get $push3=, 1 +; CHECK-NEXT: f64.gt $push2=, $pop4, $pop3 +; CHECK-NEXT: i32.const $push1=, 1 +; CHECK-NEXT: i32.xor $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp ule double %x, %y + ret i1 %a +} + +define i1 @fcmp_une_f64(double %x, double %y) { +; CHECK-LABEL: fcmp_une_f64: +; CHECK: .functype fcmp_une_f64 (f64, f64) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f64.ne $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp une double %x, %y + ret i1 %a +} + +define i1 @fcmp_uno_f64(double %x, double %y) { +; CHECK-LABEL: fcmp_uno_f64: +; CHECK: .functype fcmp_uno_f64 (f64, f64) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 1 +; CHECK-NEXT: local.get $push3=, 1 +; CHECK-NEXT: f64.ne $push2=, $pop4, $pop3 +; CHECK-NEXT: local.get $push6=, 0 +; CHECK-NEXT: local.get $push5=, 0 +; CHECK-NEXT: f64.ne $push1=, $pop6, $pop5 +; CHECK-NEXT: i32.or $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = fcmp uno double %x, %y + ret i1 %a +} + +define i1 @fcmp_true_f64(double %x, double %y) { +; CHECK-LABEL: fcmp_true_f64: +; CHECK: .functype fcmp_true_f64 (f64, f64) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: i32.const $push0=, 1 +; CHECK-NEXT: return $pop0 + %a = fcmp true double %x, %y + ret i1 %a +} diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fmaximum.ll b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fmaximum.ll new file mode 100644 index 0000000000000..117ea3ecc8d0f --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fmaximum.ll @@ -0,0 +1,32 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc < %s -O0 --global-isel -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s + +target triple = "wasm32-unknown-unknown" + +declare float @llvm.maximum.f32(float, float) +declare double @llvm.maximum.f64(double, double) + + +define float @fmaximum_f32(float %x, float %y) { +; CHECK-LABEL: fmaximum_f32: +; CHECK: .functype fmaximum_f32 (f32, f32) -> (f32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f32.max $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = call float @llvm.maximum.f32(float %x, float %y) + ret float %a +} + +define double @fmaximum_f64(double %x, double %y) { +; CHECK-LABEL: fmaximum_f64: +; CHECK: .functype fmaximum_f64 (f64, f64) -> (f64) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f64.max $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = call double @llvm.maximum.f64(double %x, double %y) + ret double %a +} diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fmaximumnum.ll b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fmaximumnum.ll new file mode 100644 index 0000000000000..45d822f952f8f --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fmaximumnum.ll @@ -0,0 +1,219 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc < %s -O0 --global-isel -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s +; +target triple = "wasm32-unknown-unknown" + +declare float @llvm.maximumnum.f32(float, float) +declare double @llvm.maximumnum.f64(double, double) + +define float @fmaximumnum_f32(float %x, float %y) { +; CHECK-LABEL: fmaximumnum_f32: +; CHECK: .functype fmaximumnum_f32 (f32, f32) -> (f32) +; CHECK-NEXT: .local f32, f32, f32, i32, i32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push19=, 1 +; CHECK-NEXT: local.get $push18=, 0 +; CHECK-NEXT: local.get $push14=, 0 +; CHECK-NEXT: local.get $push13=, 0 +; CHECK-NEXT: f32.ne $push12=, $pop14, $pop13 +; CHECK-NEXT: local.get $push16=, 0 +; CHECK-NEXT: local.get $push15=, 0 +; CHECK-NEXT: f32.ne $push11=, $pop16, $pop15 +; CHECK-NEXT: i32.or $push10=, $pop12, $pop11 +; CHECK-NEXT: f32.select $push17=, $pop19, $pop18, $pop10 +; CHECK-NEXT: local.set 2, $pop17 +; CHECK-NEXT: local.get $push26=, 2 +; CHECK-NEXT: local.get $push25=, 1 +; CHECK-NEXT: local.get $push21=, 1 +; CHECK-NEXT: local.get $push20=, 1 +; CHECK-NEXT: f32.ne $push9=, $pop21, $pop20 +; CHECK-NEXT: local.get $push23=, 1 +; CHECK-NEXT: local.get $push22=, 1 +; CHECK-NEXT: f32.ne $push8=, $pop23, $pop22 +; CHECK-NEXT: i32.or $push7=, $pop9, $pop8 +; CHECK-NEXT: f32.select $push24=, $pop26, $pop25, $pop7 +; CHECK-NEXT: local.set 3, $pop24 +; CHECK-NEXT: local.get $push31=, 2 +; CHECK-NEXT: local.get $push30=, 3 +; CHECK-NEXT: local.get $push28=, 2 +; CHECK-NEXT: local.get $push27=, 3 +; CHECK-NEXT: f32.gt $push6=, $pop28, $pop27 +; CHECK-NEXT: f32.select $push29=, $pop31, $pop30, $pop6 +; CHECK-NEXT: local.set 4, $pop29 +; CHECK-NEXT: local.get $push33=, 4 +; CHECK-NEXT: f32.const $push1=, 0x0p0 +; CHECK-NEXT: f32.eq $push32=, $pop33, $pop1 +; CHECK-NEXT: local.set 5, $pop32 +; CHECK-NEXT: local.get $push35=, 2 +; CHECK-NEXT: i32.reinterpret_f32 $push34=, $pop35 +; CHECK-NEXT: local.set 6, $pop34 +; CHECK-NEXT: local.get $push38=, 2 +; CHECK-NEXT: local.get $push37=, 4 +; CHECK-NEXT: i32.const $push3=, 0 +; CHECK-NEXT: local.get $push36=, 6 +; CHECK-NEXT: i32.eqz $push4=, $pop36 +; CHECK-NEXT: i32.or $push5=, $pop3, $pop4 +; CHECK-NEXT: f32.select $push2=, $pop38, $pop37, $pop5 +; CHECK-NEXT: local.get $push40=, 4 +; CHECK-NEXT: local.get $push39=, 5 +; CHECK-NEXT: f32.select $push0=, $pop2, $pop40, $pop39 +; CHECK-NEXT: return $pop0 + %a = call float @llvm.maximumnum.f32(float %x, float %y) + ret float %a +} + +define double @fmaximumnum_f64(double %x, double %y) { +; CHECK-LABEL: fmaximumnum_f64: +; CHECK: .functype fmaximumnum_f64 (f64, f64) -> (f64) +; CHECK-NEXT: .local f64, f64, f64, i32, i64 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push19=, 1 +; CHECK-NEXT: local.get $push18=, 0 +; CHECK-NEXT: local.get $push14=, 0 +; CHECK-NEXT: local.get $push13=, 0 +; CHECK-NEXT: f64.ne $push12=, $pop14, $pop13 +; CHECK-NEXT: local.get $push16=, 0 +; CHECK-NEXT: local.get $push15=, 0 +; CHECK-NEXT: f64.ne $push11=, $pop16, $pop15 +; CHECK-NEXT: i32.or $push10=, $pop12, $pop11 +; CHECK-NEXT: f64.select $push17=, $pop19, $pop18, $pop10 +; CHECK-NEXT: local.set 2, $pop17 +; CHECK-NEXT: local.get $push26=, 2 +; CHECK-NEXT: local.get $push25=, 1 +; CHECK-NEXT: local.get $push21=, 1 +; CHECK-NEXT: local.get $push20=, 1 +; CHECK-NEXT: f64.ne $push9=, $pop21, $pop20 +; CHECK-NEXT: local.get $push23=, 1 +; CHECK-NEXT: local.get $push22=, 1 +; CHECK-NEXT: f64.ne $push8=, $pop23, $pop22 +; CHECK-NEXT: i32.or $push7=, $pop9, $pop8 +; CHECK-NEXT: f64.select $push24=, $pop26, $pop25, $pop7 +; CHECK-NEXT: local.set 3, $pop24 +; CHECK-NEXT: local.get $push31=, 2 +; CHECK-NEXT: local.get $push30=, 3 +; CHECK-NEXT: local.get $push28=, 2 +; CHECK-NEXT: local.get $push27=, 3 +; CHECK-NEXT: f64.gt $push6=, $pop28, $pop27 +; CHECK-NEXT: f64.select $push29=, $pop31, $pop30, $pop6 +; CHECK-NEXT: local.set 4, $pop29 +; CHECK-NEXT: local.get $push33=, 4 +; CHECK-NEXT: f64.const $push1=, 0x0p0 +; CHECK-NEXT: f64.eq $push32=, $pop33, $pop1 +; CHECK-NEXT: local.set 5, $pop32 +; CHECK-NEXT: local.get $push35=, 2 +; CHECK-NEXT: i64.reinterpret_f64 $push34=, $pop35 +; CHECK-NEXT: local.set 6, $pop34 +; CHECK-NEXT: local.get $push38=, 2 +; CHECK-NEXT: local.get $push37=, 4 +; CHECK-NEXT: i32.const $push3=, 0 +; CHECK-NEXT: local.get $push36=, 6 +; CHECK-NEXT: i64.eqz $push4=, $pop36 +; CHECK-NEXT: i32.or $push5=, $pop3, $pop4 +; CHECK-NEXT: f64.select $push2=, $pop38, $pop37, $pop5 +; CHECK-NEXT: local.get $push40=, 4 +; CHECK-NEXT: local.get $push39=, 5 +; CHECK-NEXT: f64.select $push0=, $pop2, $pop40, $pop39 +; CHECK-NEXT: return $pop0 + %a = call double @llvm.maximumnum.f64(double %x, double %y) + ret double %a +} + +define float @fmaximumnum_f32_nsz(float %x, float %y) { +; CHECK-LABEL: fmaximumnum_f32_nsz: +; CHECK: .functype fmaximumnum_f32_nsz (f32, f32) -> (f32) +; CHECK-NEXT: .local f32, f32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push14=, 1 +; CHECK-NEXT: local.get $push13=, 0 +; CHECK-NEXT: local.get $push9=, 0 +; CHECK-NEXT: local.get $push8=, 0 +; CHECK-NEXT: f32.ne $push7=, $pop9, $pop8 +; CHECK-NEXT: local.get $push11=, 0 +; CHECK-NEXT: local.get $push10=, 0 +; CHECK-NEXT: f32.ne $push6=, $pop11, $pop10 +; CHECK-NEXT: i32.or $push5=, $pop7, $pop6 +; CHECK-NEXT: f32.select $push12=, $pop14, $pop13, $pop5 +; CHECK-NEXT: local.set 2, $pop12 +; CHECK-NEXT: local.get $push21=, 2 +; CHECK-NEXT: local.get $push20=, 1 +; CHECK-NEXT: local.get $push16=, 1 +; CHECK-NEXT: local.get $push15=, 1 +; CHECK-NEXT: f32.ne $push4=, $pop16, $pop15 +; CHECK-NEXT: local.get $push18=, 1 +; CHECK-NEXT: local.get $push17=, 1 +; CHECK-NEXT: f32.ne $push3=, $pop18, $pop17 +; CHECK-NEXT: i32.or $push2=, $pop4, $pop3 +; CHECK-NEXT: f32.select $push19=, $pop21, $pop20, $pop2 +; CHECK-NEXT: local.set 3, $pop19 +; CHECK-NEXT: local.get $push25=, 2 +; CHECK-NEXT: local.get $push24=, 3 +; CHECK-NEXT: local.get $push23=, 2 +; CHECK-NEXT: local.get $push22=, 3 +; CHECK-NEXT: f32.gt $push1=, $pop23, $pop22 +; CHECK-NEXT: f32.select $push0=, $pop25, $pop24, $pop1 +; CHECK-NEXT: return $pop0 + %a = call nsz float @llvm.maximumnum.f32(float %x, float %y) + ret float %a +} + +define double @fmaximumnum_f64_nsz(double %x, double %y) { +; CHECK-LABEL: fmaximumnum_f64_nsz: +; CHECK: .functype fmaximumnum_f64_nsz (f64, f64) -> (f64) +; CHECK-NEXT: .local f64, f64 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push14=, 1 +; CHECK-NEXT: local.get $push13=, 0 +; CHECK-NEXT: local.get $push9=, 0 +; CHECK-NEXT: local.get $push8=, 0 +; CHECK-NEXT: f64.ne $push7=, $pop9, $pop8 +; CHECK-NEXT: local.get $push11=, 0 +; CHECK-NEXT: local.get $push10=, 0 +; CHECK-NEXT: f64.ne $push6=, $pop11, $pop10 +; CHECK-NEXT: i32.or $push5=, $pop7, $pop6 +; CHECK-NEXT: f64.select $push12=, $pop14, $pop13, $pop5 +; CHECK-NEXT: local.set 2, $pop12 +; CHECK-NEXT: local.get $push21=, 2 +; CHECK-NEXT: local.get $push20=, 1 +; CHECK-NEXT: local.get $push16=, 1 +; CHECK-NEXT: local.get $push15=, 1 +; CHECK-NEXT: f64.ne $push4=, $pop16, $pop15 +; CHECK-NEXT: local.get $push18=, 1 +; CHECK-NEXT: local.get $push17=, 1 +; CHECK-NEXT: f64.ne $push3=, $pop18, $pop17 +; CHECK-NEXT: i32.or $push2=, $pop4, $pop3 +; CHECK-NEXT: f64.select $push19=, $pop21, $pop20, $pop2 +; CHECK-NEXT: local.set 3, $pop19 +; CHECK-NEXT: local.get $push25=, 2 +; CHECK-NEXT: local.get $push24=, 3 +; CHECK-NEXT: local.get $push23=, 2 +; CHECK-NEXT: local.get $push22=, 3 +; CHECK-NEXT: f64.gt $push1=, $pop23, $pop22 +; CHECK-NEXT: f64.select $push0=, $pop25, $pop24, $pop1 +; CHECK-NEXT: return $pop0 + %a = call nsz double @llvm.maximumnum.f64(double %x, double %y) + ret double %a +} + +define float @fmaximumnum_f32_nnan(float %x, float %y) { +; CHECK-LABEL: fmaximumnum_f32_nnan: +; CHECK: .functype fmaximumnum_f32_nnan (f32, f32) -> (f32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f32.min $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = call nnan float @llvm.maximumnum.f32(float %x, float %y) + ret float %a +} + +define double @fmaximumnum_f64_nnan(double %x, double %y) { +; CHECK-LABEL: fmaximumnum_f64_nnan: +; CHECK: .functype fmaximumnum_f64_nnan (f64, f64) -> (f64) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f64.min $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = call nnan double @llvm.maximumnum.f64(double %x, double %y) + ret double %a +} diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fmaxnum.ll b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fmaxnum.ll new file mode 100644 index 0000000000000..4fb5119c171f4 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fmaxnum.ll @@ -0,0 +1,55 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc < %s -O0 --global-isel -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s + +target triple = "wasm32-unknown-unknown" + +declare float @llvm.maxnum.f32(float, float) +declare double @llvm.maxnum.f64(double, double) + +define float @fmaxnum_f32(float %x, float %y) { +; CHECK-LABEL: fmaxnum_f32: +; CHECK: .functype fmaxnum_f32 (f32, f32) -> (f32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: call $push0=, fmaxf, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = call float @llvm.maxnum.f32(float %x, float %y) + ret float %a +} + +define double @fmaxnum_f64(double %x, double %y) { +; CHECK-LABEL: fmaxnum_f64: +; CHECK: .functype fmaxnum_f64 (f64, f64) -> (f64) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: call $push0=, fmax, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = call double @llvm.maxnum.f64(double %x, double %y) + ret double %a +} + +define float @fmaxnum_f32_nnan(float %x, float %y) { +; CHECK-LABEL: fmaxnum_f32_nnan: +; CHECK: .functype fmaxnum_f32_nnan (f32, f32) -> (f32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f32.max $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = call nnan float @llvm.maxnum.f32(float %x, float %y) + ret float %a +} + +define double @fmaxnum_f64_nnan(double %x, double %y) { +; CHECK-LABEL: fmaxnum_f64_nnan: +; CHECK: .functype fmaxnum_f64_nnan (f64, f64) -> (f64) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f64.max $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = call nnan double @llvm.maxnum.f64(double %x, double %y) + ret double %a +} diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fminimum.ll b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fminimum.ll new file mode 100644 index 0000000000000..cab1ae23c0e4c --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fminimum.ll @@ -0,0 +1,32 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc < %s -O0 --global-isel -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s + +target triple = "wasm32-unknown-unknown" + +declare float @llvm.minimum.f32(float, float) +declare double @llvm.minimum.f64(double, double) + + +define float @fminimum_f32(float %x, float %y) { +; CHECK-LABEL: fminimum_f32: +; CHECK: .functype fminimum_f32 (f32, f32) -> (f32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f32.min $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = call float @llvm.minimum.f32(float %x, float %y) + ret float %a +} + +define double @fminimum_f64(double %x, double %y) { +; CHECK-LABEL: fminimum_f64: +; CHECK: .functype fminimum_f64 (f64, f64) -> (f64) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f64.min $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = call double @llvm.minimum.f64(double %x, double %y) + ret double %a +} diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fminimumnum.ll b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fminimumnum.ll new file mode 100644 index 0000000000000..d7530a5a4a0df --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fminimumnum.ll @@ -0,0 +1,225 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc < %s -O0 --global-isel -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s +; +target triple = "wasm32-unknown-unknown" + +declare float @llvm.minimumnum.f32(float, float) +declare double @llvm.minimumnum.f64(double, double) + +define float @fminimumnum_f32(float %x, float %y) { +; CHECK-LABEL: fminimumnum_f32: +; CHECK: .functype fminimumnum_f32 (f32, f32) -> (f32) +; CHECK-NEXT: .local f32, f32, f32, i32, i32, i32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push19=, 1 +; CHECK-NEXT: local.get $push18=, 0 +; CHECK-NEXT: local.get $push14=, 0 +; CHECK-NEXT: local.get $push13=, 0 +; CHECK-NEXT: f32.ne $push12=, $pop14, $pop13 +; CHECK-NEXT: local.get $push16=, 0 +; CHECK-NEXT: local.get $push15=, 0 +; CHECK-NEXT: f32.ne $push11=, $pop16, $pop15 +; CHECK-NEXT: i32.or $push10=, $pop12, $pop11 +; CHECK-NEXT: f32.select $push17=, $pop19, $pop18, $pop10 +; CHECK-NEXT: local.set 2, $pop17 +; CHECK-NEXT: local.get $push26=, 2 +; CHECK-NEXT: local.get $push25=, 1 +; CHECK-NEXT: local.get $push21=, 1 +; CHECK-NEXT: local.get $push20=, 1 +; CHECK-NEXT: f32.ne $push9=, $pop21, $pop20 +; CHECK-NEXT: local.get $push23=, 1 +; CHECK-NEXT: local.get $push22=, 1 +; CHECK-NEXT: f32.ne $push8=, $pop23, $pop22 +; CHECK-NEXT: i32.or $push7=, $pop9, $pop8 +; CHECK-NEXT: f32.select $push24=, $pop26, $pop25, $pop7 +; CHECK-NEXT: local.set 3, $pop24 +; CHECK-NEXT: local.get $push31=, 2 +; CHECK-NEXT: local.get $push30=, 3 +; CHECK-NEXT: local.get $push28=, 2 +; CHECK-NEXT: local.get $push27=, 3 +; CHECK-NEXT: f32.lt $push6=, $pop28, $pop27 +; CHECK-NEXT: f32.select $push29=, $pop31, $pop30, $pop6 +; CHECK-NEXT: local.set 4, $pop29 +; CHECK-NEXT: local.get $push33=, 4 +; CHECK-NEXT: f32.const $push1=, 0x0p0 +; CHECK-NEXT: f32.eq $push32=, $pop33, $pop1 +; CHECK-NEXT: local.set 5, $pop32 +; CHECK-NEXT: local.get $push35=, 2 +; CHECK-NEXT: i32.reinterpret_f32 $push34=, $pop35 +; CHECK-NEXT: local.set 6, $pop34 +; CHECK-NEXT: i32.const $push36=, -2147483648 +; CHECK-NEXT: local.set 7, $pop36 +; CHECK-NEXT: local.get $push40=, 2 +; CHECK-NEXT: local.get $push39=, 4 +; CHECK-NEXT: i32.const $push3=, 0 +; CHECK-NEXT: local.get $push38=, 6 +; CHECK-NEXT: local.get $push37=, 7 +; CHECK-NEXT: i32.eq $push4=, $pop38, $pop37 +; CHECK-NEXT: i32.or $push5=, $pop3, $pop4 +; CHECK-NEXT: f32.select $push2=, $pop40, $pop39, $pop5 +; CHECK-NEXT: local.get $push42=, 4 +; CHECK-NEXT: local.get $push41=, 5 +; CHECK-NEXT: f32.select $push0=, $pop2, $pop42, $pop41 +; CHECK-NEXT: return $pop0 + %a = call float @llvm.minimumnum.f32(float %x, float %y) + ret float %a +} + +define double @fminimumnum_f64(double %x, double %y) { +; CHECK-LABEL: fminimumnum_f64: +; CHECK: .functype fminimumnum_f64 (f64, f64) -> (f64) +; CHECK-NEXT: .local f64, f64, f64, i32, i64, i64 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push19=, 1 +; CHECK-NEXT: local.get $push18=, 0 +; CHECK-NEXT: local.get $push14=, 0 +; CHECK-NEXT: local.get $push13=, 0 +; CHECK-NEXT: f64.ne $push12=, $pop14, $pop13 +; CHECK-NEXT: local.get $push16=, 0 +; CHECK-NEXT: local.get $push15=, 0 +; CHECK-NEXT: f64.ne $push11=, $pop16, $pop15 +; CHECK-NEXT: i32.or $push10=, $pop12, $pop11 +; CHECK-NEXT: f64.select $push17=, $pop19, $pop18, $pop10 +; CHECK-NEXT: local.set 2, $pop17 +; CHECK-NEXT: local.get $push26=, 2 +; CHECK-NEXT: local.get $push25=, 1 +; CHECK-NEXT: local.get $push21=, 1 +; CHECK-NEXT: local.get $push20=, 1 +; CHECK-NEXT: f64.ne $push9=, $pop21, $pop20 +; CHECK-NEXT: local.get $push23=, 1 +; CHECK-NEXT: local.get $push22=, 1 +; CHECK-NEXT: f64.ne $push8=, $pop23, $pop22 +; CHECK-NEXT: i32.or $push7=, $pop9, $pop8 +; CHECK-NEXT: f64.select $push24=, $pop26, $pop25, $pop7 +; CHECK-NEXT: local.set 3, $pop24 +; CHECK-NEXT: local.get $push31=, 2 +; CHECK-NEXT: local.get $push30=, 3 +; CHECK-NEXT: local.get $push28=, 2 +; CHECK-NEXT: local.get $push27=, 3 +; CHECK-NEXT: f64.lt $push6=, $pop28, $pop27 +; CHECK-NEXT: f64.select $push29=, $pop31, $pop30, $pop6 +; CHECK-NEXT: local.set 4, $pop29 +; CHECK-NEXT: local.get $push33=, 4 +; CHECK-NEXT: f64.const $push1=, 0x0p0 +; CHECK-NEXT: f64.eq $push32=, $pop33, $pop1 +; CHECK-NEXT: local.set 5, $pop32 +; CHECK-NEXT: local.get $push35=, 2 +; CHECK-NEXT: i64.reinterpret_f64 $push34=, $pop35 +; CHECK-NEXT: local.set 6, $pop34 +; CHECK-NEXT: i64.const $push36=, -9223372036854775808 +; CHECK-NEXT: local.set 7, $pop36 +; CHECK-NEXT: local.get $push40=, 2 +; CHECK-NEXT: local.get $push39=, 4 +; CHECK-NEXT: i32.const $push3=, 0 +; CHECK-NEXT: local.get $push38=, 6 +; CHECK-NEXT: local.get $push37=, 7 +; CHECK-NEXT: i64.eq $push4=, $pop38, $pop37 +; CHECK-NEXT: i32.or $push5=, $pop3, $pop4 +; CHECK-NEXT: f64.select $push2=, $pop40, $pop39, $pop5 +; CHECK-NEXT: local.get $push42=, 4 +; CHECK-NEXT: local.get $push41=, 5 +; CHECK-NEXT: f64.select $push0=, $pop2, $pop42, $pop41 +; CHECK-NEXT: return $pop0 + %a = call double @llvm.minimumnum.f64(double %x, double %y) + ret double %a +} + +define float @fminimumnum_f32_nsz(float %x, float %y) { +; CHECK-LABEL: fminimumnum_f32_nsz: +; CHECK: .functype fminimumnum_f32_nsz (f32, f32) -> (f32) +; CHECK-NEXT: .local f32, f32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push14=, 1 +; CHECK-NEXT: local.get $push13=, 0 +; CHECK-NEXT: local.get $push9=, 0 +; CHECK-NEXT: local.get $push8=, 0 +; CHECK-NEXT: f32.ne $push7=, $pop9, $pop8 +; CHECK-NEXT: local.get $push11=, 0 +; CHECK-NEXT: local.get $push10=, 0 +; CHECK-NEXT: f32.ne $push6=, $pop11, $pop10 +; CHECK-NEXT: i32.or $push5=, $pop7, $pop6 +; CHECK-NEXT: f32.select $push12=, $pop14, $pop13, $pop5 +; CHECK-NEXT: local.set 2, $pop12 +; CHECK-NEXT: local.get $push21=, 2 +; CHECK-NEXT: local.get $push20=, 1 +; CHECK-NEXT: local.get $push16=, 1 +; CHECK-NEXT: local.get $push15=, 1 +; CHECK-NEXT: f32.ne $push4=, $pop16, $pop15 +; CHECK-NEXT: local.get $push18=, 1 +; CHECK-NEXT: local.get $push17=, 1 +; CHECK-NEXT: f32.ne $push3=, $pop18, $pop17 +; CHECK-NEXT: i32.or $push2=, $pop4, $pop3 +; CHECK-NEXT: f32.select $push19=, $pop21, $pop20, $pop2 +; CHECK-NEXT: local.set 3, $pop19 +; CHECK-NEXT: local.get $push25=, 2 +; CHECK-NEXT: local.get $push24=, 3 +; CHECK-NEXT: local.get $push23=, 2 +; CHECK-NEXT: local.get $push22=, 3 +; CHECK-NEXT: f32.lt $push1=, $pop23, $pop22 +; CHECK-NEXT: f32.select $push0=, $pop25, $pop24, $pop1 +; CHECK-NEXT: return $pop0 + %a = call nsz float @llvm.minimumnum.f32(float %x, float %y) + ret float %a +} + +define double @fminimumnum_f64_nsz(double %x, double %y) { +; CHECK-LABEL: fminimumnum_f64_nsz: +; CHECK: .functype fminimumnum_f64_nsz (f64, f64) -> (f64) +; CHECK-NEXT: .local f64, f64 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push14=, 1 +; CHECK-NEXT: local.get $push13=, 0 +; CHECK-NEXT: local.get $push9=, 0 +; CHECK-NEXT: local.get $push8=, 0 +; CHECK-NEXT: f64.ne $push7=, $pop9, $pop8 +; CHECK-NEXT: local.get $push11=, 0 +; CHECK-NEXT: local.get $push10=, 0 +; CHECK-NEXT: f64.ne $push6=, $pop11, $pop10 +; CHECK-NEXT: i32.or $push5=, $pop7, $pop6 +; CHECK-NEXT: f64.select $push12=, $pop14, $pop13, $pop5 +; CHECK-NEXT: local.set 2, $pop12 +; CHECK-NEXT: local.get $push21=, 2 +; CHECK-NEXT: local.get $push20=, 1 +; CHECK-NEXT: local.get $push16=, 1 +; CHECK-NEXT: local.get $push15=, 1 +; CHECK-NEXT: f64.ne $push4=, $pop16, $pop15 +; CHECK-NEXT: local.get $push18=, 1 +; CHECK-NEXT: local.get $push17=, 1 +; CHECK-NEXT: f64.ne $push3=, $pop18, $pop17 +; CHECK-NEXT: i32.or $push2=, $pop4, $pop3 +; CHECK-NEXT: f64.select $push19=, $pop21, $pop20, $pop2 +; CHECK-NEXT: local.set 3, $pop19 +; CHECK-NEXT: local.get $push25=, 2 +; CHECK-NEXT: local.get $push24=, 3 +; CHECK-NEXT: local.get $push23=, 2 +; CHECK-NEXT: local.get $push22=, 3 +; CHECK-NEXT: f64.lt $push1=, $pop23, $pop22 +; CHECK-NEXT: f64.select $push0=, $pop25, $pop24, $pop1 +; CHECK-NEXT: return $pop0 + %a = call nsz double @llvm.minimumnum.f64(double %x, double %y) + ret double %a +} + +define float @fminimumnum_f32_nnan(float %x, float %y) { +; CHECK-LABEL: fminimumnum_f32_nnan: +; CHECK: .functype fminimumnum_f32_nnan (f32, f32) -> (f32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f32.min $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = call nnan float @llvm.minimumnum.f32(float %x, float %y) + ret float %a +} + +define double @fminimumnum_f64_nnan(double %x, double %y) { +; CHECK-LABEL: fminimumnum_f64_nnan: +; CHECK: .functype fminimumnum_f64_nnan (f64, f64) -> (f64) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f64.min $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = call nnan double @llvm.minimumnum.f64(double %x, double %y) + ret double %a +} diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fminnum.ll b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fminnum.ll new file mode 100644 index 0000000000000..026df12684264 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fminnum.ll @@ -0,0 +1,55 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc < %s -O0 --global-isel -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s + +target triple = "wasm32-unknown-unknown" + +declare float @llvm.minnum.f32(float, float) +declare double @llvm.minnum.f64(double, double) + +define float @fminnum_f32(float %x, float %y) { +; CHECK-LABEL: fminnum_f32: +; CHECK: .functype fminnum_f32 (f32, f32) -> (f32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: call $push0=, fminf, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = call float @llvm.minnum.f32(float %x, float %y) + ret float %a +} + +define double @fminnum_f64(double %x, double %y) { +; CHECK-LABEL: fminnum_f64: +; CHECK: .functype fminnum_f64 (f64, f64) -> (f64) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: call $push0=, fmin, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = call double @llvm.minnum.f64(double %x, double %y) + ret double %a +} + +define float @fminnum_f32_nnan(float %x, float %y) { +; CHECK-LABEL: fminnum_f32_nnan: +; CHECK: .functype fminnum_f32_nnan (f32, f32) -> (f32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f32.min $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = call nnan float @llvm.minnum.f32(float %x, float %y) + ret float %a +} + +define double @fminnum_f64_nnan(double %x, double %y) { +; CHECK-LABEL: fminnum_f64_nnan: +; CHECK: .functype fminnum_f64_nnan (f64, f64) -> (f64) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push2=, 0 +; CHECK-NEXT: local.get $push1=, 1 +; CHECK-NEXT: f64.min $push0=, $pop2, $pop1 +; CHECK-NEXT: return $pop0 + %a = call nnan double @llvm.minnum.f64(double %x, double %y) + ret double %a +} diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/is_fpclass.ll b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/is_fpclass.ll new file mode 100644 index 0000000000000..03d9ad65ec887 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/is_fpclass.ll @@ -0,0 +1,490 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc < %s -O0 --global-isel -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s + +target triple = "wasm32-unknown-unknown" + +declare i1 @llvm.is.fpclass.f32(float, i32) +declare i1 @llvm.is.fpclass.f64(double, i32) + +define i1 @is_fpclass_f32_snan(float %x) { +; CHECK-LABEL: is_fpclass_f32_snan: +; CHECK: .functype is_fpclass_f32_snan (f32) -> (i32) +; CHECK-NEXT: .local i32, i32, i32, i32, i32, i32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push5=, 0 +; CHECK-NEXT: i32.reinterpret_f32 $push4=, $pop5 +; CHECK-NEXT: local.set 1, $pop4 +; CHECK-NEXT: i32.const $push6=, 2147483647 +; CHECK-NEXT: local.set 2, $pop6 +; CHECK-NEXT: i32.const $push7=, 2139095040 +; CHECK-NEXT: local.set 3, $pop7 +; CHECK-NEXT: local.get $push10=, 1 +; CHECK-NEXT: local.get $push9=, 2 +; CHECK-NEXT: i32.and $push8=, $pop10, $pop9 +; CHECK-NEXT: local.set 4, $pop8 +; CHECK-NEXT: i32.const $push11=, 0 +; CHECK-NEXT: local.set 5, $pop11 +; CHECK-NEXT: i32.const $push12=, 2143289344 +; CHECK-NEXT: local.set 6, $pop12 +; CHECK-NEXT: local.get $push17=, 5 +; CHECK-NEXT: local.get $push14=, 4 +; CHECK-NEXT: local.get $push13=, 3 +; CHECK-NEXT: i32.gt_u $push0=, $pop14, $pop13 +; CHECK-NEXT: local.get $push16=, 4 +; CHECK-NEXT: local.get $push15=, 6 +; CHECK-NEXT: i32.lt_u $push1=, $pop16, $pop15 +; CHECK-NEXT: i32.and $push2=, $pop0, $pop1 +; CHECK-NEXT: i32.or $push3=, $pop17, $pop2 +; CHECK-NEXT: return $pop3 + %a = call i1 @llvm.is.fpclass.f32(float %x, i32 1) + ret i1 %a +} + +define i1 @is_fpclass_f32_qnan(float %x) { +; CHECK-LABEL: is_fpclass_f32_qnan: +; CHECK: .functype is_fpclass_f32_qnan (f32) -> (i32) +; CHECK-NEXT: .local i32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push6=, 0 +; CHECK-NEXT: i32.reinterpret_f32 $push0=, $pop6 +; CHECK-NEXT: i32.const $push1=, 2147483647 +; CHECK-NEXT: i32.and $push7=, $pop0, $pop1 +; CHECK-NEXT: local.set 1, $pop7 +; CHECK-NEXT: i32.const $push2=, 0 +; CHECK-NEXT: local.get $push8=, 1 +; CHECK-NEXT: i32.const $push3=, 2143289344 +; CHECK-NEXT: i32.ge_u $push4=, $pop8, $pop3 +; CHECK-NEXT: i32.or $push5=, $pop2, $pop4 +; CHECK-NEXT: return $pop5 + %a = call i1 @llvm.is.fpclass.f32(float %x, i32 2) + ret i1 %a +} + +define i1 @is_fpclass_f32_neginf(float %x) { +; CHECK-LABEL: is_fpclass_f32_neginf: +; CHECK: .functype is_fpclass_f32_neginf (f32) -> (i32) +; CHECK-NEXT: .local i32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push5=, 0 +; CHECK-NEXT: i32.reinterpret_f32 $push4=, $pop5 +; CHECK-NEXT: local.set 1, $pop4 +; CHECK-NEXT: i32.const $push0=, 0 +; CHECK-NEXT: local.get $push6=, 1 +; CHECK-NEXT: i32.const $push1=, -8388608 +; CHECK-NEXT: i32.eq $push2=, $pop6, $pop1 +; CHECK-NEXT: i32.or $push3=, $pop0, $pop2 +; CHECK-NEXT: return $pop3 + %a = call i1 @llvm.is.fpclass.f32(float %x, i32 4) + ret i1 %a +} + +define i1 @is_fpclass_f32_negnormal(float %x) { +; CHECK-LABEL: is_fpclass_f32_negnormal: +; CHECK: .functype is_fpclass_f32_negnormal (f32) -> (i32) +; CHECK-NEXT: .local i32, i32, i32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push9=, 0 +; CHECK-NEXT: i32.reinterpret_f32 $push8=, $pop9 +; CHECK-NEXT: local.set 1, $pop8 +; CHECK-NEXT: local.get $push11=, 1 +; CHECK-NEXT: i32.const $push0=, 2147483647 +; CHECK-NEXT: i32.and $push10=, $pop11, $pop0 +; CHECK-NEXT: local.set 2, $pop10 +; CHECK-NEXT: local.get $push14=, 1 +; CHECK-NEXT: local.get $push13=, 2 +; CHECK-NEXT: i32.ne $push12=, $pop14, $pop13 +; CHECK-NEXT: local.set 3, $pop12 +; CHECK-NEXT: i32.const $push1=, 0 +; CHECK-NEXT: local.get $push16=, 3 +; CHECK-NEXT: local.get $push15=, 2 +; CHECK-NEXT: i32.const $push2=, 8388608 +; CHECK-NEXT: i32.sub $push3=, $pop15, $pop2 +; CHECK-NEXT: i32.const $push4=, 2130706432 +; CHECK-NEXT: i32.lt_u $push5=, $pop3, $pop4 +; CHECK-NEXT: i32.and $push6=, $pop16, $pop5 +; CHECK-NEXT: i32.or $push7=, $pop1, $pop6 +; CHECK-NEXT: return $pop7 + %a = call i1 @llvm.is.fpclass.f32(float %x, i32 8) + ret i1 %a +} + +define i1 @is_fpclass_f32_negsubnorm(float %x) { +; CHECK-LABEL: is_fpclass_f32_negsubnorm: +; CHECK: .functype is_fpclass_f32_negsubnorm (f32) -> (i32) +; CHECK-NEXT: .local i32, i32, i32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push9=, 0 +; CHECK-NEXT: i32.reinterpret_f32 $push8=, $pop9 +; CHECK-NEXT: local.set 1, $pop8 +; CHECK-NEXT: local.get $push11=, 1 +; CHECK-NEXT: i32.const $push0=, 2147483647 +; CHECK-NEXT: i32.and $push10=, $pop11, $pop0 +; CHECK-NEXT: local.set 2, $pop10 +; CHECK-NEXT: local.get $push14=, 1 +; CHECK-NEXT: local.get $push13=, 2 +; CHECK-NEXT: i32.ne $push12=, $pop14, $pop13 +; CHECK-NEXT: local.set 3, $pop12 +; CHECK-NEXT: i32.const $push1=, 0 +; CHECK-NEXT: local.get $push16=, 3 +; CHECK-NEXT: local.get $push15=, 2 +; CHECK-NEXT: i32.const $push2=, 1 +; CHECK-NEXT: i32.sub $push3=, $pop15, $pop2 +; CHECK-NEXT: i32.const $push4=, 8388607 +; CHECK-NEXT: i32.lt_u $push5=, $pop3, $pop4 +; CHECK-NEXT: i32.and $push6=, $pop16, $pop5 +; CHECK-NEXT: i32.or $push7=, $pop1, $pop6 +; CHECK-NEXT: return $pop7 + %a = call i1 @llvm.is.fpclass.f32(float %x, i32 16) + ret i1 %a +} + +define i1 @is_fpclass_f32_negzero(float %x) { +; CHECK-LABEL: is_fpclass_f32_negzero: +; CHECK: .functype is_fpclass_f32_negzero (f32) -> (i32) +; CHECK-NEXT: .local i32, i32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 0 +; CHECK-NEXT: i32.reinterpret_f32 $push3=, $pop4 +; CHECK-NEXT: local.set 1, $pop3 +; CHECK-NEXT: i32.const $push5=, -2147483648 +; CHECK-NEXT: local.set 2, $pop5 +; CHECK-NEXT: i32.const $push0=, 0 +; CHECK-NEXT: local.get $push7=, 1 +; CHECK-NEXT: local.get $push6=, 2 +; CHECK-NEXT: i32.eq $push1=, $pop7, $pop6 +; CHECK-NEXT: i32.or $push2=, $pop0, $pop1 +; CHECK-NEXT: return $pop2 + %a = call i1 @llvm.is.fpclass.f32(float %x, i32 32) + ret i1 %a +} + +define i1 @is_fpclass_f32_poszero(float %x) { +; CHECK-LABEL: is_fpclass_f32_poszero: +; CHECK: .functype is_fpclass_f32_poszero (f32) -> (i32) +; CHECK-NEXT: .local i32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 0 +; CHECK-NEXT: i32.reinterpret_f32 $push3=, $pop4 +; CHECK-NEXT: local.set 1, $pop3 +; CHECK-NEXT: i32.const $push0=, 0 +; CHECK-NEXT: local.get $push5=, 1 +; CHECK-NEXT: i32.eqz $push1=, $pop5 +; CHECK-NEXT: i32.or $push2=, $pop0, $pop1 +; CHECK-NEXT: return $pop2 + %a = call i1 @llvm.is.fpclass.f32(float %x, i32 64) + ret i1 %a +} + +define i1 @is_fpclass_f32_possubnorm(float %x) { +; CHECK-LABEL: is_fpclass_f32_possubnorm: +; CHECK: .functype is_fpclass_f32_possubnorm (f32) -> (i32) +; CHECK-NEXT: .local i32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push7=, 0 +; CHECK-NEXT: i32.reinterpret_f32 $push6=, $pop7 +; CHECK-NEXT: local.set 1, $pop6 +; CHECK-NEXT: i32.const $push0=, 0 +; CHECK-NEXT: local.get $push8=, 1 +; CHECK-NEXT: i32.const $push1=, 1 +; CHECK-NEXT: i32.sub $push2=, $pop8, $pop1 +; CHECK-NEXT: i32.const $push3=, 8388607 +; CHECK-NEXT: i32.lt_u $push4=, $pop2, $pop3 +; CHECK-NEXT: i32.or $push5=, $pop0, $pop4 +; CHECK-NEXT: return $pop5 + %a = call i1 @llvm.is.fpclass.f32(float %x, i32 128) + ret i1 %a +} + +define i1 @is_fpclass_f32_posnormal(float %x) { +; CHECK-LABEL: is_fpclass_f32_posnormal: +; CHECK: .functype is_fpclass_f32_posnormal (f32) -> (i32) +; CHECK-NEXT: .local i32, i32, i32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push11=, 0 +; CHECK-NEXT: i32.reinterpret_f32 $push10=, $pop11 +; CHECK-NEXT: local.set 1, $pop10 +; CHECK-NEXT: local.get $push13=, 1 +; CHECK-NEXT: i32.const $push0=, 2147483647 +; CHECK-NEXT: i32.and $push12=, $pop13, $pop0 +; CHECK-NEXT: local.set 2, $pop12 +; CHECK-NEXT: local.get $push16=, 1 +; CHECK-NEXT: local.get $push15=, 2 +; CHECK-NEXT: i32.ne $push14=, $pop16, $pop15 +; CHECK-NEXT: local.set 3, $pop14 +; CHECK-NEXT: i32.const $push1=, 0 +; CHECK-NEXT: local.get $push17=, 2 +; CHECK-NEXT: i32.const $push2=, 8388608 +; CHECK-NEXT: i32.sub $push3=, $pop17, $pop2 +; CHECK-NEXT: i32.const $push4=, 2130706432 +; CHECK-NEXT: i32.lt_u $push5=, $pop3, $pop4 +; CHECK-NEXT: local.get $push18=, 3 +; CHECK-NEXT: i32.const $push6=, -1 +; CHECK-NEXT: i32.xor $push7=, $pop18, $pop6 +; CHECK-NEXT: i32.and $push8=, $pop5, $pop7 +; CHECK-NEXT: i32.or $push9=, $pop1, $pop8 +; CHECK-NEXT: return $pop9 + %a = call i1 @llvm.is.fpclass.f32(float %x, i32 256) + ret i1 %a +} + +define i1 @is_fpclass_f32_posinf(float %x) { +; CHECK-LABEL: is_fpclass_f32_posinf: +; CHECK: .functype is_fpclass_f32_posinf (f32) -> (i32) +; CHECK-NEXT: .local i32, i32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 0 +; CHECK-NEXT: i32.reinterpret_f32 $push3=, $pop4 +; CHECK-NEXT: local.set 1, $pop3 +; CHECK-NEXT: i32.const $push5=, 2139095040 +; CHECK-NEXT: local.set 2, $pop5 +; CHECK-NEXT: i32.const $push0=, 0 +; CHECK-NEXT: local.get $push7=, 1 +; CHECK-NEXT: local.get $push6=, 2 +; CHECK-NEXT: i32.eq $push1=, $pop7, $pop6 +; CHECK-NEXT: i32.or $push2=, $pop0, $pop1 +; CHECK-NEXT: return $pop2 + %a = call i1 @llvm.is.fpclass.f32(float %x, i32 512) + ret i1 %a +} + + +define i1 @is_fpclass_f64_snan(double %x) { +; CHECK-LABEL: is_fpclass_f64_snan: +; CHECK: .functype is_fpclass_f64_snan (f64) -> (i32) +; CHECK-NEXT: .local i64, i64, i64, i64, i32, i64 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push5=, 0 +; CHECK-NEXT: i64.reinterpret_f64 $push4=, $pop5 +; CHECK-NEXT: local.set 1, $pop4 +; CHECK-NEXT: i64.const $push6=, 9223372036854775807 +; CHECK-NEXT: local.set 2, $pop6 +; CHECK-NEXT: i64.const $push7=, 9218868437227405312 +; CHECK-NEXT: local.set 3, $pop7 +; CHECK-NEXT: local.get $push10=, 1 +; CHECK-NEXT: local.get $push9=, 2 +; CHECK-NEXT: i64.and $push8=, $pop10, $pop9 +; CHECK-NEXT: local.set 4, $pop8 +; CHECK-NEXT: i32.const $push11=, 0 +; CHECK-NEXT: local.set 5, $pop11 +; CHECK-NEXT: i64.const $push12=, 9221120237041090560 +; CHECK-NEXT: local.set 6, $pop12 +; CHECK-NEXT: local.get $push17=, 5 +; CHECK-NEXT: local.get $push14=, 4 +; CHECK-NEXT: local.get $push13=, 3 +; CHECK-NEXT: i64.gt_u $push0=, $pop14, $pop13 +; CHECK-NEXT: local.get $push16=, 4 +; CHECK-NEXT: local.get $push15=, 6 +; CHECK-NEXT: i64.lt_u $push1=, $pop16, $pop15 +; CHECK-NEXT: i32.and $push2=, $pop0, $pop1 +; CHECK-NEXT: i32.or $push3=, $pop17, $pop2 +; CHECK-NEXT: return $pop3 + %a = call i1 @llvm.is.fpclass.f64(double %x, i32 1) + ret i1 %a +} + +define i1 @is_fpclass_f64_qnan(double %x) { +; CHECK-LABEL: is_fpclass_f64_qnan: +; CHECK: .functype is_fpclass_f64_qnan (f64) -> (i32) +; CHECK-NEXT: .local i64 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push6=, 0 +; CHECK-NEXT: i64.reinterpret_f64 $push0=, $pop6 +; CHECK-NEXT: i64.const $push1=, 9223372036854775807 +; CHECK-NEXT: i64.and $push7=, $pop0, $pop1 +; CHECK-NEXT: local.set 1, $pop7 +; CHECK-NEXT: i32.const $push2=, 0 +; CHECK-NEXT: local.get $push8=, 1 +; CHECK-NEXT: i64.const $push3=, 9221120237041090560 +; CHECK-NEXT: i64.ge_u $push4=, $pop8, $pop3 +; CHECK-NEXT: i32.or $push5=, $pop2, $pop4 +; CHECK-NEXT: return $pop5 + %a = call i1 @llvm.is.fpclass.f64(double %x, i32 2) + ret i1 %a +} + +define i1 @is_fpclass_f64_neginf(double %x) { +; CHECK-LABEL: is_fpclass_f64_neginf: +; CHECK: .functype is_fpclass_f64_neginf (f64) -> (i32) +; CHECK-NEXT: .local i64 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push5=, 0 +; CHECK-NEXT: i64.reinterpret_f64 $push4=, $pop5 +; CHECK-NEXT: local.set 1, $pop4 +; CHECK-NEXT: i32.const $push0=, 0 +; CHECK-NEXT: local.get $push6=, 1 +; CHECK-NEXT: i64.const $push1=, -4503599627370496 +; CHECK-NEXT: i64.eq $push2=, $pop6, $pop1 +; CHECK-NEXT: i32.or $push3=, $pop0, $pop2 +; CHECK-NEXT: return $pop3 + %a = call i1 @llvm.is.fpclass.f64(double %x, i32 4) + ret i1 %a +} + +define i1 @is_fpclass_f64_negnormal(double %x) { +; CHECK-LABEL: is_fpclass_f64_negnormal: +; CHECK: .functype is_fpclass_f64_negnormal (f64) -> (i32) +; CHECK-NEXT: .local i64, i64, i32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push9=, 0 +; CHECK-NEXT: i64.reinterpret_f64 $push8=, $pop9 +; CHECK-NEXT: local.set 1, $pop8 +; CHECK-NEXT: local.get $push11=, 1 +; CHECK-NEXT: i64.const $push0=, 9223372036854775807 +; CHECK-NEXT: i64.and $push10=, $pop11, $pop0 +; CHECK-NEXT: local.set 2, $pop10 +; CHECK-NEXT: local.get $push14=, 1 +; CHECK-NEXT: local.get $push13=, 2 +; CHECK-NEXT: i64.ne $push12=, $pop14, $pop13 +; CHECK-NEXT: local.set 3, $pop12 +; CHECK-NEXT: i32.const $push1=, 0 +; CHECK-NEXT: local.get $push16=, 3 +; CHECK-NEXT: local.get $push15=, 2 +; CHECK-NEXT: i64.const $push2=, 4503599627370496 +; CHECK-NEXT: i64.sub $push3=, $pop15, $pop2 +; CHECK-NEXT: i64.const $push4=, 9214364837600034816 +; CHECK-NEXT: i64.lt_u $push5=, $pop3, $pop4 +; CHECK-NEXT: i32.and $push6=, $pop16, $pop5 +; CHECK-NEXT: i32.or $push7=, $pop1, $pop6 +; CHECK-NEXT: return $pop7 + %a = call i1 @llvm.is.fpclass.f64(double %x, i32 8) + ret i1 %a +} + +define i1 @is_fpclass_f64_negsubnorm(double %x) { +; CHECK-LABEL: is_fpclass_f64_negsubnorm: +; CHECK: .functype is_fpclass_f64_negsubnorm (f64) -> (i32) +; CHECK-NEXT: .local i64, i64, i32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push9=, 0 +; CHECK-NEXT: i64.reinterpret_f64 $push8=, $pop9 +; CHECK-NEXT: local.set 1, $pop8 +; CHECK-NEXT: local.get $push11=, 1 +; CHECK-NEXT: i64.const $push0=, 9223372036854775807 +; CHECK-NEXT: i64.and $push10=, $pop11, $pop0 +; CHECK-NEXT: local.set 2, $pop10 +; CHECK-NEXT: local.get $push14=, 1 +; CHECK-NEXT: local.get $push13=, 2 +; CHECK-NEXT: i64.ne $push12=, $pop14, $pop13 +; CHECK-NEXT: local.set 3, $pop12 +; CHECK-NEXT: i32.const $push1=, 0 +; CHECK-NEXT: local.get $push16=, 3 +; CHECK-NEXT: local.get $push15=, 2 +; CHECK-NEXT: i64.const $push2=, 1 +; CHECK-NEXT: i64.sub $push3=, $pop15, $pop2 +; CHECK-NEXT: i64.const $push4=, 4503599627370495 +; CHECK-NEXT: i64.lt_u $push5=, $pop3, $pop4 +; CHECK-NEXT: i32.and $push6=, $pop16, $pop5 +; CHECK-NEXT: i32.or $push7=, $pop1, $pop6 +; CHECK-NEXT: return $pop7 + %a = call i1 @llvm.is.fpclass.f64(double %x, i32 16) + ret i1 %a +} + +define i1 @is_fpclass_f64_negzero(double %x) { +; CHECK-LABEL: is_fpclass_f64_negzero: +; CHECK: .functype is_fpclass_f64_negzero (f64) -> (i32) +; CHECK-NEXT: .local i64, i64 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 0 +; CHECK-NEXT: i64.reinterpret_f64 $push3=, $pop4 +; CHECK-NEXT: local.set 1, $pop3 +; CHECK-NEXT: i64.const $push5=, -9223372036854775808 +; CHECK-NEXT: local.set 2, $pop5 +; CHECK-NEXT: i32.const $push0=, 0 +; CHECK-NEXT: local.get $push7=, 1 +; CHECK-NEXT: local.get $push6=, 2 +; CHECK-NEXT: i64.eq $push1=, $pop7, $pop6 +; CHECK-NEXT: i32.or $push2=, $pop0, $pop1 +; CHECK-NEXT: return $pop2 + %a = call i1 @llvm.is.fpclass.f64(double %x, i32 32) + ret i1 %a +} + +define i1 @is_fpclass_f64_poszero(double %x) { +; CHECK-LABEL: is_fpclass_f64_poszero: +; CHECK: .functype is_fpclass_f64_poszero (f64) -> (i32) +; CHECK-NEXT: .local i64 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 0 +; CHECK-NEXT: i64.reinterpret_f64 $push3=, $pop4 +; CHECK-NEXT: local.set 1, $pop3 +; CHECK-NEXT: i32.const $push0=, 0 +; CHECK-NEXT: local.get $push5=, 1 +; CHECK-NEXT: i64.eqz $push1=, $pop5 +; CHECK-NEXT: i32.or $push2=, $pop0, $pop1 +; CHECK-NEXT: return $pop2 + %a = call i1 @llvm.is.fpclass.f64(double %x, i32 64) + ret i1 %a +} + +define i1 @is_fpclass_f64_possubnorm(double %x) { +; CHECK-LABEL: is_fpclass_f64_possubnorm: +; CHECK: .functype is_fpclass_f64_possubnorm (f64) -> (i32) +; CHECK-NEXT: .local i64 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push7=, 0 +; CHECK-NEXT: i64.reinterpret_f64 $push6=, $pop7 +; CHECK-NEXT: local.set 1, $pop6 +; CHECK-NEXT: i32.const $push0=, 0 +; CHECK-NEXT: local.get $push8=, 1 +; CHECK-NEXT: i64.const $push1=, 1 +; CHECK-NEXT: i64.sub $push2=, $pop8, $pop1 +; CHECK-NEXT: i64.const $push3=, 4503599627370495 +; CHECK-NEXT: i64.lt_u $push4=, $pop2, $pop3 +; CHECK-NEXT: i32.or $push5=, $pop0, $pop4 +; CHECK-NEXT: return $pop5 + %a = call i1 @llvm.is.fpclass.f64(double %x, i32 128) + ret i1 %a +} + +define i1 @is_fpclass_f64_posnormal(double %x) { +; CHECK-LABEL: is_fpclass_f64_posnormal: +; CHECK: .functype is_fpclass_f64_posnormal (f64) -> (i32) +; CHECK-NEXT: .local i64, i64, i32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push11=, 0 +; CHECK-NEXT: i64.reinterpret_f64 $push10=, $pop11 +; CHECK-NEXT: local.set 1, $pop10 +; CHECK-NEXT: local.get $push13=, 1 +; CHECK-NEXT: i64.const $push0=, 9223372036854775807 +; CHECK-NEXT: i64.and $push12=, $pop13, $pop0 +; CHECK-NEXT: local.set 2, $pop12 +; CHECK-NEXT: local.get $push16=, 1 +; CHECK-NEXT: local.get $push15=, 2 +; CHECK-NEXT: i64.ne $push14=, $pop16, $pop15 +; CHECK-NEXT: local.set 3, $pop14 +; CHECK-NEXT: i32.const $push1=, 0 +; CHECK-NEXT: local.get $push17=, 2 +; CHECK-NEXT: i64.const $push2=, 4503599627370496 +; CHECK-NEXT: i64.sub $push3=, $pop17, $pop2 +; CHECK-NEXT: i64.const $push4=, 9214364837600034816 +; CHECK-NEXT: i64.lt_u $push5=, $pop3, $pop4 +; CHECK-NEXT: local.get $push18=, 3 +; CHECK-NEXT: i32.const $push6=, -1 +; CHECK-NEXT: i32.xor $push7=, $pop18, $pop6 +; CHECK-NEXT: i32.and $push8=, $pop5, $pop7 +; CHECK-NEXT: i32.or $push9=, $pop1, $pop8 +; CHECK-NEXT: return $pop9 + %a = call i1 @llvm.is.fpclass.f64(double %x, i32 256) + ret i1 %a +} + +define i1 @is_fpclass_f64_posinf(double %x) { +; CHECK-LABEL: is_fpclass_f64_posinf: +; CHECK: .functype is_fpclass_f64_posinf (f64) -> (i32) +; CHECK-NEXT: .local i64, i64 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get $push4=, 0 +; CHECK-NEXT: i64.reinterpret_f64 $push3=, $pop4 +; CHECK-NEXT: local.set 1, $pop3 +; CHECK-NEXT: i64.const $push5=, 9218868437227405312 +; CHECK-NEXT: local.set 2, $pop5 +; CHECK-NEXT: i32.const $push0=, 0 +; CHECK-NEXT: local.get $push7=, 1 +; CHECK-NEXT: local.get $push6=, 2 +; CHECK-NEXT: i64.eq $push1=, $pop7, $pop6 +; CHECK-NEXT: i32.or $push2=, $pop0, $pop1 +; CHECK-NEXT: return $pop2 + %a = call i1 @llvm.is.fpclass.f64(double %x, i32 512) + ret i1 %a +} _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
