Index: llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp =================================================================== --- llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp +++ llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp @@ -85,6 +85,17 @@ } } +static bool isScalarSplatInstr(const MachineInstr &MI) { + switch (getRVVMCOpcode(MI.getOpcode())) { + default: + return false; + case RISCV::VMV_V_I: + case RISCV::VMV_V_X: + case RISCV::VFMV_V_F: + return true; + } +} + static bool isVSlideInstr(const MachineInstr &MI) { switch (getRVVMCOpcode(MI.getOpcode())) { default: @@ -911,6 +922,20 @@ Used.TailPolicy = false; } + // A tail undefined vmv.v.i/x or vfmv.v.f with VL=1 can be treated in the same + // semantically as vmv.s.x. This is particularly useful since we don't have an + // immediate form of vmv.s.x, and thus frequently use vmv.v.i in it's place. + // Since a splat is non-constant time in LMUL, we do need to be careful to not + // increase the number of active vector registers (unlikely for vmv.s.x.) + if (isScalarSplatInstr(MI) && Require.hasAVLImm() && Require.getAVLImm() == 1 && + isLMUL1OrSmaller(CurInfo.getVLMUL()) && hasUndefinedMergeOp(MI, *MRI)) { + Used.LMUL = false; + Used.SEWLMULRatio = false; + Used.VLAny = false; + Used.SEW = DemandedFields::SEWGreaterThanOrEqual; + Used.TailPolicy = false; + } + if (CurInfo.isCompatible(Used, Require, *MRI)) return false; Index: llvm/test/CodeGen/RISCV/rvv/fixed-vectors-reduction-int-vp.ll =================================================================== --- llvm/test/CodeGen/RISCV/rvv/fixed-vectors-reduction-int-vp.ll +++ llvm/test/CodeGen/RISCV/rvv/fixed-vectors-reduction-int-vp.ll @@ -1431,8 +1431,8 @@ ; RV32-NEXT: vmv.v.x v9, a1 ; RV32-NEXT: vmsne.vi v9, v9, 0 ; RV32-NEXT: vmand.mm v0, v9, v0 -; RV32-NEXT: vsetvli zero, zero, e8, mf8, ta, ma ; RV32-NEXT: vmv.v.i v9, 1 +; RV32-NEXT: vsetvli zero, zero, e8, mf8, ta, ma ; RV32-NEXT: vmerge.vvm v8, v9, v8, v0 ; RV32-NEXT: vmv.x.s a0, v8 ; RV32-NEXT: mv a1, a2 @@ -1452,8 +1452,8 @@ ; RV64-NEXT: vmv.v.x v9, a1 ; RV64-NEXT: vmsne.vi v9, v9, 0 ; RV64-NEXT: vmand.mm v0, v9, v0 -; RV64-NEXT: vsetvli zero, zero, e8, mf8, ta, ma ; RV64-NEXT: vmv.v.i v9, 1 +; RV64-NEXT: vsetvli zero, zero, e8, mf8, ta, ma ; RV64-NEXT: vmerge.vvm v8, v9, v8, v0 ; RV64-NEXT: vmv.x.s a0, v8 ; RV64-NEXT: mv a1, a2 Index: llvm/test/CodeGen/RISCV/rvv/fixed-vectors-reduction-int.ll =================================================================== --- llvm/test/CodeGen/RISCV/rvv/fixed-vectors-reduction-int.ll +++ llvm/test/CodeGen/RISCV/rvv/fixed-vectors-reduction-int.ll @@ -2199,9 +2199,7 @@ ; RV32: # %bb.0: ; RV32-NEXT: vsetivli zero, 2, e64, m1, ta, ma ; RV32-NEXT: vle64.v v8, (a0) -; RV32-NEXT: vsetivli zero, 1, e64, m1, ta, ma ; RV32-NEXT: vmv.v.i v9, -1 -; RV32-NEXT: vsetivli zero, 2, e64, m1, ta, ma ; RV32-NEXT: vredand.vs v8, v8, v9 ; RV32-NEXT: vmv.x.s a0, v8 ; RV32-NEXT: li a1, 32 @@ -5686,9 +5684,7 @@ ; RV32: # %bb.0: ; RV32-NEXT: vsetivli zero, 2, e64, m1, ta, ma ; RV32-NEXT: vle64.v v8, (a0) -; RV32-NEXT: vsetivli zero, 1, e64, m1, ta, ma ; RV32-NEXT: vmv.v.i v9, -1 -; RV32-NEXT: vsetivli zero, 2, e64, m1, ta, ma ; RV32-NEXT: vredminu.vs v8, v8, v9 ; RV32-NEXT: vmv.x.s a0, v8 ; RV32-NEXT: li a1, 32