Skip to content

Commit 2fc1275

Browse files
authored
[RISCV] Fix corner cases after #170070 (#170438)
There are two fixes: 1. Clear kill flags for `FalseReg` in foldVMergeToMask or we can't pass the MachineVerifier because of using a killed virtual register. 2. Restrict `lookThruCopies` to only look through COPYs with one non-debug use. This was found when backporting #170070 to 21.x branch.
1 parent 6af1c3f commit 2fc1275

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class RISCVVectorPeephole : public MachineFunctionPass {
7373
bool isAllOnesMask(const MachineInstr *MaskDef) const;
7474
std::optional<unsigned> getConstant(const MachineOperand &VL) const;
7575
bool ensureDominates(const MachineOperand &Use, MachineInstr &Src) const;
76-
Register lookThruCopies(Register Reg) const;
76+
Register lookThruCopies(Register Reg, bool OneUseOnly = false) const;
7777
};
7878

7979
} // namespace
@@ -389,13 +389,16 @@ bool RISCVVectorPeephole::convertAllOnesVMergeToVMv(MachineInstr &MI) const {
389389

390390
// If \p Reg is defined by one or more COPYs of virtual registers, traverses
391391
// the chain and returns the root non-COPY source.
392-
Register RISCVVectorPeephole::lookThruCopies(Register Reg) const {
392+
Register RISCVVectorPeephole::lookThruCopies(Register Reg,
393+
bool OneUseOnly) const {
393394
while (MachineInstr *Def = MRI->getUniqueVRegDef(Reg)) {
394395
if (!Def->isFullCopy())
395396
break;
396397
Register Src = Def->getOperand(1).getReg();
397398
if (!Src.isVirtual())
398399
break;
400+
if (OneUseOnly && !MRI->hasOneNonDBGUse(Reg))
401+
break;
399402
Reg = Src;
400403
}
401404
return Reg;
@@ -715,7 +718,8 @@ bool RISCVVectorPeephole::foldVMergeToMask(MachineInstr &MI) const {
715718

716719
Register PassthruReg = lookThruCopies(MI.getOperand(1).getReg());
717720
Register FalseReg = lookThruCopies(MI.getOperand(2).getReg());
718-
Register TrueReg = lookThruCopies(MI.getOperand(3).getReg());
721+
Register TrueReg =
722+
lookThruCopies(MI.getOperand(3).getReg(), /*OneUseOnly=*/true);
719723
if (!TrueReg.isVirtual() || !MRI->hasOneUse(TrueReg))
720724
return false;
721725
MachineInstr &True = *MRI->getUniqueVRegDef(TrueReg);
@@ -834,6 +838,8 @@ bool RISCVVectorPeephole::foldVMergeToMask(MachineInstr &MI) const {
834838
MRI->constrainRegClass(
835839
MO.getReg(), True.getRegClassConstraint(MO.getOperandNo(), TII, TRI));
836840
}
841+
// We should clear the IsKill flag since we have a new use now.
842+
MRI->clearKillFlags(FalseReg);
837843
MI.eraseFromParent();
838844

839845
return true;

llvm/test/CodeGen/RISCV/rvv/vmerge-peephole.mir

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,48 @@ body: |
136136
%y:vrnov0 = COPY %x
137137
%z:vrnov0 = PseudoVMERGE_VVM_M1 %passthru, %passthru, %y, %mask, %avl, 5 /* e32 */
138138
...
139+
---
140+
name: copy_is_killed
141+
body: |
142+
bb.0:
143+
liveins: $v0, $v8, $v9
144+
; CHECK-LABEL: name: copy_is_killed
145+
; CHECK: liveins: $v0, $v8, $v9
146+
; CHECK-NEXT: {{ $}}
147+
; CHECK-NEXT: %x:vr = COPY $v8
148+
; CHECK-NEXT: %y:vr = COPY $v9
149+
; CHECK-NEXT: %mask:vmv0 = COPY $v0
150+
; CHECK-NEXT: %add0:vr = PseudoVADD_VV_M1 $noreg, %x, %y, -1, 5 /* e32 */, 3 /* ta, ma */
151+
; CHECK-NEXT: %add1:vrnov0 = COPY %add:vrnov0
152+
; CHECK-NEXT: %merge:vrnov0 = PseudoVOR_VV_M1_MASK %add:vrnov0, %add1, %y, %mask, -1, 5 /* e32 */, 1 /* ta, mu */
153+
%x:vr = COPY $v8
154+
%y:vr = COPY $v9
155+
%mask:vmv0 = COPY $v0
156+
%add0:vr = PseudoVADD_VV_M1 $noreg, %x:vr, %y:vr, -1, 5, 3
157+
%add1:vrnov0 = COPY killed %add:vr
158+
%or:vrnov0 = PseudoVOR_VV_M1 $noreg, %add1:vrnov0, %y:vr, -1, 5, 3
159+
%merge:vrnov0 = PseudoVMERGE_VVM_M1 $noreg, %add1:vrnov0, killed %or:vrnov0, killed %mask:vmv0, -1, 5 /* e32 */
160+
161+
...
162+
---
163+
name: copy_multiple_use
164+
body: |
165+
bb.0:
166+
liveins: $x8, $v0, $v8
167+
; CHECK-LABEL: name: copy_multiple_use
168+
; CHECK: liveins: $x8, $v0, $v8
169+
; CHECK-NEXT: {{ $}}
170+
; CHECK-NEXT: %avl:gprnox0 = COPY $x8
171+
; CHECK-NEXT: %passthru:vrnov0 = COPY $v8
172+
; CHECK-NEXT: %x:vrnov0 = PseudoVLE32_V_M1 $noreg, $noreg, %avl, 5 /* e32 */, 2 /* tu, ma */ :: (load unknown-size, align 1)
173+
; CHECK-NEXT: %copy:vrnov0 = COPY %x
174+
; CHECK-NEXT: %mask:vmv0 = COPY $v0
175+
; CHECK-NEXT: PseudoVSE8_V_M1 %copy, $noreg, %avl, 5 /* e32 */
176+
; CHECK-NEXT: %y:vrnov0 = PseudoVMERGE_VVM_M1 %passthru, %passthru, %copy, %mask, %avl, 5 /* e32 */
177+
%avl:gprnox0 = COPY $x8
178+
%passthru:vrnov0 = COPY $v8
179+
%x:vrnov0 = PseudoVLE32_V_M1 $noreg, $noreg, %avl, 5 /* e32 */, 2 /* tu, ma */ :: (load unknown-size)
180+
%copy:vrnov0 = COPY %x
181+
%mask:vmv0 = COPY $v0
182+
PseudoVSE8_V_M1 %copy, $noreg, %avl, 5 /* e8 */
183+
%y:vrnov0 = PseudoVMERGE_VVM_M1 %passthru, %passthru, %copy, %mask, %avl, 5 /* e32 */

0 commit comments

Comments
 (0)