diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -803,6 +803,9 @@ return true; } + // Return true if the target wants to transform Op(Splat(X)) -> Splat(Op(X)) + virtual bool preferScalarizeSplat(unsigned Opc) const { return true; } + /// Return true if the target wants to use the optimization that /// turns ext(promotableInst1(...(promotableInstN(load)))) into /// promotedInst1(...(promotedInstN(ext(load)))). diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -440,6 +440,7 @@ SDValue visitOR(SDNode *N); SDValue visitORLike(SDValue N0, SDValue N1, SDNode *N); SDValue visitXOR(SDNode *N); + SDValue SimplifyVCastOp(SDNode *N, const SDLoc &DL); SDValue SimplifyVBinOp(SDNode *N, const SDLoc &DL); SDValue visitSHL(SDNode *N); SDValue visitSRA(SDNode *N); @@ -12337,6 +12338,10 @@ EVT VT = N->getValueType(0); SDLoc DL(N); + if (VT.isVector()) + if (SDValue FoldedVOp = SimplifyVCastOp(N, DL)) + return FoldedVOp; + // sext(undef) = 0 because the top bit will all be the same. if (N0.isUndef()) return DAG.getConstant(0, DL, VT); @@ -12586,6 +12591,10 @@ SDValue N0 = N->getOperand(0); EVT VT = N->getValueType(0); + if (VT.isVector()) + if (SDValue FoldedVOp = SimplifyVCastOp(N, SDLoc(N))) + return FoldedVOp; + // zext(undef) = 0 if (N0.isUndef()) return DAG.getConstant(0, SDLoc(N), VT); @@ -16231,6 +16240,10 @@ SDValue N0 = N->getOperand(0); EVT VT = N->getValueType(0); + if (VT.isVector()) + if (SDValue FoldedVOp = SimplifyVCastOp(N, SDLoc(N))) + return FoldedVOp; + // If this is fp_round(fpextend), don't fold it, allow ourselves to be folded. if (N->hasOneUse() && N->use_begin()->getOpcode() == ISD::FP_ROUND) @@ -24050,6 +24063,39 @@ return DAG.getSplat(VT, DL, ScalarBO); } +/// Visit a vector cast operation, like FP_EXTEND. +SDValue DAGCombiner::SimplifyVCastOp(SDNode *N, const SDLoc &DL) { + EVT VT = N->getValueType(0); + assert(VT.isVector() && "SimplifyVCastOp only works on vectors!"); + EVT EltVT = VT.getVectorElementType(); + unsigned Opcode = N->getOpcode(); + + SDValue N0 = N->getOperand(0); + EVT SrcVT = N0->getValueType(0); + EVT SrcEltVT = SrcVT.getVectorElementType(); + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + + // TODO: promote operation might be also good here? + int Index0; + SDValue Src0 = DAG.getSplatSourceVector(N0, Index0); + if (Src0 && + (N0.getOpcode() == ISD::SPLAT_VECTOR || + TLI.isExtractVecEltCheap(VT, Index0)) && + TLI.isOperationLegalOrCustom(Opcode, EltVT) && + TLI.preferScalarizeSplat(Opcode)) { + SDValue IndexC = DAG.getVectorIdxConstant(Index0, DL); + SDValue Elt = + DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, SrcEltVT, Src0, IndexC); + SDValue ScalarBO = DAG.getNode(Opcode, DL, EltVT, Elt, N->getFlags()); + if (VT.isScalableVector()) + return DAG.getSplatVector(VT, DL, ScalarBO); + SmallVector Ops(VT.getVectorNumElements(), ScalarBO); + return DAG.getBuildVector(VT, DL, Ops); + } + + return SDValue(); +} + /// Visit a binary vector operation, like ADD. SDValue DAGCombiner::SimplifyVBinOp(SDNode *N, const SDLoc &DL) { EVT VT = N->getValueType(0); 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 @@ -380,6 +380,8 @@ bool isIntDivCheap(EVT VT, AttributeList Attr) const override; + bool preferScalarizeSplat(unsigned Opc) const override; + bool softPromoteHalfType() const override { return true; } /// Return the register type for a given MVT, ensuring vectors are treated 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 @@ -13513,6 +13513,14 @@ return OptSize && !VT.isVector(); } +bool RISCVTargetLowering::preferScalarizeSplat(unsigned Opc) const { + // Scalarize zero_ext and sign_ext might stop match to widening instruction in + // some situation. + if (Opc == ISD::ZERO_EXTEND || Opc == ISD::SIGN_EXTEND) + return false; + return true; +} + #define GET_REGISTER_MATCHER #include "RISCVGenAsmMatcher.inc" 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 @@ -479,9 +479,8 @@ (!cast(instruction_name#"_VV_"#vti.LMul.MX) wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; - def : Pat<(fma (wti.Vector (riscv_fpextend_vl_oneuse - (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), - (vti.Mask true_mask), (XLenVT srcvalue))), + def : Pat<(fma (wti.Vector (SplatFPOp + (fpext_oneuse vti.ScalarRegClass:$rs1))), (wti.Vector (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), (vti.Mask true_mask), (XLenVT srcvalue))), @@ -505,9 +504,7 @@ (!cast(instruction_name#"_VV_"#vti.LMul.MX) wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; - def : Pat<(fma (riscv_fpextend_vl_oneuse - (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), - (vti.Mask true_mask), (XLenVT srcvalue)), + def : Pat<(fma (SplatFPOp (fpext_oneuse vti.ScalarRegClass:$rs1)), (fneg (wti.Vector (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), (vti.Mask true_mask), (XLenVT srcvalue)))), @@ -515,9 +512,7 @@ (!cast(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; - def : Pat<(fma (fneg (wti.Vector (riscv_fpextend_vl_oneuse - (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), - (vti.Mask true_mask), (XLenVT srcvalue)))), + def : Pat<(fma (fneg (wti.Vector (SplatFPOp (fpext_oneuse vti.ScalarRegClass:$rs1)))), (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), (vti.Mask true_mask), (XLenVT srcvalue)), (fneg wti.RegClass:$rd)), @@ -540,9 +535,7 @@ (!cast(instruction_name#"_VV_"#vti.LMul.MX) wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; - def : Pat<(fma (wti.Vector (riscv_fpextend_vl_oneuse - (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), - (vti.Mask true_mask), (XLenVT srcvalue))), + def : Pat<(fma (wti.Vector (SplatFPOp (fpext_oneuse vti.ScalarRegClass:$rs1))), (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), (vti.Mask true_mask), (XLenVT srcvalue)), (fneg wti.RegClass:$rd)), @@ -565,9 +558,7 @@ (!cast(instruction_name#"_VV_"#vti.LMul.MX) wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; - def : Pat<(fma (wti.Vector (riscv_fpextend_vl_oneuse - (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), - (vti.Mask true_mask), (XLenVT srcvalue))), + def : Pat<(fma (wti.Vector (SplatFPOp (fpext_oneuse vti.ScalarRegClass:$rs1))), (fneg (wti.Vector (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), (vti.Mask true_mask), (XLenVT srcvalue)))), @@ -575,9 +566,7 @@ (!cast(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; - def : Pat<(fma (fneg (wti.Vector (riscv_fpextend_vl_oneuse - (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), - (vti.Mask true_mask), (XLenVT srcvalue)))), + def : Pat<(fma (fneg (wti.Vector (SplatFPOp (fpext_oneuse vti.ScalarRegClass:$rs1)))), (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), (vti.Mask true_mask), (XLenVT srcvalue)), wti.RegClass:$rd), diff --git a/llvm/test/CodeGen/Hexagon/autohvx/isel-sext-inreg.ll b/llvm/test/CodeGen/Hexagon/autohvx/isel-sext-inreg.ll --- a/llvm/test/CodeGen/Hexagon/autohvx/isel-sext-inreg.ll +++ b/llvm/test/CodeGen/Hexagon/autohvx/isel-sext-inreg.ll @@ -7,7 +7,7 @@ target triple = "hexagon" ; CHECK-LABEL: danny: -; CHECK: vmem +; CHECK: memh define void @danny(i16* %a0) #0 { b0: %v1 = load i16, i16* %a0, align 2 @@ -29,7 +29,7 @@ } ; CHECK-LABEL: sammy: -; CHECK: vmem +; CHECK: memh define void @sammy(i16* %a0) #1 { b0: %v1 = load i16, i16* %a0, align 2 diff --git a/llvm/test/CodeGen/RISCV/rvv/vfcopysign-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfcopysign-sdnode.ll --- a/llvm/test/CodeGen/RISCV/rvv/vfcopysign-sdnode.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vfcopysign-sdnode.ll @@ -604,11 +604,9 @@ 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, ma -; CHECK-NEXT: vfmv.v.f v9, fa0 -; CHECK-NEXT: vfwcvt.f.f.v v10, v9 -; CHECK-NEXT: vsetvli zero, zero, e32, mf2, ta, ma -; CHECK-NEXT: vfsgnj.vv v8, v8, v10 +; CHECK-NEXT: fcvt.s.h ft0, fa0 +; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, ma +; CHECK-NEXT: vfsgnj.vf v8, v8, ft0 ; CHECK-NEXT: ret %head = insertelement poison, half %s, i32 0 %splat = shufflevector %head, poison, zeroinitializer @@ -634,11 +632,9 @@ 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, ma -; CHECK-NEXT: vfmv.v.f v9, fa0 -; CHECK-NEXT: vfwcvt.f.f.v v10, v9 -; CHECK-NEXT: vsetvli zero, zero, e32, mf2, ta, ma -; CHECK-NEXT: vfsgnjn.vv v8, v8, v10 +; CHECK-NEXT: fcvt.s.h ft0, fa0 +; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, ma +; CHECK-NEXT: vfsgnjn.vf v8, v8, ft0 ; CHECK-NEXT: ret %head = insertelement poison, half %s, i32 0 %splat = shufflevector %head, poison, zeroinitializer @@ -866,11 +862,9 @@ 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, ma -; CHECK-NEXT: vfmv.v.f v12, fa0 -; CHECK-NEXT: vfwcvt.f.f.v v16, v12 -; CHECK-NEXT: vsetvli zero, zero, e32, m4, ta, ma -; CHECK-NEXT: vfsgnj.vv v8, v8, v16 +; CHECK-NEXT: fcvt.s.h ft0, fa0 +; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma +; CHECK-NEXT: vfsgnj.vf v8, v8, ft0 ; CHECK-NEXT: ret %head = insertelement poison, half %s, i32 0 %splat = shufflevector %head, poison, zeroinitializer @@ -896,11 +890,9 @@ 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, ma -; CHECK-NEXT: vfmv.v.f v12, fa0 -; CHECK-NEXT: vfwcvt.f.f.v v16, v12 -; CHECK-NEXT: vsetvli zero, zero, e32, m4, ta, ma -; CHECK-NEXT: vfsgnjn.vv v8, v8, v16 +; CHECK-NEXT: fcvt.s.h ft0, fa0 +; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma +; CHECK-NEXT: vfsgnjn.vf v8, v8, ft0 ; CHECK-NEXT: ret %head = insertelement poison, half %s, i32 0 %splat = shufflevector %head, poison, zeroinitializer @@ -1082,13 +1074,9 @@ 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, ma -; CHECK-NEXT: vfmv.v.f v9, fa0 -; CHECK-NEXT: vfwcvt.f.f.v v10, v9 -; CHECK-NEXT: vsetvli zero, zero, e32, mf2, ta, ma -; CHECK-NEXT: vfwcvt.f.f.v v9, v10 -; CHECK-NEXT: vsetvli zero, zero, e64, m1, ta, ma -; CHECK-NEXT: vfsgnj.vv v8, v8, v9 +; CHECK-NEXT: fcvt.d.h ft0, fa0 +; CHECK-NEXT: vsetvli a0, zero, e64, m1, ta, ma +; CHECK-NEXT: vfsgnj.vf v8, v8, ft0 ; CHECK-NEXT: ret %head = insertelement poison, half %s, i32 0 %splat = shufflevector %head, poison, zeroinitializer @@ -1116,13 +1104,9 @@ 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, ma -; CHECK-NEXT: vfmv.v.f v9, fa0 -; CHECK-NEXT: vfwcvt.f.f.v v10, v9 -; CHECK-NEXT: vsetvli zero, zero, e32, mf2, ta, ma -; CHECK-NEXT: vfwcvt.f.f.v v9, v10 -; CHECK-NEXT: vsetvli zero, zero, e64, m1, ta, ma -; CHECK-NEXT: vfsgnjn.vv v8, v8, v9 +; CHECK-NEXT: fcvt.d.h ft0, fa0 +; CHECK-NEXT: vsetvli a0, zero, e64, m1, ta, ma +; CHECK-NEXT: vfsgnjn.vf v8, v8, ft0 ; CHECK-NEXT: ret %head = insertelement poison, half %s, i32 0 %splat = shufflevector %head, poison, zeroinitializer @@ -1148,11 +1132,9 @@ 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, ma -; CHECK-NEXT: vfmv.v.f v9, fa0 -; CHECK-NEXT: vfwcvt.f.f.v v10, v9 -; CHECK-NEXT: vsetvli zero, zero, e64, m1, ta, ma -; CHECK-NEXT: vfsgnj.vv v8, v8, v10 +; CHECK-NEXT: fcvt.d.s ft0, fa0 +; CHECK-NEXT: vsetvli a0, zero, e64, m1, ta, ma +; CHECK-NEXT: vfsgnj.vf v8, v8, ft0 ; CHECK-NEXT: ret %head = insertelement poison, float %s, i32 0 %splat = shufflevector %head, poison, zeroinitializer @@ -1178,11 +1160,9 @@ 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, ma -; CHECK-NEXT: vfmv.v.f v9, fa0 -; CHECK-NEXT: vfwcvt.f.f.v v10, v9 -; CHECK-NEXT: vsetvli zero, zero, e64, m1, ta, ma -; CHECK-NEXT: vfsgnjn.vv v8, v8, v10 +; CHECK-NEXT: fcvt.d.s ft0, fa0 +; CHECK-NEXT: vsetvli a0, zero, e64, m1, ta, ma +; CHECK-NEXT: vfsgnjn.vf v8, v8, ft0 ; CHECK-NEXT: ret %head = insertelement poison, float %s, i32 0 %splat = shufflevector %head, poison, zeroinitializer @@ -1354,13 +1334,9 @@ 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, ma -; CHECK-NEXT: vfmv.v.f v16, fa0 -; CHECK-NEXT: vfwcvt.f.f.v v20, v16 -; CHECK-NEXT: vsetvli zero, zero, e32, m4, ta, ma -; CHECK-NEXT: vfwcvt.f.f.v v24, v20 -; CHECK-NEXT: vsetvli zero, zero, e64, m8, ta, ma -; CHECK-NEXT: vfsgnj.vv v8, v8, v24 +; CHECK-NEXT: fcvt.d.h ft0, fa0 +; CHECK-NEXT: vsetvli a0, zero, e64, m8, ta, ma +; CHECK-NEXT: vfsgnj.vf v8, v8, ft0 ; CHECK-NEXT: ret %head = insertelement poison, half %s, i32 0 %splat = shufflevector %head, poison, zeroinitializer @@ -1388,13 +1364,9 @@ 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, ma -; CHECK-NEXT: vfmv.v.f v16, fa0 -; CHECK-NEXT: vfwcvt.f.f.v v20, v16 -; CHECK-NEXT: vsetvli zero, zero, e32, m4, ta, ma -; CHECK-NEXT: vfwcvt.f.f.v v24, v20 -; CHECK-NEXT: vsetvli zero, zero, e64, m8, ta, ma -; CHECK-NEXT: vfsgnjn.vv v8, v8, v24 +; CHECK-NEXT: fcvt.d.h ft0, fa0 +; CHECK-NEXT: vsetvli a0, zero, e64, m8, ta, ma +; CHECK-NEXT: vfsgnjn.vf v8, v8, ft0 ; CHECK-NEXT: ret %head = insertelement poison, half %s, i32 0 %splat = shufflevector %head, poison, zeroinitializer @@ -1420,11 +1392,9 @@ 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, ma -; CHECK-NEXT: vfmv.v.f v16, fa0 -; CHECK-NEXT: vfwcvt.f.f.v v24, v16 -; CHECK-NEXT: vsetvli zero, zero, e64, m8, ta, ma -; CHECK-NEXT: vfsgnj.vv v8, v8, v24 +; CHECK-NEXT: fcvt.d.s ft0, fa0 +; CHECK-NEXT: vsetvli a0, zero, e64, m8, ta, ma +; CHECK-NEXT: vfsgnj.vf v8, v8, ft0 ; CHECK-NEXT: ret %head = insertelement poison, float %s, i32 0 %splat = shufflevector %head, poison, zeroinitializer @@ -1450,11 +1420,9 @@ 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, ma -; CHECK-NEXT: vfmv.v.f v16, fa0 -; CHECK-NEXT: vfwcvt.f.f.v v24, v16 -; CHECK-NEXT: vsetvli zero, zero, e64, m8, ta, ma -; CHECK-NEXT: vfsgnjn.vv v8, v8, v24 +; CHECK-NEXT: fcvt.d.s ft0, fa0 +; CHECK-NEXT: vsetvli a0, zero, e64, m8, ta, ma +; CHECK-NEXT: vfsgnjn.vf v8, v8, ft0 ; CHECK-NEXT: ret %head = insertelement poison, float %s, i32 0 %splat = shufflevector %head, poison, zeroinitializer