diff --git a/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp b/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp index 6bb026378274e..c9c2413d009b7 100644 --- a/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp +++ b/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp @@ -611,7 +611,7 @@ bool RISCVVectorPeephole::foldVMV_V_V(MachineInstr &MI) { MachineInstr *Src = MRI->getVRegDef(MI.getOperand(2).getReg()); if (!Src || Src->hasUnmodeledSideEffects() || - Src->getParent() != MI.getParent() || Src->getNumDefs() != 1 || + Src->getParent() != MI.getParent() || !RISCVII::isFirstDefTiedToFirstUse(Src->getDesc()) || !RISCVII::hasVLOp(Src->getDesc().TSFlags) || !RISCVII::hasVecPolicyOp(Src->getDesc().TSFlags)) @@ -622,7 +622,7 @@ bool RISCVVectorPeephole::foldVMV_V_V(MachineInstr &MI) { return false; // Src needs to have the same passthru as VMV_V_V - MachineOperand &SrcPassthru = Src->getOperand(1); + MachineOperand &SrcPassthru = Src->getOperand(Src->getNumExplicitDefs()); if (SrcPassthru.getReg() != RISCV::NoRegister && SrcPassthru.getReg() != Passthru.getReg()) return false; @@ -643,7 +643,8 @@ bool RISCVVectorPeephole::foldVMV_V_V(MachineInstr &MI) { // If Src is masked then its passthru needs to be in VRNoV0. if (Passthru.getReg() != RISCV::NoRegister) MRI->constrainRegClass(Passthru.getReg(), - TII->getRegClass(Src->getDesc(), 1, TRI, + TII->getRegClass(Src->getDesc(), + SrcPassthru.getOperandNo(), TRI, *Src->getParent()->getParent())); } diff --git a/llvm/test/CodeGen/RISCV/rvv/vmv.v.v-peephole.ll b/llvm/test/CodeGen/RISCV/rvv/vmv.v.v-peephole.ll index 6345b90db23b8..1e2e7795f6546 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vmv.v.v-peephole.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vmv.v.v-peephole.ll @@ -206,3 +206,19 @@ define @undef_passthru( %passthru, @llvm.riscv.vmv.v.v.nxv1i64( undef, %a, iXLen %avl) ret %b } + +; Check that we can fold into vle64ff.v even if we need to move it past the +; passthru and it's safe. +define @vleff_move_past_passthru(ptr %p, ptr %q, iXLen %avl) { +; CHECK-LABEL: vleff_move_past_passthru: +; CHECK: # %bb.0: +; CHECK-NEXT: vl1re64.v v8, (a1) +; CHECK-NEXT: vsetvli zero, a2, e64, m1, tu, ma +; CHECK-NEXT: vle64ff.v v8, (a0) +; CHECK-NEXT: ret + %a = call { , iXLen } @llvm.riscv.vleff( poison, ptr %p, iXLen %avl) + %vec = extractvalue { , iXLen } %a, 0 + %passthru = load , ptr %q + %b = call @llvm.riscv.vmv.v.v.nxv1i64( %passthru, %vec, iXLen %avl) + ret %b +} diff --git a/llvm/test/CodeGen/RISCV/rvv/vmv.v.v-peephole.mir b/llvm/test/CodeGen/RISCV/rvv/vmv.v.v-peephole.mir index f545ecc5e53d7..6e106e50634f0 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vmv.v.v-peephole.mir +++ b/llvm/test/CodeGen/RISCV/rvv/vmv.v.v-peephole.mir @@ -135,3 +135,20 @@ body: | %3:vrnov0 = PseudoVMV_V_V_MF2 $noreg, %2, 0, 5 /* e32 */, 0 /* tu, mu */ %7:vmv0 = COPY $v8 %6:vrnov0 = PseudoVLSE32_V_MF2_MASK %3, $noreg, $noreg, %7, 0, 5 /* e32 */, 0 /* tu, mu */ :: (load unknown-size, align 4) +... +--- +name: move_vleff +body: | + bb.0: + liveins: $v8 + ; CHECK-LABEL: name: move_vleff + ; CHECK: liveins: $v8 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: %passthru:vr = COPY $v8 + ; CHECK-NEXT: %x:vr, %vl:gpr = PseudoVLE32FF_V_M1 %passthru, $noreg, 4, 5 /* e32 */, 0 /* tu, mu */ :: (load unknown-size, align 1) + ; CHECK-NEXT: %y:gpr = ADDI $x0, 1 + %x:vr, %vl:gpr = PseudoVLE32FF_V_M1 $noreg, $noreg, 4, 5 /* e32 */, 0 /* tu, mu */ :: (load unknown-size) + %passthru:vr = COPY $v8 + %y:gpr = ADDI $x0, 1 + %z:vr = PseudoVMV_V_V_M1 %passthru, %x, 4, 5 /* e32 */, 0 /* tu, mu */ +...