Skip to content

Commit 5ecb37b

Browse files
authored
[RISCV] Make InitUndef handle undef operand (#65755)
Address #65704. If the operand is marked as undef, the InitUndef misses this case. This patch makes InitUndef pass handle the undef operand case.
1 parent 71ba05b commit 5ecb37b

File tree

4 files changed

+106
-56
lines changed

4 files changed

+106
-56
lines changed

llvm/lib/Target/RISCV/RISCVRVVInitUndef.cpp

Lines changed: 43 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,13 @@ class RISCVInitUndef : public MachineFunctionPass {
8080
private:
8181
bool processBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB,
8282
const DeadLaneDetector &DLD);
83-
bool handleImplicitDef(MachineBasicBlock &MBB,
84-
MachineBasicBlock::iterator &Inst);
8583
bool isVectorRegClass(const Register R);
8684
const TargetRegisterClass *
8785
getVRLargestSuperClass(const TargetRegisterClass *RC) const;
8886
bool handleSubReg(MachineFunction &MF, MachineInstr &MI,
8987
const DeadLaneDetector &DLD);
88+
bool fixupIllOperand(MachineInstr *MI, MachineOperand &MO);
89+
bool handleReg(MachineInstr *MI);
9090
};
9191

9292
} // end anonymous namespace
@@ -137,53 +137,30 @@ static bool isEarlyClobberMI(MachineInstr &MI) {
137137
});
138138
}
139139

