diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -114,6 +114,8 @@ // float to single-width float, rounding towards odd). Takes a double-width // float vector and produces a single-width float vector. VFNCVT_ROD, + // A type-legalized version of the built-in FCOPYSIGN node. + VFCOPYSIGN, }; } // namespace RISCVISD @@ -315,6 +317,7 @@ SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const; bool isEligibleForTailCallOptimization( CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF, diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -448,6 +448,9 @@ // Expand various condition codes (explained above). for (auto CC : VFPCCToExpand) setCondCodeAction(CC, VT, Expand); + // Vector fcopysign operations are legal, but both operand value types + // must be the same. Custom-lower to achieve this. + setOperationAction(ISD::FCOPYSIGN, VT, Custom); }; if (Subtarget.hasStdExtZfh()) @@ -893,6 +896,8 @@ return Op; } + case ISD::FCOPYSIGN: + return lowerFCOPYSIGN(Op, DAG); } } @@ -1606,6 +1611,24 @@ } } +// FCOPYSIGN nodes may have a "sign" operand of a different type than the other +// operand. Since the RVV ISA doesn't permit this, we custom-lower FCOPYSIGN +// nodes to a target-specific version once the types have been matched. +SDValue RISCVTargetLowering::lowerFCOPYSIGN(SDValue Op, + SelectionDAG &DAG) const { + EVT VT = Op.getValueType(); + SDLoc DL(Op); + + SDValue In2 = Op.getOperand(1); + EVT SrcVT = In2.getValueType(); + + if (!SrcVT.bitsEq(VT)) + In2 = DAG.getFPExtendOrRound(In2, DL, VT); + + // Return a custom node to prevent infinite DAGCombien loops + return DAG.getNode(RISCVISD::VFCOPYSIGN, DL, VT, Op.getOperand(0), In2); +} + // Returns the opcode of the target-specific SDNode that implements the 32-bit // form of the given Opcode. static RISCVISD::NodeType getRISCVWOpcode(unsigned Opcode) { @@ -4151,6 +4174,7 @@ NODE_NAME_CASE(VSLIDEDOWN) NODE_NAME_CASE(VID) NODE_NAME_CASE(VFNCVT_ROD) + NODE_NAME_CASE(VFCOPYSIGN) } // clang-format on return nullptr; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td @@ -511,6 +511,8 @@ : SDNode<"RISCVISD::VFNCVT_ROD", SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVec<1>]>, []>; +def riscv_vfcopysign : SDNode<"RISCVISD::VFCOPYSIGN", SDTFPBinOp, []>; + let Predicates = [HasStdExtV, HasStdExtF] in { // 14.2. Vector Single-Width Floating-Point Add/Subtract Instructions @@ -591,11 +593,31 @@ (!cast("PseudoVFSQRT_V_"# vti.LMul.MX) vti.RegClass:$rs2, vti.AVL, vti.SEW)>; - // 14.10. Vector Floating-Point Sign-Injection Instructions + // 14.12. Vector Floating-Point Sign-Injection Instructions + def : Pat<(fabs (vti.Vector vti.RegClass:$rs)), + (!cast("PseudoVFSGNJX_VV_"# vti.LMul.MX) + vti.RegClass:$rs, vti.RegClass:$rs, vti.AVL, vti.SEW)>; // Handle fneg with VFSGNJN using the same input for both operands. def : Pat<(fneg (vti.Vector vti.RegClass:$rs)), (!cast("PseudoVFSGNJN_VV_"# vti.LMul.MX) vti.RegClass:$rs, vti.RegClass:$rs, vti.AVL, vti.SEW)>; + + def : Pat<(vti.Vector (riscv_vfcopysign vti.RegClass:$rs1, vti.RegClass:$rs2)), + (!cast("PseudoVFSGNJ_VV_"# vti.LMul.MX) + vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.SEW)>; + def : Pat<(vti.Vector (riscv_vfcopysign vti.RegClass:$rs1, + (splat_vector vti.ScalarRegClass:$rs2))), + (!cast("PseudoVFSGNJ_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) + vti.RegClass:$rs1, vti.ScalarRegClass:$rs2, vti.AVL, vti.SEW)>; + + def : Pat<(vti.Vector (riscv_vfcopysign vti.RegClass:$rs1, + (fneg vti.RegClass:$rs2))), + (!cast("PseudoVFSGNJN_VV_"# vti.LMul.MX) + vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.SEW)>; + def : Pat<(vti.Vector (riscv_vfcopysign vti.RegClass:$rs1, + (fneg (splat_vector vti.ScalarRegClass:$rs2)))), + (!cast("PseudoVFSGNJN_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) + vti.RegClass:$rs1, vti.ScalarRegClass:$rs2, vti.AVL, vti.SEW)>; } // 14.11. Vector Floating-Point Compare Instructions diff --git a/llvm/test/CodeGen/RISCV/rvv/vfabs-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfabs-sdnode.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/vfabs-sdnode.ll @@ -0,0 +1,185 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+d,+experimental-zfh,+experimental-v -target-abi=ilp32d \ +; RUN: -verify-machineinstrs < %s | FileCheck %s +; RUN: llc -mtriple=riscv64 -mattr=+d,+experimental-zfh,+experimental-v -target-abi=lp64d \ +; RUN: -verify-machineinstrs < %s | FileCheck %s + +declare @llvm.fabs.nxv1f16() + +define @vfabs_nxv1f16( %v) { +; CHECK-LABEL: vfabs_nxv1f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfsgnjx.vv v8, v8, v8 +; CHECK-NEXT: ret + %r = call @llvm.fabs.nxv1f16( %v) + ret %r +} + +declare @llvm.fabs.nxv2f16() + +define @vfabs_nxv2f16( %v) { +; CHECK-LABEL: vfabs_nxv2f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf2,ta,mu +; CHECK-NEXT: vfsgnjx.vv v8, v8, v8 +; CHECK-NEXT: ret + %r = call @llvm.fabs.nxv2f16( %v) + ret %r +} + +declare @llvm.fabs.nxv4f16() + +define @vfabs_nxv4f16( %v) { +; CHECK-LABEL: vfabs_nxv4f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m1,ta,mu +; CHECK-NEXT: vfsgnjx.vv v8, v8, v8 +; CHECK-NEXT: ret + %r = call @llvm.fabs.nxv4f16( %v) + ret %r +} + +declare @llvm.fabs.nxv8f16() + +define @vfabs_nxv8f16( %v) { +; CHECK-LABEL: vfabs_nxv8f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfsgnjx.vv v8, v8, v8 +; CHECK-NEXT: ret + %r = call @llvm.fabs.nxv8f16( %v) + ret %r +} + +declare @llvm.fabs.nxv16f16() + +define @vfabs_nxv16f16( %v) { +; CHECK-LABEL: vfabs_nxv16f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m4,ta,mu +; CHECK-NEXT: vfsgnjx.vv v8, v8, v8 +; CHECK-NEXT: ret + %r = call @llvm.fabs.nxv16f16( %v) + ret %r +} + +declare @llvm.fabs.nxv32f16() + +define @vfabs_nxv32f16( %v) { +; CHECK-LABEL: vfabs_nxv32f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m8,ta,mu +; CHECK-NEXT: vfsgnjx.vv v8, v8, v8 +; CHECK-NEXT: ret + %r = call @llvm.fabs.nxv32f16( %v) + ret %r +} + +declare @llvm.fabs.nxv1f32() + +define @vfabs_nxv1f32( %v) { +; CHECK-LABEL: vfabs_nxv1f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfsgnjx.vv v8, v8, v8 +; CHECK-NEXT: ret + %r = call @llvm.fabs.nxv1f32( %v) + ret %r +} + +declare @llvm.fabs.nxv2f32() + +define @vfabs_nxv2f32( %v) { +; CHECK-LABEL: vfabs_nxv2f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m1,ta,mu +; CHECK-NEXT: vfsgnjx.vv v8, v8, v8 +; CHECK-NEXT: ret + %r = call @llvm.fabs.nxv2f32( %v) + ret %r +} + +declare @llvm.fabs.nxv4f32() + +define @vfabs_nxv4f32( %v) { +; CHECK-LABEL: vfabs_nxv4f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m2,ta,mu +; CHECK-NEXT: vfsgnjx.vv v8, v8, v8 +; CHECK-NEXT: ret + %r = call @llvm.fabs.nxv4f32( %v) + ret %r +} + +declare @llvm.fabs.nxv8f32() + +define @vfabs_nxv8f32( %v) { +; CHECK-LABEL: vfabs_nxv8f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfsgnjx.vv v8, v8, v8 +; CHECK-NEXT: ret + %r = call @llvm.fabs.nxv8f32( %v) + ret %r +} + +declare @llvm.fabs.nxv16f32() + +define @vfabs_nxv16f32( %v) { +; CHECK-LABEL: vfabs_nxv16f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m8,ta,mu +; CHECK-NEXT: vfsgnjx.vv v8, v8, v8 +; CHECK-NEXT: ret + %r = call @llvm.fabs.nxv16f32( %v) + ret %r +} + +declare @llvm.fabs.nxv1f64() + +define @vfabs_nxv1f64( %v) { +; CHECK-LABEL: vfabs_nxv1f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfsgnjx.vv v8, v8, v8 +; CHECK-NEXT: ret + %r = call @llvm.fabs.nxv1f64( %v) + ret %r +} + +declare @llvm.fabs.nxv2f64() + +define @vfabs_nxv2f64( %v) { +; CHECK-LABEL: vfabs_nxv2f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m2,ta,mu +; CHECK-NEXT: vfsgnjx.vv v8, v8, v8 +; CHECK-NEXT: ret + %r = call @llvm.fabs.nxv2f64( %v) + ret %r +} + +declare @llvm.fabs.nxv4f64() + +define @vfabs_nxv4f64( %v) { +; CHECK-LABEL: vfabs_nxv4f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m4,ta,mu +; CHECK-NEXT: vfsgnjx.vv v8, v8, v8 +; CHECK-NEXT: ret + %r = call @llvm.fabs.nxv4f64( %v) + ret %r +} + +declare @llvm.fabs.nxv8f64() + +define @vfabs_nxv8f64( %v) { +; CHECK-LABEL: vfabs_nxv8f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfsgnjx.vv v8, v8, v8 +; CHECK-NEXT: ret + %r = call @llvm.fabs.nxv8f64( %v) + ret %r +} diff --git a/llvm/test/CodeGen/RISCV/rvv/vfcopysign-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfcopysign-sdnode.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/vfcopysign-sdnode.ll @@ -0,0 +1,1495 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+d,+experimental-zfh,+experimental-v -target-abi=ilp32d \ +; RUN: -verify-machineinstrs < %s | FileCheck %s +; RUN: llc -mtriple=riscv64 -mattr=+d,+experimental-zfh,+experimental-v -target-abi=lp64d \ +; RUN: -verify-machineinstrs < %s | FileCheck %s + +declare @llvm.copysign.nxv1f16(, ) + +define @vfcopysign_vv_nxv1f16( %vm, %vs) { +; CHECK-LABEL: vfcopysign_vv_nxv1f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v9 +; CHECK-NEXT: ret + %r = call @llvm.copysign.nxv1f16( %vm, %vs) + ret %r +} + +define @vfcopysign_vf_nxv1f16( %vm, half %s) { +; CHECK-LABEL: vfcopysign_vf_nxv1f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfsgnj.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %r = call @llvm.copysign.nxv1f16( %vm, %splat) + ret %r +} + +define @vfcopynsign_vv_nxv1f16( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_vv_nxv1f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfsgnjn.vv v8, v8, v9 +; CHECK-NEXT: ret + %n = fneg %vs + %r = call @llvm.copysign.nxv1f16( %vm, %n) + ret %r +} + +define @vfcopynsign_vf_nxv1f16( %vm, half %s) { +; CHECK-LABEL: vfcopynsign_vf_nxv1f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfsgnjn.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %r = call @llvm.copysign.nxv1f16( %vm, %n) + ret %r +} + +define @vfcopysign_exttrunc_vv_nxv1f16_nxv1f32( %vm, %vs) { +; CHECK-LABEL: vfcopysign_exttrunc_vv_nxv1f16_nxv1f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v25, v9 +; CHECK-NEXT: vfsgnj.vv v8, v8, v25 +; CHECK-NEXT: ret + %e = fptrunc %vs to + %r = call @llvm.copysign.nxv1f16( %vm, %e) + ret %r +} + +define @vfcopysign_exttrunc_vf_nxv1f16_nxv1f32( %vm, float %s) { +; CHECK-LABEL: vfcopysign_exttrunc_vf_nxv1f16_nxv1f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfmv.v.f v25, fa0 +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v26, v25 +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %esplat = fptrunc %splat to + %r = call @llvm.copysign.nxv1f16( %vm, %esplat) + ret %r +} + +define @vfcopynsign_exttrunc_vv_nxv1f16_nxv1f32( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_exttrunc_vv_nxv1f16_nxv1f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfsgnjn.vv v25, v9, v9 +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v26, v25 +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %n = fneg %vs + %eneg = fptrunc %n to + %r = call @llvm.copysign.nxv1f16( %vm, %eneg) + ret %r +} + +define @vfcopynsign_exttrunc_vf_nxv1f16_nxv1f32( %vm, float %s) { +; CHECK-LABEL: vfcopynsign_exttrunc_vf_nxv1f16_nxv1f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfmv.v.f v25, fa0 +; CHECK-NEXT: vfsgnjn.vv v25, v25, v25 +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v26, v25 +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %eneg = fptrunc %n to + %r = call @llvm.copysign.nxv1f16( %vm, %eneg) + ret %r +} + +define @vfcopysign_exttrunc_vv_nxv1f16_nxv1f64( %vm, %vs) { +; CHECK-LABEL: vfcopysign_exttrunc_vv_nxv1f16_nxv1f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfncvt.rod.f.f.w v25, v9 +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v26, v25 +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %e = fptrunc %vs to + %r = call @llvm.copysign.nxv1f16( %vm, %e) + ret %r +} + +define @vfcopysign_exttrunc_vf_nxv1f16_nxv1f64( %vm, double %s) { +; CHECK-LABEL: vfcopysign_exttrunc_vf_nxv1f16_nxv1f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfmv.v.f v25, fa0 +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfncvt.rod.f.f.w v26, v25 +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v25, v26 +; CHECK-NEXT: vfsgnj.vv v8, v8, v25 +; CHECK-NEXT: ret + %head = insertelement undef, double %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %esplat = fptrunc %splat to + %r = call @llvm.copysign.nxv1f16( %vm, %esplat) + ret %r +} + +define @vfcopynsign_exttrunc_vv_nxv1f16_nxv1f64( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_exttrunc_vv_nxv1f16_nxv1f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfsgnjn.vv v25, v9, v9 +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfncvt.rod.f.f.w v26, v25 +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v25, v26 +; CHECK-NEXT: vfsgnj.vv v8, v8, v25 +; CHECK-NEXT: ret + %n = fneg %vs + %eneg = fptrunc %n to + %r = call @llvm.copysign.nxv1f16( %vm, %eneg) + ret %r +} + +define @vfcopynsign_exttrunc_vf_nxv1f16_nxv1f64( %vm, double %s) { +; CHECK-LABEL: vfcopynsign_exttrunc_vf_nxv1f16_nxv1f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfmv.v.f v25, fa0 +; CHECK-NEXT: vfsgnjn.vv v25, v25, v25 +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfncvt.rod.f.f.w v26, v25 +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v25, v26 +; CHECK-NEXT: vfsgnj.vv v8, v8, v25 +; CHECK-NEXT: ret + %head = insertelement undef, double %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %eneg = fptrunc %n to + %r = call @llvm.copysign.nxv1f16( %vm, %eneg) + ret %r +} + +declare @llvm.copysign.nxv2f16(, ) + +define @vfcopysign_vv_nxv2f16( %vm, %vs) { +; CHECK-LABEL: vfcopysign_vv_nxv2f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf2,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v9 +; CHECK-NEXT: ret + %r = call @llvm.copysign.nxv2f16( %vm, %vs) + ret %r +} + +define @vfcopysign_vf_nxv2f16( %vm, half %s) { +; CHECK-LABEL: vfcopysign_vf_nxv2f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf2,ta,mu +; CHECK-NEXT: vfsgnj.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %r = call @llvm.copysign.nxv2f16( %vm, %splat) + ret %r +} + +define @vfcopynsign_vv_nxv2f16( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_vv_nxv2f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf2,ta,mu +; CHECK-NEXT: vfsgnjn.vv v8, v8, v9 +; CHECK-NEXT: ret + %n = fneg %vs + %r = call @llvm.copysign.nxv2f16( %vm, %n) + ret %r +} + +define @vfcopynsign_vf_nxv2f16( %vm, half %s) { +; CHECK-LABEL: vfcopynsign_vf_nxv2f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf2,ta,mu +; CHECK-NEXT: vfsgnjn.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %r = call @llvm.copysign.nxv2f16( %vm, %n) + ret %r +} + +declare @llvm.copysign.nxv4f16(, ) + +define @vfcopysign_vv_nxv4f16( %vm, %vs) { +; CHECK-LABEL: vfcopysign_vv_nxv4f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m1,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v9 +; CHECK-NEXT: ret + %r = call @llvm.copysign.nxv4f16( %vm, %vs) + ret %r +} + +define @vfcopysign_vf_nxv4f16( %vm, half %s) { +; CHECK-LABEL: vfcopysign_vf_nxv4f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m1,ta,mu +; CHECK-NEXT: vfsgnj.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %r = call @llvm.copysign.nxv4f16( %vm, %splat) + ret %r +} + +define @vfcopynsign_vv_nxv4f16( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_vv_nxv4f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m1,ta,mu +; CHECK-NEXT: vfsgnjn.vv v8, v8, v9 +; CHECK-NEXT: ret + %n = fneg %vs + %r = call @llvm.copysign.nxv4f16( %vm, %n) + ret %r +} + +define @vfcopynsign_vf_nxv4f16( %vm, half %s) { +; CHECK-LABEL: vfcopynsign_vf_nxv4f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m1,ta,mu +; CHECK-NEXT: vfsgnjn.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %r = call @llvm.copysign.nxv4f16( %vm, %n) + ret %r +} + +declare @llvm.copysign.nxv8f16(, ) + +define @vfcopysign_vv_nxv8f16( %vm, %vs) { +; CHECK-LABEL: vfcopysign_vv_nxv8f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v10 +; CHECK-NEXT: ret + %r = call @llvm.copysign.nxv8f16( %vm, %vs) + ret %r +} + +define @vfcopysign_vf_nxv8f16( %vm, half %s) { +; CHECK-LABEL: vfcopysign_vf_nxv8f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfsgnj.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %r = call @llvm.copysign.nxv8f16( %vm, %splat) + ret %r +} + +define @vfcopynsign_vv_nxv8f16( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_vv_nxv8f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfsgnjn.vv v8, v8, v10 +; CHECK-NEXT: ret + %n = fneg %vs + %r = call @llvm.copysign.nxv8f16( %vm, %n) + ret %r +} + +define @vfcopynsign_vf_nxv8f16( %vm, half %s) { +; CHECK-LABEL: vfcopynsign_vf_nxv8f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfsgnjn.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %r = call @llvm.copysign.nxv8f16( %vm, %n) + ret %r +} + +define @vfcopysign_exttrunc_vv_nxv8f16_nxv8f32( %vm, %vs) { +; CHECK-LABEL: vfcopysign_exttrunc_vv_nxv8f16_nxv8f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v26, v12 +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %e = fptrunc %vs to + %r = call @llvm.copysign.nxv8f16( %vm, %e) + ret %r +} + +define @vfcopysign_exttrunc_vf_nxv8f16_nxv8f32( %vm, float %s) { +; CHECK-LABEL: vfcopysign_exttrunc_vf_nxv8f16_nxv8f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfmv.v.f v28, fa0 +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v26, v28 +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %esplat = fptrunc %splat to + %r = call @llvm.copysign.nxv8f16( %vm, %esplat) + ret %r +} + +define @vfcopynsign_exttrunc_vv_nxv8f16_nxv8f32( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_exttrunc_vv_nxv8f16_nxv8f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfsgnjn.vv v28, v12, v12 +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v26, v28 +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %n = fneg %vs + %eneg = fptrunc %n to + %r = call @llvm.copysign.nxv8f16( %vm, %eneg) + ret %r +} + +define @vfcopynsign_exttrunc_vf_nxv8f16_nxv8f32( %vm, float %s) { +; CHECK-LABEL: vfcopynsign_exttrunc_vf_nxv8f16_nxv8f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfmv.v.f v28, fa0 +; CHECK-NEXT: vfsgnjn.vv v28, v28, v28 +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v26, v28 +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %eneg = fptrunc %n to + %r = call @llvm.copysign.nxv8f16( %vm, %eneg) + ret %r +} + +define @vfcopysign_exttrunc_vv_nxv8f16_nxv8f64( %vm, %vs) { +; CHECK-LABEL: vfcopysign_exttrunc_vv_nxv8f16_nxv8f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfncvt.rod.f.f.w v28, v16 +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v26, v28 +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %e = fptrunc %vs to + %r = call @llvm.copysign.nxv8f16( %vm, %e) + ret %r +} + +define @vfcopysign_exttrunc_vf_nxv8f16_nxv8f64( %vm, double %s) { +; CHECK-LABEL: vfcopysign_exttrunc_vf_nxv8f16_nxv8f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfmv.v.f v16, fa0 +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfncvt.rod.f.f.w v28, v16 +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v26, v28 +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %head = insertelement undef, double %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %esplat = fptrunc %splat to + %r = call @llvm.copysign.nxv8f16( %vm, %esplat) + ret %r +} + +define @vfcopynsign_exttrunc_vv_nxv8f16_nxv8f64( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_exttrunc_vv_nxv8f16_nxv8f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfsgnjn.vv v16, v16, v16 +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfncvt.rod.f.f.w v28, v16 +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v26, v28 +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %n = fneg %vs + %eneg = fptrunc %n to + %r = call @llvm.copysign.nxv8f16( %vm, %eneg) + ret %r +} + +define @vfcopynsign_exttrunc_vf_nxv8f16_nxv8f64( %vm, double %s) { +; CHECK-LABEL: vfcopynsign_exttrunc_vf_nxv8f16_nxv8f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfmv.v.f v16, fa0 +; CHECK-NEXT: vfsgnjn.vv v16, v16, v16 +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfncvt.rod.f.f.w v28, v16 +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v26, v28 +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %head = insertelement undef, double %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %eneg = fptrunc %n to + %r = call @llvm.copysign.nxv8f16( %vm, %eneg) + ret %r +} + +declare @llvm.copysign.nxv16f16(, ) + +define @vfcopysign_vv_nxv16f16( %vm, %vs) { +; CHECK-LABEL: vfcopysign_vv_nxv16f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m4,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v12 +; CHECK-NEXT: ret + %r = call @llvm.copysign.nxv16f16( %vm, %vs) + ret %r +} + +define @vfcopysign_vf_nxv16f16( %vm, half %s) { +; CHECK-LABEL: vfcopysign_vf_nxv16f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m4,ta,mu +; CHECK-NEXT: vfsgnj.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %r = call @llvm.copysign.nxv16f16( %vm, %splat) + ret %r +} + +define @vfcopynsign_vv_nxv16f16( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_vv_nxv16f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m4,ta,mu +; CHECK-NEXT: vfsgnjn.vv v8, v8, v12 +; CHECK-NEXT: ret + %n = fneg %vs + %r = call @llvm.copysign.nxv16f16( %vm, %n) + ret %r +} + +define @vfcopynsign_vf_nxv16f16( %vm, half %s) { +; CHECK-LABEL: vfcopynsign_vf_nxv16f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m4,ta,mu +; CHECK-NEXT: vfsgnjn.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %r = call @llvm.copysign.nxv16f16( %vm, %n) + ret %r +} + +declare @llvm.copysign.nxv32f16(, ) + +define @vfcopysign_vv_nxv32f16( %vm, %vs) { +; CHECK-LABEL: vfcopysign_vv_nxv32f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m8,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v16 +; CHECK-NEXT: ret + %r = call @llvm.copysign.nxv32f16( %vm, %vs) + ret %r +} + +define @vfcopysign_vf_nxv32f16( %vm, half %s) { +; CHECK-LABEL: vfcopysign_vf_nxv32f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m8,ta,mu +; CHECK-NEXT: vfsgnj.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %r = call @llvm.copysign.nxv32f16( %vm, %splat) + ret %r +} + +define @vfcopynsign_vv_nxv32f16( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_vv_nxv32f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m8,ta,mu +; CHECK-NEXT: vfsgnjn.vv v8, v8, v16 +; CHECK-NEXT: ret + %n = fneg %vs + %r = call @llvm.copysign.nxv32f16( %vm, %n) + ret %r +} + +define @vfcopynsign_vf_nxv32f16( %vm, half %s) { +; CHECK-LABEL: vfcopynsign_vf_nxv32f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m8,ta,mu +; CHECK-NEXT: vfsgnjn.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %r = call @llvm.copysign.nxv32f16( %vm, %n) + ret %r +} + +declare @llvm.copysign.nxv1f32(, ) + +define @vfcopysign_vv_nxv1f32( %vm, %vs) { +; CHECK-LABEL: vfcopysign_vv_nxv1f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v9 +; CHECK-NEXT: ret + %r = call @llvm.copysign.nxv1f32( %vm, %vs) + ret %r +} + +define @vfcopysign_vf_nxv1f32( %vm, float %s) { +; CHECK-LABEL: vfcopysign_vf_nxv1f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfsgnj.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %r = call @llvm.copysign.nxv1f32( %vm, %splat) + ret %r +} + +define @vfcopynsign_vv_nxv1f32( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_vv_nxv1f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfsgnjn.vv v8, v8, v9 +; CHECK-NEXT: ret + %n = fneg %vs + %r = call @llvm.copysign.nxv1f32( %vm, %n) + ret %r +} + +define @vfcopynsign_vf_nxv1f32( %vm, float %s) { +; CHECK-LABEL: vfcopynsign_vf_nxv1f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfsgnjn.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %r = call @llvm.copysign.nxv1f32( %vm, %n) + ret %r +} + +define @vfcopysign_exttrunc_vv_nxv1f32_nxv1f16( %vm, %vs) { +; CHECK-LABEL: vfcopysign_exttrunc_vv_nxv1f32_nxv1f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfwcvt.f.f.v v25, v9 +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v25 +; CHECK-NEXT: ret + %e = fpext %vs to + %r = call @llvm.copysign.nxv1f32( %vm, %e) + ret %r +} + +define @vfcopysign_exttrunc_vf_nxv1f32_nxv1f16( %vm, half %s) { +; CHECK-LABEL: vfcopysign_exttrunc_vf_nxv1f32_nxv1f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfmv.v.f v25, fa0 +; CHECK-NEXT: vfwcvt.f.f.v v26, v25 +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %esplat = fpext %splat to + %r = call @llvm.copysign.nxv1f32( %vm, %esplat) + ret %r +} + +define @vfcopynsign_exttrunc_vv_nxv1f32_nxv1f16( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_exttrunc_vv_nxv1f32_nxv1f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfsgnjn.vv v25, v9, v9 +; CHECK-NEXT: vfwcvt.f.f.v v26, v25 +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %n = fneg %vs + %eneg = fpext %n to + %r = call @llvm.copysign.nxv1f32( %vm, %eneg) + ret %r +} + +define @vfcopynsign_exttrunc_vf_nxv1f32_nxv1f16( %vm, half %s) { +; CHECK-LABEL: vfcopynsign_exttrunc_vf_nxv1f32_nxv1f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfmv.v.f v25, fa0 +; CHECK-NEXT: vfsgnjn.vv v25, v25, v25 +; CHECK-NEXT: vfwcvt.f.f.v v26, v25 +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %eneg = fpext %n to + %r = call @llvm.copysign.nxv1f32( %vm, %eneg) + ret %r +} + +define @vfcopysign_exttrunc_vv_nxv1f32_nxv1f64( %vm, %vs) { +; CHECK-LABEL: vfcopysign_exttrunc_vv_nxv1f32_nxv1f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v25, v9 +; CHECK-NEXT: vfsgnj.vv v8, v8, v25 +; CHECK-NEXT: ret + %e = fptrunc %vs to + %r = call @llvm.copysign.nxv1f32( %vm, %e) + ret %r +} + +define @vfcopysign_exttrunc_vf_nxv1f32_nxv1f64( %vm, double %s) { +; CHECK-LABEL: vfcopysign_exttrunc_vf_nxv1f32_nxv1f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfmv.v.f v25, fa0 +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v26, v25 +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %head = insertelement undef, double %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %esplat = fptrunc %splat to + %r = call @llvm.copysign.nxv1f32( %vm, %esplat) + ret %r +} + +define @vfcopynsign_exttrunc_vv_nxv1f32_nxv1f64( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_exttrunc_vv_nxv1f32_nxv1f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfsgnjn.vv v25, v9, v9 +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v26, v25 +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %n = fneg %vs + %eneg = fptrunc %n to + %r = call @llvm.copysign.nxv1f32( %vm, %eneg) + ret %r +} + +define @vfcopynsign_exttrunc_vf_nxv1f32_nxv1f64( %vm, double %s) { +; CHECK-LABEL: vfcopynsign_exttrunc_vf_nxv1f32_nxv1f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfmv.v.f v25, fa0 +; CHECK-NEXT: vfsgnjn.vv v25, v25, v25 +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v26, v25 +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %head = insertelement undef, double %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %eneg = fptrunc %n to + %r = call @llvm.copysign.nxv1f32( %vm, %eneg) + ret %r +} + +declare @llvm.copysign.nxv2f32(, ) + +define @vfcopysign_vv_nxv2f32( %vm, %vs) { +; CHECK-LABEL: vfcopysign_vv_nxv2f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m1,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v9 +; CHECK-NEXT: ret + %r = call @llvm.copysign.nxv2f32( %vm, %vs) + ret %r +} + +define @vfcopysign_vf_nxv2f32( %vm, float %s) { +; CHECK-LABEL: vfcopysign_vf_nxv2f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m1,ta,mu +; CHECK-NEXT: vfsgnj.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %r = call @llvm.copysign.nxv2f32( %vm, %splat) + ret %r +} + +define @vfcopynsign_vv_nxv2f32( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_vv_nxv2f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m1,ta,mu +; CHECK-NEXT: vfsgnjn.vv v8, v8, v9 +; CHECK-NEXT: ret + %n = fneg %vs + %r = call @llvm.copysign.nxv2f32( %vm, %n) + ret %r +} + +define @vfcopynsign_vf_nxv2f32( %vm, float %s) { +; CHECK-LABEL: vfcopynsign_vf_nxv2f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m1,ta,mu +; CHECK-NEXT: vfsgnjn.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %r = call @llvm.copysign.nxv2f32( %vm, %n) + ret %r +} + +declare @llvm.copysign.nxv4f32(, ) + +define @vfcopysign_vv_nxv4f32( %vm, %vs) { +; CHECK-LABEL: vfcopysign_vv_nxv4f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m2,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v10 +; CHECK-NEXT: ret + %r = call @llvm.copysign.nxv4f32( %vm, %vs) + ret %r +} + +define @vfcopysign_vf_nxv4f32( %vm, float %s) { +; CHECK-LABEL: vfcopysign_vf_nxv4f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m2,ta,mu +; CHECK-NEXT: vfsgnj.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %r = call @llvm.copysign.nxv4f32( %vm, %splat) + ret %r +} + +define @vfcopynsign_vv_nxv4f32( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_vv_nxv4f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m2,ta,mu +; CHECK-NEXT: vfsgnjn.vv v8, v8, v10 +; CHECK-NEXT: ret + %n = fneg %vs + %r = call @llvm.copysign.nxv4f32( %vm, %n) + ret %r +} + +define @vfcopynsign_vf_nxv4f32( %vm, float %s) { +; CHECK-LABEL: vfcopynsign_vf_nxv4f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m2,ta,mu +; CHECK-NEXT: vfsgnjn.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %r = call @llvm.copysign.nxv4f32( %vm, %n) + ret %r +} + +declare @llvm.copysign.nxv8f32(, ) + +define @vfcopysign_vv_nxv8f32( %vm, %vs) { +; CHECK-LABEL: vfcopysign_vv_nxv8f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v12 +; CHECK-NEXT: ret + %r = call @llvm.copysign.nxv8f32( %vm, %vs) + ret %r +} + +define @vfcopysign_vf_nxv8f32( %vm, float %s) { +; CHECK-LABEL: vfcopysign_vf_nxv8f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfsgnj.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %r = call @llvm.copysign.nxv8f32( %vm, %splat) + ret %r +} + +define @vfcopynsign_vv_nxv8f32( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_vv_nxv8f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfsgnjn.vv v8, v8, v12 +; CHECK-NEXT: ret + %n = fneg %vs + %r = call @llvm.copysign.nxv8f32( %vm, %n) + ret %r +} + +define @vfcopynsign_vf_nxv8f32( %vm, float %s) { +; CHECK-LABEL: vfcopynsign_vf_nxv8f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfsgnjn.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %r = call @llvm.copysign.nxv8f32( %vm, %n) + ret %r +} + +define @vfcopysign_exttrunc_vv_nxv8f32_nxv8f16( %vm, %vs) { +; CHECK-LABEL: vfcopysign_exttrunc_vv_nxv8f32_nxv8f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfwcvt.f.f.v v28, v12 +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v28 +; CHECK-NEXT: ret + %e = fpext %vs to + %r = call @llvm.copysign.nxv8f32( %vm, %e) + ret %r +} + +define @vfcopysign_exttrunc_vf_nxv8f32_nxv8f16( %vm, half %s) { +; CHECK-LABEL: vfcopysign_exttrunc_vf_nxv8f32_nxv8f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfmv.v.f v26, fa0 +; CHECK-NEXT: vfwcvt.f.f.v v28, v26 +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v28 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %esplat = fpext %splat to + %r = call @llvm.copysign.nxv8f32( %vm, %esplat) + ret %r +} + +define @vfcopynsign_exttrunc_vv_nxv8f32_nxv8f16( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_exttrunc_vv_nxv8f32_nxv8f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfsgnjn.vv v26, v12, v12 +; CHECK-NEXT: vfwcvt.f.f.v v28, v26 +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v28 +; CHECK-NEXT: ret + %n = fneg %vs + %eneg = fpext %n to + %r = call @llvm.copysign.nxv8f32( %vm, %eneg) + ret %r +} + +define @vfcopynsign_exttrunc_vf_nxv8f32_nxv8f16( %vm, half %s) { +; CHECK-LABEL: vfcopynsign_exttrunc_vf_nxv8f32_nxv8f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfmv.v.f v26, fa0 +; CHECK-NEXT: vfsgnjn.vv v26, v26, v26 +; CHECK-NEXT: vfwcvt.f.f.v v28, v26 +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v28 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %eneg = fpext %n to + %r = call @llvm.copysign.nxv8f32( %vm, %eneg) + ret %r +} + +define @vfcopysign_exttrunc_vv_nxv8f32_nxv8f64( %vm, %vs) { +; CHECK-LABEL: vfcopysign_exttrunc_vv_nxv8f32_nxv8f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v28, v16 +; CHECK-NEXT: vfsgnj.vv v8, v8, v28 +; CHECK-NEXT: ret + %e = fptrunc %vs to + %r = call @llvm.copysign.nxv8f32( %vm, %e) + ret %r +} + +define @vfcopysign_exttrunc_vf_nxv8f32_nxv8f64( %vm, double %s) { +; CHECK-LABEL: vfcopysign_exttrunc_vf_nxv8f32_nxv8f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfmv.v.f v16, fa0 +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v28, v16 +; CHECK-NEXT: vfsgnj.vv v8, v8, v28 +; CHECK-NEXT: ret + %head = insertelement undef, double %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %esplat = fptrunc %splat to + %r = call @llvm.copysign.nxv8f32( %vm, %esplat) + ret %r +} + +define @vfcopynsign_exttrunc_vv_nxv8f32_nxv8f64( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_exttrunc_vv_nxv8f32_nxv8f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfsgnjn.vv v16, v16, v16 +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v28, v16 +; CHECK-NEXT: vfsgnj.vv v8, v8, v28 +; CHECK-NEXT: ret + %n = fneg %vs + %eneg = fptrunc %n to + %r = call @llvm.copysign.nxv8f32( %vm, %eneg) + ret %r +} + +define @vfcopynsign_exttrunc_vf_nxv8f32_nxv8f64( %vm, double %s) { +; CHECK-LABEL: vfcopynsign_exttrunc_vf_nxv8f32_nxv8f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfmv.v.f v16, fa0 +; CHECK-NEXT: vfsgnjn.vv v16, v16, v16 +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfncvt.f.f.w v28, v16 +; CHECK-NEXT: vfsgnj.vv v8, v8, v28 +; CHECK-NEXT: ret + %head = insertelement undef, double %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %eneg = fptrunc %n to + %r = call @llvm.copysign.nxv8f32( %vm, %eneg) + ret %r +} + +declare @llvm.copysign.nxv16f32(, ) + +define @vfcopysign_vv_nxv16f32( %vm, %vs) { +; CHECK-LABEL: vfcopysign_vv_nxv16f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m8,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v16 +; CHECK-NEXT: ret + %r = call @llvm.copysign.nxv16f32( %vm, %vs) + ret %r +} + +define @vfcopysign_vf_nxv16f32( %vm, float %s) { +; CHECK-LABEL: vfcopysign_vf_nxv16f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m8,ta,mu +; CHECK-NEXT: vfsgnj.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %r = call @llvm.copysign.nxv16f32( %vm, %splat) + ret %r +} + +define @vfcopynsign_vv_nxv16f32( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_vv_nxv16f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m8,ta,mu +; CHECK-NEXT: vfsgnjn.vv v8, v8, v16 +; CHECK-NEXT: ret + %n = fneg %vs + %r = call @llvm.copysign.nxv16f32( %vm, %n) + ret %r +} + +define @vfcopynsign_vf_nxv16f32( %vm, float %s) { +; CHECK-LABEL: vfcopynsign_vf_nxv16f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m8,ta,mu +; CHECK-NEXT: vfsgnjn.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %r = call @llvm.copysign.nxv16f32( %vm, %n) + ret %r +} + +declare @llvm.copysign.nxv1f64(, ) + +define @vfcopysign_vv_nxv1f64( %vm, %vs) { +; CHECK-LABEL: vfcopysign_vv_nxv1f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v9 +; CHECK-NEXT: ret + %r = call @llvm.copysign.nxv1f64( %vm, %vs) + ret %r +} + +define @vfcopysign_vf_nxv1f64( %vm, double %s) { +; CHECK-LABEL: vfcopysign_vf_nxv1f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfsgnj.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, double %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %r = call @llvm.copysign.nxv1f64( %vm, %splat) + ret %r +} + +define @vfcopynsign_vv_nxv1f64( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_vv_nxv1f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfsgnjn.vv v8, v8, v9 +; CHECK-NEXT: ret + %n = fneg %vs + %r = call @llvm.copysign.nxv1f64( %vm, %n) + ret %r +} + +define @vfcopynsign_vf_nxv1f64( %vm, double %s) { +; CHECK-LABEL: vfcopynsign_vf_nxv1f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfsgnjn.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, double %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %r = call @llvm.copysign.nxv1f64( %vm, %n) + ret %r +} + +define @vfcopysign_exttrunc_vv_nxv1f64_nxv1f16( %vm, %vs) { +; CHECK-LABEL: vfcopysign_exttrunc_vv_nxv1f64_nxv1f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfwcvt.f.f.v v25, v9 +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfwcvt.f.f.v v26, v25 +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %e = fpext %vs to + %r = call @llvm.copysign.nxv1f64( %vm, %e) + ret %r +} + +define @vfcopysign_exttrunc_vf_nxv1f64_nxv1f16( %vm, half %s) { +; CHECK-LABEL: vfcopysign_exttrunc_vf_nxv1f64_nxv1f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfmv.v.f v25, fa0 +; CHECK-NEXT: vfwcvt.f.f.v v26, v25 +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfwcvt.f.f.v v25, v26 +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v25 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %esplat = fpext %splat to + %r = call @llvm.copysign.nxv1f64( %vm, %esplat) + ret %r +} + +define @vfcopynsign_exttrunc_vv_nxv1f64_nxv1f16( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_exttrunc_vv_nxv1f64_nxv1f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfsgnjn.vv v25, v9, v9 +; CHECK-NEXT: vfwcvt.f.f.v v26, v25 +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfwcvt.f.f.v v25, v26 +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v25 +; CHECK-NEXT: ret + %n = fneg %vs + %eneg = fpext %n to + %r = call @llvm.copysign.nxv1f64( %vm, %eneg) + ret %r +} + +define @vfcopynsign_exttrunc_vf_nxv1f64_nxv1f16( %vm, half %s) { +; CHECK-LABEL: vfcopynsign_exttrunc_vf_nxv1f64_nxv1f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,mf4,ta,mu +; CHECK-NEXT: vfmv.v.f v25, fa0 +; CHECK-NEXT: vfsgnjn.vv v25, v25, v25 +; CHECK-NEXT: vfwcvt.f.f.v v26, v25 +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfwcvt.f.f.v v25, v26 +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v25 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %eneg = fpext %n to + %r = call @llvm.copysign.nxv1f64( %vm, %eneg) + ret %r +} + +define @vfcopysign_exttrunc_vv_nxv1f64_nxv1f32( %vm, %vs) { +; CHECK-LABEL: vfcopysign_exttrunc_vv_nxv1f64_nxv1f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfwcvt.f.f.v v25, v9 +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v25 +; CHECK-NEXT: ret + %e = fpext %vs to + %r = call @llvm.copysign.nxv1f64( %vm, %e) + ret %r +} + +define @vfcopysign_exttrunc_vf_nxv1f64_nxv1f32( %vm, float %s) { +; CHECK-LABEL: vfcopysign_exttrunc_vf_nxv1f64_nxv1f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfmv.v.f v25, fa0 +; CHECK-NEXT: vfwcvt.f.f.v v26, v25 +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %esplat = fpext %splat to + %r = call @llvm.copysign.nxv1f64( %vm, %esplat) + ret %r +} + +define @vfcopynsign_exttrunc_vv_nxv1f64_nxv1f32( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_exttrunc_vv_nxv1f64_nxv1f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfsgnjn.vv v25, v9, v9 +; CHECK-NEXT: vfwcvt.f.f.v v26, v25 +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %n = fneg %vs + %eneg = fpext %n to + %r = call @llvm.copysign.nxv1f64( %vm, %eneg) + ret %r +} + +define @vfcopynsign_exttrunc_vf_nxv1f64_nxv1f32( %vm, float %s) { +; CHECK-LABEL: vfcopynsign_exttrunc_vf_nxv1f64_nxv1f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,mf2,ta,mu +; CHECK-NEXT: vfmv.v.f v25, fa0 +; CHECK-NEXT: vfsgnjn.vv v25, v25, v25 +; CHECK-NEXT: vfwcvt.f.f.v v26, v25 +; CHECK-NEXT: vsetvli a0, zero, e64,m1,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v26 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %eneg = fpext %n to + %r = call @llvm.copysign.nxv1f64( %vm, %eneg) + ret %r +} + +declare @llvm.copysign.nxv2f64(, ) + +define @vfcopysign_vv_nxv2f64( %vm, %vs) { +; CHECK-LABEL: vfcopysign_vv_nxv2f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m2,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v10 +; CHECK-NEXT: ret + %r = call @llvm.copysign.nxv2f64( %vm, %vs) + ret %r +} + +define @vfcopysign_vf_nxv2f64( %vm, double %s) { +; CHECK-LABEL: vfcopysign_vf_nxv2f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m2,ta,mu +; CHECK-NEXT: vfsgnj.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, double %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %r = call @llvm.copysign.nxv2f64( %vm, %splat) + ret %r +} + +define @vfcopynsign_vv_nxv2f64( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_vv_nxv2f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m2,ta,mu +; CHECK-NEXT: vfsgnjn.vv v8, v8, v10 +; CHECK-NEXT: ret + %n = fneg %vs + %r = call @llvm.copysign.nxv2f64( %vm, %n) + ret %r +} + +define @vfcopynsign_vf_nxv2f64( %vm, double %s) { +; CHECK-LABEL: vfcopynsign_vf_nxv2f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m2,ta,mu +; CHECK-NEXT: vfsgnjn.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, double %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %r = call @llvm.copysign.nxv2f64( %vm, %n) + ret %r +} + +declare @llvm.copysign.nxv4f64(, ) + +define @vfcopysign_vv_nxv4f64( %vm, %vs) { +; CHECK-LABEL: vfcopysign_vv_nxv4f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m4,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v12 +; CHECK-NEXT: ret + %r = call @llvm.copysign.nxv4f64( %vm, %vs) + ret %r +} + +define @vfcopysign_vf_nxv4f64( %vm, double %s) { +; CHECK-LABEL: vfcopysign_vf_nxv4f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m4,ta,mu +; CHECK-NEXT: vfsgnj.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, double %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %r = call @llvm.copysign.nxv4f64( %vm, %splat) + ret %r +} + +define @vfcopynsign_vv_nxv4f64( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_vv_nxv4f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m4,ta,mu +; CHECK-NEXT: vfsgnjn.vv v8, v8, v12 +; CHECK-NEXT: ret + %n = fneg %vs + %r = call @llvm.copysign.nxv4f64( %vm, %n) + ret %r +} + +define @vfcopynsign_vf_nxv4f64( %vm, double %s) { +; CHECK-LABEL: vfcopynsign_vf_nxv4f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m4,ta,mu +; CHECK-NEXT: vfsgnjn.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, double %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %r = call @llvm.copysign.nxv4f64( %vm, %n) + ret %r +} + +declare @llvm.copysign.nxv8f64(, ) + +define @vfcopysign_vv_nxv8f64( %vm, %vs) { +; CHECK-LABEL: vfcopysign_vv_nxv8f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v16 +; CHECK-NEXT: ret + %r = call @llvm.copysign.nxv8f64( %vm, %vs) + ret %r +} + +define @vfcopysign_vf_nxv8f64( %vm, double %s) { +; CHECK-LABEL: vfcopysign_vf_nxv8f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfsgnj.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, double %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %r = call @llvm.copysign.nxv8f64( %vm, %splat) + ret %r +} + +define @vfcopynsign_vv_nxv8f64( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_vv_nxv8f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfsgnjn.vv v8, v8, v16 +; CHECK-NEXT: ret + %n = fneg %vs + %r = call @llvm.copysign.nxv8f64( %vm, %n) + ret %r +} + +define @vfcopynsign_vf_nxv8f64( %vm, double %s) { +; CHECK-LABEL: vfcopynsign_vf_nxv8f64: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfsgnjn.vf v8, v8, fa0 +; CHECK-NEXT: ret + %head = insertelement undef, double %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %r = call @llvm.copysign.nxv8f64( %vm, %n) + ret %r +} + +define @vfcopysign_exttrunc_vv_nxv8f64_nxv8f16( %vm, %vs) { +; CHECK-LABEL: vfcopysign_exttrunc_vv_nxv8f64_nxv8f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfwcvt.f.f.v v28, v16 +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfwcvt.f.f.v v16, v28 +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v16 +; CHECK-NEXT: ret + %e = fpext %vs to + %r = call @llvm.copysign.nxv8f64( %vm, %e) + ret %r +} + +define @vfcopysign_exttrunc_vf_nxv8f64_nxv8f16( %vm, half %s) { +; CHECK-LABEL: vfcopysign_exttrunc_vf_nxv8f64_nxv8f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfmv.v.f v26, fa0 +; CHECK-NEXT: vfwcvt.f.f.v v28, v26 +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfwcvt.f.f.v v16, v28 +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v16 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %esplat = fpext %splat to + %r = call @llvm.copysign.nxv8f64( %vm, %esplat) + ret %r +} + +define @vfcopynsign_exttrunc_vv_nxv8f64_nxv8f16( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_exttrunc_vv_nxv8f64_nxv8f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfsgnjn.vv v26, v16, v16 +; CHECK-NEXT: vfwcvt.f.f.v v28, v26 +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfwcvt.f.f.v v16, v28 +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v16 +; CHECK-NEXT: ret + %n = fneg %vs + %eneg = fpext %n to + %r = call @llvm.copysign.nxv8f64( %vm, %eneg) + ret %r +} + +define @vfcopynsign_exttrunc_vf_nxv8f64_nxv8f16( %vm, half %s) { +; CHECK-LABEL: vfcopynsign_exttrunc_vf_nxv8f64_nxv8f16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16,m2,ta,mu +; CHECK-NEXT: vfmv.v.f v26, fa0 +; CHECK-NEXT: vfsgnjn.vv v26, v26, v26 +; CHECK-NEXT: vfwcvt.f.f.v v28, v26 +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfwcvt.f.f.v v16, v28 +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v16 +; CHECK-NEXT: ret + %head = insertelement undef, half %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %eneg = fpext %n to + %r = call @llvm.copysign.nxv8f64( %vm, %eneg) + ret %r +} + +define @vfcopysign_exttrunc_vv_nxv8f64_nxv8f32( %vm, %vs) { +; CHECK-LABEL: vfcopysign_exttrunc_vv_nxv8f64_nxv8f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfwcvt.f.f.v v24, v16 +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v24 +; CHECK-NEXT: ret + %e = fpext %vs to + %r = call @llvm.copysign.nxv8f64( %vm, %e) + ret %r +} + +define @vfcopysign_exttrunc_vf_nxv8f64_nxv8f32( %vm, float %s) { +; CHECK-LABEL: vfcopysign_exttrunc_vf_nxv8f64_nxv8f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfmv.v.f v28, fa0 +; CHECK-NEXT: vfwcvt.f.f.v v16, v28 +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v16 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %esplat = fpext %splat to + %r = call @llvm.copysign.nxv8f64( %vm, %esplat) + ret %r +} + +define @vfcopynsign_exttrunc_vv_nxv8f64_nxv8f32( %vm, %vs) { +; CHECK-LABEL: vfcopynsign_exttrunc_vv_nxv8f64_nxv8f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfsgnjn.vv v28, v16, v16 +; CHECK-NEXT: vfwcvt.f.f.v v16, v28 +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v16 +; CHECK-NEXT: ret + %n = fneg %vs + %eneg = fpext %n to + %r = call @llvm.copysign.nxv8f64( %vm, %eneg) + ret %r +} + +define @vfcopynsign_exttrunc_vf_nxv8f64_nxv8f32( %vm, float %s) { +; CHECK-LABEL: vfcopynsign_exttrunc_vf_nxv8f64_nxv8f32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32,m4,ta,mu +; CHECK-NEXT: vfmv.v.f v28, fa0 +; CHECK-NEXT: vfsgnjn.vv v28, v28, v28 +; CHECK-NEXT: vfwcvt.f.f.v v16, v28 +; CHECK-NEXT: vsetvli a0, zero, e64,m8,ta,mu +; CHECK-NEXT: vfsgnj.vv v8, v8, v16 +; CHECK-NEXT: ret + %head = insertelement undef, float %s, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %n = fneg %splat + %eneg = fpext %n to + %r = call @llvm.copysign.nxv8f64( %vm, %eneg) + ret %r +}