Skip to content

[RISCV] Copy AVLs whose LiveIntervals aren't extendable in insertVSETVLI #98342

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 24 additions & 13 deletions llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -950,12 +950,6 @@ void RISCVInsertVSETVLI::forwardVSETVLIAVL(VSETVLIInfo &Info) const {
VSETVLIInfo DefInstrInfo = getInfoForVSETVLI(*DefMI);
if (!DefInstrInfo.hasSameVLMAX(Info))
return;
// If the AVL is a register with multiple definitions, don't forward it. We
// might not be able to extend its LiveInterval without clobbering other val
// nums.
if (DefInstrInfo.hasAVLReg() &&
!LIS->getInterval(DefInstrInfo.getAVLReg()).containsOneValue())
return;
Info.setAVL(DefInstrInfo);
}

Expand Down Expand Up @@ -1149,15 +1143,32 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
.addImm(Info.encodeVTYPE());
if (LIS) {
LIS->InsertMachineInstrInMaps(*MI);
// Normally the AVL's live range will already extend past the inserted
// vsetvli because the pseudos below will already use the AVL. But this
// isn't always the case, e.g. PseudoVMV_X_S doesn't have an AVL operand or
// we've taken the AVL from the VL output of another vsetvli.
LiveInterval &LI = LIS->getInterval(AVLReg);
SlotIndex SI = LIS->getInstructionIndex(*MI).getRegSlot();
assert((LI.liveAt(SI) && LI.getVNInfoAt(SI) == Info.getAVLVNInfo()) ||
(!LI.liveAt(SI) && LI.containsOneValue()));
LIS->extendToIndices(LI, SI);
// If the AVL value isn't live at MI, do a quick check to see if it's easily
// extendable. Otherwise, we need to copy it.
if (LI.getVNInfoBefore(SI) != Info.getAVLVNInfo()) {
if (!LI.liveAt(SI) && LI.containsOneValue())
LIS->extendToIndices(LI, SI);
else {
Register AVLCopyReg =
MRI->createVirtualRegister(&RISCV::GPRNoX0RegClass);
MachineBasicBlock::iterator II;
if (Info.getAVLVNInfo()->isPHIDef())
II = LIS->getMBBFromIndex(Info.getAVLVNInfo()->def)->getFirstNonPHI();
else {
II = LIS->getInstructionFromIndex(Info.getAVLVNInfo()->def);
II = std::next(II);
}
assert(II.isValid());
auto AVLCopy =
BuildMI(*II->getParent(), II, DL, TII->get(RISCV::COPY), AVLCopyReg)
.addReg(AVLReg);
LIS->InsertMachineInstrInMaps(*AVLCopy);
MI->getOperand(1).setReg(AVLCopyReg);
LIS->createAndComputeVirtRegInterval(AVLCopyReg);
}
}
}
}

Expand Down
11 changes: 6 additions & 5 deletions llvm/test/CodeGen/RISCV/rvv/vsetvli-insert-crossbb.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1126,12 +1126,13 @@ exit:
ret void
}

