Skip to content

Commit 9cf6759

Browse files
committed
[RISCVRVVInitUndef] Remove implicit single use assumption for IMPLICIT_DEF
The code was written with the implicit assumption that each IMPLICIT_DEF either a) the tied operand, or b) an untied source, but not both. This is true right now, but an upcoming change may allow CSE of IMPLICIT_DEFs in some cases, so let's rewrite the code to handle that possibility. I added an MIR case which demonstrates the multiple use IMPLICIT_DEF. To my knowledge, this is not a reachable configuration from IR right now. As an aside, this makes the structure a much closer match with the sub-reg liveness case, and we can probably just merge these routines. (Future work.) Differential Revision: https://reviews.llvm.org/D156477
1 parent ef4bf1d commit 9cf6759

File tree

3 files changed

+133
-39
lines changed

3 files changed

+133
-39
lines changed

llvm/lib/Target/RISCV/RISCVRVVInitUndef.cpp

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -118,65 +118,57 @@ static unsigned getUndefInitOpcode(unsigned RegClassID) {
118118
}
119119
}
120120

121+
static bool isEarlyClobberMI(MachineInstr &MI) {
122+
return llvm::any_of(MI.defs(), [](const MachineOperand &DefMO) {
123+
return DefMO.isReg() && DefMO.isEarlyClobber();
124+
});
125+
}
126+
121127
bool RISCVInitUndef::handleImplicitDef(MachineBasicBlock &MBB,
122128
MachineBasicBlock::iterator &Inst) {
123-
const TargetRegisterInfo &TRI =
124-
*MBB.getParent()->getSubtarget().getRegisterInfo();
125-
126129
assert(Inst->getOpcode() == TargetOpcode::IMPLICIT_DEF);
127130

128131
Register Reg = Inst->getOperand(0).getReg();
129132
if (!Reg.isVirtual())
130133
return false;
131134

132-
bool NeedPseudoInit = false;
135+
bool HasOtherUse = false;
133136
SmallVector<MachineOperand *, 1> UseMOs;
134137
for (MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
135-
MachineInstr *UserMI = MO.getParent();
136-
137-
bool HasEarlyClobber = false;
138-
bool TiedToDef = false;
139-
for (MachineOperand &UserMO : UserMI->operands()) {
140-
if (!UserMO.isReg())
141-
continue;
142-
if (UserMO.isEarlyClobber())
143-
HasEarlyClobber = true;
144-
if (UserMO.isUse() && UserMO.isTied() &&
145-
TRI.regsOverlap(UserMO.getReg(), Reg))
146-
TiedToDef = true;
147-
}
148-
if (HasEarlyClobber && !TiedToDef) {
149-
NeedPseudoInit = true;
150-
UseMOs.push_back(&MO);
138+
if (isEarlyClobberMI(*MO.getParent())) {
139+
if (MO.isUse() && !MO.isTied())
140+
UseMOs.push_back(&MO);
141+
else
142+
HasOtherUse = true;
151143
}
152144
}
153145

154-
if (!NeedPseudoInit)
146+
if (UseMOs.empty())
155147
return false;
156148

157149
LLVM_DEBUG(
158150
dbgs() << "Emitting PseudoRVVInitUndef for implicit vector register "
159151
<< Reg << '\n');
160152

161-
unsigned RegClassID = getVRLargestSuperClass(MRI->getRegClass(Reg))->getID();
162-
unsigned Opcode = getUndefInitOpcode(RegClassID);
153+
const TargetRegisterClass *TargetRegClass =
154+
getVRLargestSuperClass(MRI->getRegClass(Reg));
155+
unsigned Opcode = getUndefInitOpcode(TargetRegClass->getID());
163156

164-
BuildMI(MBB, Inst, Inst->getDebugLoc(), TII->get(Opcode), Reg);
157+
Register NewDest = Reg;
158+
if (HasOtherUse)
159+
NewDest = MRI->createVirtualRegister(TargetRegClass);
160+
BuildMI(MBB, Inst, Inst->getDebugLoc(), TII->get(Opcode), NewDest);
165161

166-
Inst = MBB.erase(Inst);
162+
if (!HasOtherUse)
163+
Inst = MBB.erase(Inst);
167164

168-
for (auto MO : UseMOs)
165+
for (auto MO : UseMOs) {
166+
MO->setReg(NewDest);
169167
MO->setIsUndef(false);
170-
168+
}
171169
return true;
172170
}
173171

174-
static bool isEarlyClobberMI(MachineInstr &MI) {
175-
return llvm::any_of(MI.defs(), [](const MachineOperand &DefMO) {
176-
return DefMO.isReg() && DefMO.isEarlyClobber();
177-
});
178-
}
179-
180172
bool RISCVInitUndef::handleSubReg(MachineFunction &MF, MachineInstr &MI,
181173
const DeadLaneDetector &DLD) {
182174
bool Changed = false;

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
22
; RUN: llc -mtriple riscv64 -mattr=+v -riscv-enable-subreg-liveness < %s | FileCheck %s
33

4+
define <vscale x 2 x float> @vrgather_all_undef(ptr %p) {
5+
; CHECK-LABEL: vrgather_all_undef:
6+
; CHECK: # %bb.0: # %entry
7+
; CHECK-NEXT: vsetivli zero, 0, e32, m1, ta, ma
8+
; CHECK-NEXT: vrgather.vi v8, v9, 0
9+
; CHECK-NEXT: ret
10+
entry:
11+
%0 = tail call <vscale x 2 x float> @llvm.riscv.vrgather.vx.nxv2f32.i64(<vscale x 2 x float> undef, <vscale x 2 x float> undef, i64 0, i64 0)
12+
ret <vscale x 2 x float> %0
13+
}
14+
415
define dso_local signext i32 @undef_early_clobber_chain() {
516
; CHECK-LABEL: undef_early_clobber_chain:
617
; CHECK: # %bb.0: # %entry
@@ -25,14 +36,14 @@ entry:
2536
define internal void @SubRegLivenessUndefInPhi(i64 %cond) {
2637
; CHECK-LABEL: SubRegLivenessUndefInPhi:
2738
; CHECK: # %bb.0: # %start
28-
; CHECK-NEXT: blez a0, .LBB1_2
39+
; CHECK-NEXT: blez a0, .LBB2_2
2940
; CHECK-NEXT: # %bb.1: # %Cond1
3041
; CHECK-NEXT: vsetvli a0, zero, e16, mf4, ta, ma
3142
; CHECK-NEXT: vid.v v8
3243
; CHECK-NEXT: vadd.vi v10, v8, 1
3344
; CHECK-NEXT: vadd.vi v12, v8, 3
34-
; CHECK-NEXT: j .LBB1_3
35-
; CHECK-NEXT: .LBB1_2: # %Cond2
45+
; CHECK-NEXT: j .LBB2_3
46+
; CHECK-NEXT: .LBB2_2: # %Cond2
3647
; CHECK-NEXT: vsetvli a0, zero, e16, mf4, ta, ma
3748
; CHECK-NEXT: vid.v v9
3849
; CHECK-NEXT: csrr a0, vlenb
@@ -48,7 +59,7 @@ define internal void @SubRegLivenessUndefInPhi(i64 %cond) {
4859
; CHECK-NEXT: vadd.vi v9, v9, 3
4960
; CHECK-NEXT: vsetvli zero, a1, e16, m1, ta, ma
5061
; CHECK-NEXT: vslideup.vx v12, v9, a0
51-
; CHECK-NEXT: .LBB1_3: # %UseSR
62+
; CHECK-NEXT: .LBB2_3: # %UseSR
5263
; CHECK-NEXT: vl1r.v v14, (zero)
5364
; CHECK-NEXT: vsetivli zero, 4, e8, m1, ta, ma
5465
; CHECK-NEXT: vrgatherei16.vv v13, v14, v8
@@ -104,7 +115,7 @@ define internal void @SubRegLivenessUndef() {
104115
; CHECK-NEXT: vid.v v8
105116
; CHECK-NEXT: vadd.vi v10, v8, 1
106117
; CHECK-NEXT: vadd.vi v12, v8, 3
107-
; CHECK-NEXT: .LBB2_1: # %loopIR3.i.i
118+
; CHECK-NEXT: .LBB3_1: # %loopIR3.i.i
108119
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
109120
; CHECK-NEXT: vl1r.v v14, (zero)
110121
; CHECK-NEXT: vsetivli zero, 4, e8, m1, ta, ma
@@ -117,7 +128,7 @@ define internal void @SubRegLivenessUndef() {
117128
; CHECK-NEXT: vsetvli a0, zero, e8, m1, ta, ma
118129
; CHECK-NEXT: vand.vv v9, v9, v11
119130
; CHECK-NEXT: vs1r.v v9, (zero)
120-
; CHECK-NEXT: j .LBB2_1
131+
; CHECK-NEXT: j .LBB3_1
121132
loopIR.preheader.i.i:
122133
%v15 = tail call <vscale x 1 x i16> @llvm.experimental.stepvector.nxv1i16()
123134
%v17 = tail call <vscale x 8 x i16> @llvm.vector.insert.nxv8i16.nxv1i16(<vscale x 8 x i16> poison, <vscale x 1 x i16> %v15, i64 0)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=riscv32 -mattr=+v -riscv-enable-subreg-liveness -run-pass riscv-init-undef -run-pass machineverifier %s -o - | FileCheck %s
3+
4+
--- |
5+
source_filename = "<stdin>"
6+
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
7+
target triple = "riscv64"
8+
9+
define <vscale x 2 x float> @undef_early_clobber_chain(ptr %p) #0 {
10+
entry:
11+
%0 = tail call <vscale x 2 x float> @llvm.riscv.vrgather.vx.nxv2f32.i64(<vscale x 2 x float> undef, <vscale x 2 x float> undef, i64 0, i64 0)
12+
ret <vscale x 2 x float> %0
13+
}
14+
15+
declare <vscale x 2 x float> @llvm.riscv.vrgather.vx.nxv2f32.i64(<vscale x 2 x float>, <vscale x 2 x float>, i64, i64) #1
16+
17+
attributes #0 = { "target-features"="+v" }
18+
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(none) "target-features"="+v" }
19+
20+
...
21+
---
22+
name: undef_early_clobber_chain
23+
alignment: 4
24+
exposesReturnsTwice: false
25+
legalized: false
26+
regBankSelected: false
27+
selected: false
28+
failedISel: false
29+
tracksRegLiveness: true
30+
hasWinCFI: false
31+
callsEHReturn: false
32+
callsUnwindInit: false
33+
hasEHCatchret: false
34+
hasEHScopes: false
35+
hasEHFunclets: false
36+
isOutlined: false
37+
debugInstrRef: false
38+
failsVerification: false
39+
tracksDebugUserValues: false
40+
registers:
41+
- { id: 0, class: gpr, preferred-register: '' }
42+
- { id: 1, class: vr, preferred-register: '' }
43+
- { id: 2, class: vr, preferred-register: '' }
44+
- { id: 3, class: vr, preferred-register: '' }
45+
liveins: []
46+
frameInfo:
47+
isFrameAddressTaken: false
48+
isReturnAddressTaken: false
49+
hasStackMap: false
50+
hasPatchPoint: false
51+
stackSize: 0
52+
offsetAdjustment: 0
53+
maxAlignment: 1
54+
adjustsStack: false
55+
hasCalls: false
56+
stackProtector: ''
57+
functionContext: ''
58+
maxCallFrameSize: 4294967295
59+
cvBytesOfCalleeSavedRegisters: 0
60+
hasOpaqueSPAdjustment: false
61+
hasVAStart: false
62+
hasMustTailInVarArgFunc: false
63+
hasTailCall: false
64+
localFrameSize: 0
65+
savePoint: ''
66+
restorePoint: ''
67+
fixedStack: []
68+
stack: []
69+
entry_values: []
70+
callSites: []
71+
debugValueSubstitutions: []
72+
constants: []
73+
machineFunctionInfo:
74+
varArgsFrameIndex: 0
75+
varArgsSaveSize: 0
76+
body: |
77+
bb.0.entry:
78+
; CHECK-LABEL: name: undef_early_clobber_chain
79+
; CHECK: [[PseudoRVVInitUndefM1_:%[0-9]+]]:vr = PseudoRVVInitUndefM1
80+
; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
81+
; CHECK-NEXT: dead $x0 = PseudoVSETIVLI 0, 208 /* e32, m1, ta, ma */, implicit-def $vl, implicit-def $vtype
82+
; CHECK-NEXT: early-clobber %1:vr = PseudoVRGATHER_VI_M1 undef [[DEF]], [[PseudoRVVInitUndefM1_]], 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
83+
; CHECK-NEXT: $v8 = COPY %1
84+
; CHECK-NEXT: PseudoRET implicit $v8
85+
%2:vr = IMPLICIT_DEF
86+
dead $x0 = PseudoVSETIVLI 0, 208 /* e32, m1, ta, ma */, implicit-def $vl, implicit-def $vtype
87+
early-clobber %1:vr = PseudoVRGATHER_VI_M1 undef %2, undef %2, 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
88+
$v8 = COPY %1
89+
PseudoRET implicit $v8
90+
91+
...

0 commit comments

Comments
 (0)