diff --git a/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp b/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp index 5acb7f5bcd56a..6ddca4a3e0909 100644 --- a/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp +++ b/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp @@ -73,7 +73,7 @@ class RISCVVectorPeephole : public MachineFunctionPass { bool isAllOnesMask(const MachineInstr *MaskDef) const; std::optional getConstant(const MachineOperand &VL) const; bool ensureDominates(const MachineOperand &Use, MachineInstr &Src) const; - Register lookThruCopies(Register Reg) const; + Register lookThruCopies(Register Reg, bool OneUseOnly = false) const; }; } // namespace @@ -389,13 +389,16 @@ bool RISCVVectorPeephole::convertAllOnesVMergeToVMv(MachineInstr &MI) const { // If \p Reg is defined by one or more COPYs of virtual registers, traverses // the chain and returns the root non-COPY source. -Register RISCVVectorPeephole::lookThruCopies(Register Reg) const { +Register RISCVVectorPeephole::lookThruCopies(Register Reg, + bool OneUseOnly) const { while (MachineInstr *Def = MRI->getUniqueVRegDef(Reg)) { if (!Def->isFullCopy()) break; Register Src = Def->getOperand(1).getReg(); if (!Src.isVirtual()) break; + if (OneUseOnly && !MRI->hasOneNonDBGUse(Reg)) + break; Reg = Src; } return Reg; @@ -715,7 +718,8 @@ bool RISCVVectorPeephole::foldVMergeToMask(MachineInstr &MI) const { Register PassthruReg = lookThruCopies(MI.getOperand(1).getReg()); Register FalseReg = lookThruCopies(MI.getOperand(2).getReg()); - Register TrueReg = lookThruCopies(MI.getOperand(3).getReg()); + Register TrueReg = + lookThruCopies(MI.getOperand(3).getReg(), /*OneUseOnly=*/true); if (!TrueReg.isVirtual() || !MRI->hasOneUse(TrueReg)) return false; MachineInstr &True = *MRI->getUniqueVRegDef(TrueReg); @@ -834,6 +838,8 @@ bool RISCVVectorPeephole::foldVMergeToMask(MachineInstr &MI) const { MRI->constrainRegClass( MO.getReg(), True.getRegClassConstraint(MO.getOperandNo(), TII, TRI)); } + // We should clear the IsKill flag since we have a new use now. + MRI->clearKillFlags(FalseReg); MI.eraseFromParent(); return true; diff --git a/llvm/test/CodeGen/RISCV/rvv/vmerge-peephole.mir b/llvm/test/CodeGen/RISCV/rvv/vmerge-peephole.mir index 338732c53aa3e..81a271bd975e3 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vmerge-peephole.mir +++ b/llvm/test/CodeGen/RISCV/rvv/vmerge-peephole.mir @@ -136,3 +136,48 @@ body: | %y:vrnov0 = COPY %x %z:vrnov0 = PseudoVMERGE_VVM_M1 %passthru, %passthru, %y, %mask, %avl, 5 /* e32 */ ... +--- +name: copy_is_killed +body: | + bb.0: + liveins: $v0, $v8, $v9 + ; CHECK-LABEL: name: copy_is_killed + ; CHECK: liveins: $v0, $v8, $v9 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: %x:vr = COPY $v8 + ; CHECK-NEXT: %y:vr = COPY $v9 + ; CHECK-NEXT: %mask:vmv0 = COPY $v0 + ; CHECK-NEXT: %add0:vr = PseudoVADD_VV_M1 $noreg, %x, %y, -1, 5 /* e32 */, 3 /* ta, ma */ + ; CHECK-NEXT: %add1:vrnov0 = COPY %add:vrnov0 + ; CHECK-NEXT: %merge:vrnov0 = PseudoVOR_VV_M1_MASK %add:vrnov0, %add1, %y, %mask, -1, 5 /* e32 */, 1 /* ta, mu */ + %x:vr = COPY $v8 + %y:vr = COPY $v9 + %mask:vmv0 = COPY $v0 + %add0:vr = PseudoVADD_VV_M1 $noreg, %x:vr, %y:vr, -1, 5, 3 + %add1:vrnov0 = COPY killed %add:vr + %or:vrnov0 = PseudoVOR_VV_M1 $noreg, %add1:vrnov0, %y:vr, -1, 5, 3 + %merge:vrnov0 = PseudoVMERGE_VVM_M1 $noreg, %add1:vrnov0, killed %or:vrnov0, killed %mask:vmv0, -1, 5 /* e32 */ + +... +--- +name: copy_multiple_use +body: | + bb.0: + liveins: $x8, $v0, $v8 + ; CHECK-LABEL: name: copy_multiple_use + ; CHECK: liveins: $x8, $v0, $v8 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: %avl:gprnox0 = COPY $x8 + ; CHECK-NEXT: %passthru:vrnov0 = COPY $v8 + ; CHECK-NEXT: %x:vrnov0 = PseudoVLE32_V_M1 $noreg, $noreg, %avl, 5 /* e32 */, 2 /* tu, ma */ :: (load unknown-size, align 1) + ; CHECK-NEXT: %copy:vrnov0 = COPY %x + ; CHECK-NEXT: %mask:vmv0 = COPY $v0 + ; CHECK-NEXT: PseudoVSE8_V_M1 %copy, $noreg, %avl, 5 /* e32 */ + ; CHECK-NEXT: %y:vrnov0 = PseudoVMERGE_VVM_M1 %passthru, %passthru, %copy, %mask, %avl, 5 /* e32 */ + %avl:gprnox0 = COPY $x8 + %passthru:vrnov0 = COPY $v8 + %x:vrnov0 = PseudoVLE32_V_M1 $noreg, $noreg, %avl, 5 /* e32 */, 2 /* tu, ma */ :: (load unknown-size) + %copy:vrnov0 = COPY %x + %mask:vmv0 = COPY $v0 + PseudoVSE8_V_M1 %copy, $noreg, %avl, 5 /* e8 */ + %y:vrnov0 = PseudoVMERGE_VVM_M1 %passthru, %passthru, %copy, %mask, %avl, 5 /* e32 */