; Check that we don't forward an AVL if we wouldn't be able to extend its
; LiveInterval without clobbering other val nos.
define <vscale x 4 x i32> @unforwardable_avl(i64 %n, <vscale x 4 x i32> %v, i1 %cmp) {
; CHECK-LABEL: unforwardable_avl:
; Check that if we forward an AVL whose value is clobbered in its LiveInterval
; we emit a copy instead.
define <vscale x 4 x i32> @clobbered_forwarded_avl(i64 %n, <vscale x 4 x i32> %v, i1 %cmp) {
; CHECK-LABEL: clobbered_forwarded_avl:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetvli a2, a0, e32, m2, ta, ma
; CHECK-NEXT: mv a2, a0
; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma
; CHECK-NEXT: andi a1, a1, 1
; CHECK-NEXT: .LBB27_1: # %for.body
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
Expand Down
75 changes: 70 additions & 5 deletions llvm/test/CodeGen/RISCV/rvv/vsetvli-insert-crossbb.mir
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,11 @@
ret void
}

define void @unforwardable_avl() {
define void @clobberred_forwarded_avl() {
ret void
}

define void @clobberred_forwarded_phi_avl() {
ret void
}

Expand Down Expand Up @@ -995,16 +999,17 @@ body: |
PseudoBR %bb.1
...
---
name: unforwardable_avl
name: clobberred_forwarded_avl
tracksRegLiveness: true
body: |
; CHECK-LABEL: name: unforwardable_avl
; CHECK-LABEL: name: clobberred_forwarded_avl
; CHECK: bb.0:
; CHECK-NEXT: successors: %bb.1(0x80000000)
; CHECK-NEXT: liveins: $x10, $v8m2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: %avl:gprnox0 = COPY $x10
; CHECK-NEXT: %outvl:gprnox0 = PseudoVSETVLI %avl, 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY %avl
; CHECK-NEXT: dead %outvl:gprnox0 = PseudoVSETVLI %avl, 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors: %bb.2(0x80000000)
Expand All @@ -1017,7 +1022,7 @@ body: |
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: dead [[PseudoVSETVLIX0_:%[0-9]+]]:gpr = PseudoVSETVLIX0 killed $x0, 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
; CHECK-NEXT: renamable $v10m2 = PseudoVADD_VV_M2 undef renamable $v10m2, renamable $v8m2, renamable $v8m2, -1, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: dead $x0 = PseudoVSETVLI %outvl, 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
; CHECK-NEXT: dead $x0 = PseudoVSETVLI [[COPY]], 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
; CHECK-NEXT: renamable $v8m2 = PseudoVADD_VV_M2 undef renamable $v8m2, killed renamable $v10m2, renamable $v8m2, $noreg, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: PseudoRET implicit $v8m2
bb.0:
Expand All @@ -1034,3 +1039,63 @@ body: |
renamable $v10m2 = PseudoVADD_VV_M2 undef renamable $v10m2, renamable $v8m2, renamable $v8m2, -1, 5, 0
renamable $v8m2 = PseudoVADD_VV_M2 undef renamable $v8m2, killed renamable $v10m2, killed renamable $v8m2, %outvl:gprnox0, 5, 0
PseudoRET implicit $v8m2
...
---
name: clobberred_forwarded_phi_avl
tracksRegLiveness: true
body: |
; CHECK-LABEL: name: clobberred_forwarded_phi_avl
; CHECK: bb.0:
; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000)
; CHECK-NEXT: liveins: $x10, $x11, $v8m2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: %v:vrm2 = COPY $v8m2
; CHECK-NEXT: [[ADDI:%[0-9]+]]:gprnox0 = ADDI $x0, 1
; CHECK-NEXT: %x:gpr = COPY $x10
; CHECK-NEXT: %y:gpr = COPY $x11
; CHECK-NEXT: BEQ %x, %y, %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors: %bb.2(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[ADDI:%[0-9]+]]:gprnox0 = ADDI $x0, 2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: successors: %bb.3(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY [[ADDI]]
; CHECK-NEXT: dead %outvl:gprnox0 = PseudoVSETVLI [[ADDI]], 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.3:
; CHECK-NEXT: successors: %bb.4(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: dead [[ADDI:%[0-9]+]]:gprnox0 = ADDI [[ADDI]], 1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.4:
; CHECK-NEXT: dead [[PseudoVSETVLIX0_:%[0-9]+]]:gpr = PseudoVSETVLIX0 killed $x0, 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
; CHECK-NEXT: renamable $v10m2 = PseudoVADD_VV_M2 undef renamable $v10m2, %v, %v, -1, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: dead $x0 = PseudoVSETVLI [[COPY]], 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
; CHECK-NEXT: renamable $v8m2 = PseudoVADD_VV_M2 undef renamable $v8m2, killed renamable $v10m2, %v, $noreg, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: PseudoRET implicit $v8m2
bb.0:
liveins: $x10, $x11, $v8m2
%v:vrm2 = COPY $v8m2
%a:gpr = ADDI $x0, 1
%x:gpr = COPY $x10
%y:gpr = COPY $x11
BEQ %x, %y, %bb.2

bb.1:
%b:gpr = ADDI $x0, 2

bb.2:
%avl:gprnox0 = PHI %a, %bb.0, %b, %bb.1
%outvl:gprnox0 = PseudoVSETVLI %avl:gprnox0, 209, implicit-def dead $vl, implicit-def dead $vtype

bb.3:
%avl:gprnox0 = ADDI %avl:gprnox0, 1

bb.4:
renamable $v10m2 = PseudoVADD_VV_M2 undef renamable $v10m2, %v, %v, -1, 5, 0
renamable $v8m2 = PseudoVADD_VV_M2 undef renamable $v8m2, killed renamable $v10m2, killed %v, %outvl:gprnox0, 5, 0
PseudoRET implicit $v8m2
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ define ptr @foo(ptr %a0, ptr %a1, i64 %a2) {
; CHECK-NEXT: mv a3, a0
; CHECK-NEXT: .LBB0_3: # %do.body
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: vsetvli zero, a4, e8, m8, ta, ma
; CHECK-NEXT: vle8.v v8, (a1)
; CHECK-NEXT: vse8.v v8, (a3)
; CHECK-NEXT: add a3, a3, a4
Expand Down
Loading