140-
bool RISCVInitUndef::handleImplicitDef(MachineBasicBlock &MBB,
141-
MachineBasicBlock::iterator &Inst) {
142-
assert(Inst->getOpcode() == TargetOpcode::IMPLICIT_DEF);
143-
144-
Register Reg = Inst->getOperand(0).getReg();
145-
if (!Reg.isVirtual())
146-
return false;
147-
148-
bool HasOtherUse = false;
149-
SmallVector<MachineOperand *, 1> UseMOs;
150-
for (MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
151-
if (isEarlyClobberMI(*MO.getParent())) {
152-
if (MO.isUse() && !MO.isTied())
153-
UseMOs.push_back(&MO);
154-
else
155-
HasOtherUse = true;
156-
}
140+
static bool findImplictDefMIFromReg(Register Reg, MachineRegisterInfo *MRI) {
141+
for (auto &DefMI : MRI->def_instructions(Reg)) {
142+
if (DefMI.getOpcode() == TargetOpcode::IMPLICIT_DEF)
143+
return true;
157144
}
145+
return false;
146+
}
158147

159-
if (UseMOs.empty())
160-
return false;
161-
162-
LLVM_DEBUG(
163-
dbgs() << "Emitting PseudoRVVInitUndef for implicit vector register "
164-
<< Reg << '\n');
165-
166-
const TargetRegisterClass *TargetRegClass =
167-
getVRLargestSuperClass(MRI->getRegClass(Reg));
168-
unsigned Opcode = getUndefInitOpcode(TargetRegClass->getID());
169-
170-
Register NewDest = Reg;
171-
if (HasOtherUse) {
172-
NewDest = MRI->createVirtualRegister(TargetRegClass);
173-
// We don't have a way to update dead lanes, so keep track of the
174-
// new register so that we avoid querying it later.
175-
NewRegs.insert(NewDest);
176-
}
177-
BuildMI(MBB, Inst, Inst->getDebugLoc(), TII->get(Opcode), NewDest);
178-
179-
if (!HasOtherUse)
180-
DeadInsts.push_back(&(*Inst));
148+
bool RISCVInitUndef::handleReg(MachineInstr *MI) {
149+
bool Changed = false;
150+
for (auto &UseMO : MI->uses()) {
151+
if (!UseMO.isReg())
152+
continue;
153+
if (UseMO.isTied())
154+
continue;
155+
if (!UseMO.getReg().isVirtual())
156+
continue;
157+
if (!isVectorRegClass(UseMO.getReg()))
158+
continue;
181159

182-
for (auto MO : UseMOs) {
183-
MO->setReg(NewDest);
184-
MO->setIsUndef(false);
160+
if (UseMO.isUndef() || findImplictDefMIFromReg(UseMO.getReg(), MRI))
161+
Changed |= fixupIllOperand(MI, UseMO);
185162
}
186-
return true;
163+
return Changed;
187164
}
188165

189166
bool RISCVInitUndef::handleSubReg(MachineFunction &MF, MachineInstr &MI,
@@ -248,6 +225,23 @@ bool RISCVInitUndef::handleSubReg(MachineFunction &MF, MachineInstr &MI,
248225
return Changed;
249226
}
250227

228+
bool RISCVInitUndef::fixupIllOperand(MachineInstr *MI, MachineOperand &MO) {
229+
230+
LLVM_DEBUG(
231+
dbgs() << "Emitting PseudoRVVInitUndef for implicit vector register "
232+
<< MO.getReg() << '\n');
233+
234+
const TargetRegisterClass *TargetRegClass =
235+
getVRLargestSuperClass(MRI->getRegClass(MO.getReg()));
236+
unsigned Opcode = getUndefInitOpcode(TargetRegClass->getID());
237+
Register NewReg = MRI->createVirtualRegister(TargetRegClass);
238+
BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), TII->get(Opcode), NewReg);
239+
MO.setReg(NewReg);
240+
if (MO.isUndef())
241+
MO.setIsUndef(false);
242+
return true;
243+
}
244+
251245
bool RISCVInitUndef::processBasicBlock(MachineFunction &MF,
252246
MachineBasicBlock &MBB,
253247
const DeadLaneDetector &DLD) {
@@ -274,12 +268,10 @@ bool RISCVInitUndef::processBasicBlock(MachineFunction &MF,
274268
}
275269
}
276270

277-
if (ST->enableSubRegLiveness() && isEarlyClobberMI(MI))
278-
Changed |= handleSubReg(MF, MI, DLD);
279-
if (MI.isImplicitDef()) {
280-
auto DstReg = MI.getOperand(0).getReg();
281-
if (DstReg.isVirtual() && isVectorRegClass(DstReg))
282-
Changed |= handleImplicitDef(MBB, I);
271+
if (isEarlyClobberMI(MI)) {
272+
if (ST->enableSubRegLiveness())
273+
Changed |= handleSubReg(MF, MI, DLD);
274+
Changed |= handleReg(&MI);
283275
}
284276
}
285277
return Changed;
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
2+
; RUN: llc -mtriple=riscv64 -mattr=+v,+f,+m,+zfh,+zvfh \
3+
; RUN: < %s | FileCheck %s
4+
5+
declare <16 x i8> @llvm.vector.extract.v16i8.nxv8i8(<vscale x 8 x i8>, i64 immarg)
6+
declare <vscale x 8 x i8> @llvm.vector.insert.nxv8i8.v16i8(<vscale x 8 x i8>, <16 x i8>, i64 immarg)
7+
declare <vscale x 8 x i8> @llvm.riscv.vslideup.nxv8i8.i64(<vscale x 8 x i8>, <vscale x 8 x i8>, i64, i64, i64 immarg)
8+
declare <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v4i32(<vscale x 2 x i32>, <4 x i32>, i64 immarg)
9+
10+
define void @foo(<vscale x 8 x i8> %0) {
11+
; CHECK-LABEL: foo:
12+
; CHECK: # %bb.0:
13+
; CHECK-NEXT: addi sp, sp, -32
14+
; CHECK-NEXT: .cfi_def_cfa_offset 32
15+
; CHECK-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
16+
; CHECK-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
17+
; CHECK-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
18+
; CHECK-NEXT: .cfi_offset ra, -8
19+
; CHECK-NEXT: .cfi_offset s0, -16
20+
; CHECK-NEXT: .cfi_offset s1, -24
21+
; CHECK-NEXT: vsetvli a0, zero, e8, m1, ta, ma
22+
; CHECK-NEXT: vmv.v.i v9, 0
23+
; CHECK-NEXT: vsetivli zero, 0, e8, m1, tu, ma
24+
; CHECK-NEXT: vslideup.vi v9, v10, 0
25+
; CHECK-NEXT: vsetivli zero, 1, e64, m1, ta, ma
26+
; CHECK-NEXT: vmv.x.s s0, v9
27+
; CHECK-NEXT: vsetivli zero, 0, e8, m1, tu, ma
28+
; CHECK-NEXT: vslideup.vi v8, v9, 0
29+
; CHECK-NEXT: vsetivli zero, 1, e64, m1, ta, ma
30+
; CHECK-NEXT: vmv.x.s s1, v8
31+
; CHECK-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1
32+
; CHECK-NEXT: li a1, 0
33+
; CHECK-NEXT: mv a0, s0
34+
; CHECK-NEXT: mv a2, s1
35+
; CHECK-NEXT: li a3, 0
36+
; CHECK-NEXT: li a4, 0
37+
; CHECK-NEXT: li a5, 0
38+
; CHECK-NEXT: jalr a1
39+
; CHECK-NEXT: j .LBB0_1
40+
%2 = tail call <vscale x 8 x i8> @llvm.vector.insert.nxv8i8.v16i8(<vscale x 8 x i8> undef, <16 x i8> undef, i64 0)
41+
%3 = tail call <vscale x 8 x i8> @llvm.vector.insert.nxv8i8.v16i8(<vscale x 8 x i8> undef, <16 x i8> poison, i64 0)
42+
br label %4
43+
44+
4: ; preds = %4, %1
45+
%5 = tail call <vscale x 8 x i8> @llvm.riscv.vslideup.nxv8i8.i64(<vscale x 8 x i8> zeroinitializer, <vscale x 8 x i8> %2, i64 0, i64 0, i64 0)
46+
%6 = tail call <16 x i8> @llvm.vector.extract.v16i8.nxv8i8(<vscale x 8 x i8> %5, i64 0)
47+
%7 = bitcast <16 x i8> %6 to <2 x i64>
48+
%8 = extractelement <2 x i64> %7, i64 0
49+
%9 = insertvalue [2 x i64] zeroinitializer, i64 %8, 0
50+
%10 = tail call <vscale x 8 x i8> @llvm.riscv.vslideup.nxv8i8.i64(<vscale x 8 x i8> %0, <vscale x 8 x i8> %3, i64 0, i64 0, i64 0)
51+
%11 = tail call <16 x i8> @llvm.vector.extract.v16i8.nxv8i8(<vscale x 8 x i8> %10, i64 0)
52+
%12 = bitcast <16 x i8> %11 to <2 x i64>
53+
%13 = extractelement <2 x i64> %12, i64 0
54+
%14 = insertvalue [2 x i64] zeroinitializer, i64 %13, 0
55+
%15 = tail call fastcc [2 x i64] null([2 x i64] %9, [2 x i64] %14, [2 x i64] zeroinitializer)
56+
br label %4
57+
}

llvm/test/CodeGen/RISCV/rvv/handle-noreg-with-implicit-def.mir

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ tracksRegLiveness: true
77
body: |
88
bb.0.entry:
99
; MIR-LABEL: name: vrgather_all_undef
10-
; MIR: [[PseudoRVVInitUndefM1_:%[0-9]+]]:vr = PseudoRVVInitUndefM1
11-
; MIR-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
12-
; MIR-NEXT: early-clobber %1:vr = PseudoVRGATHER_VI_M1 [[DEF]], killed [[PseudoRVVInitUndefM1_]], 0, 0, 5 /* e32 */, 0 /* tu, mu */
10+
; MIR: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
11+
; MIR-NEXT: [[DEF1:%[0-9]+]]:vr = IMPLICIT_DEF
12+
; MIR-NEXT: [[PseudoRVVInitUndefM1_:%[0-9]+]]:vr = PseudoRVVInitUndefM1
13+
; MIR-NEXT: early-clobber %1:vr = PseudoVRGATHER_VI_M1 [[DEF1]], killed [[PseudoRVVInitUndefM1_]], 0, 0, 5 /* e32 */, 0 /* tu, mu */
1314
; MIR-NEXT: $v8 = COPY %1
1415
; MIR-NEXT: PseudoRET implicit $v8
1516
%2:vr = IMPLICIT_DEF

llvm/test/CodeGen/RISCV/rvv/undef-earlyclobber-chain.mir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ machineFunctionInfo:
7676
body: |
7777
bb.0.entry:
7878
; CHECK-LABEL: name: undef_early_clobber_chain
79-
; CHECK: [[PseudoRVVInitUndefM1_:%[0-9]+]]:vr = PseudoRVVInitUndefM1
80-
; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
79+
; CHECK: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
8180
; CHECK-NEXT: dead $x0 = PseudoVSETIVLI 0, 208 /* e32, m1, ta, ma */, implicit-def $vl, implicit-def $vtype
81+
; CHECK-NEXT: [[PseudoRVVInitUndefM1_:%[0-9]+]]:vr = PseudoRVVInitUndefM1
8282
; CHECK-NEXT: early-clobber %1:vr = PseudoVRGATHER_VI_M1 undef [[DEF]], [[PseudoRVVInitUndefM1_]], 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
8383
; CHECK-NEXT: $v8 = COPY %1
8484
; CHECK-NEXT: PseudoRET implicit $v8

0 commit comments

Comments
 (0)