Skip to content

Commit 557ef04

Browse files
authored
[RISCV] Copy AVLs whose LiveIntervals aren't extendable in insertVSETVLI (llvm#98342)
Currently before forwarding an AVL we do a simple non-exhaustive check to see if its LiveInterval is extendable. But we also need to check for this when we're extending an AVL's LiveInterval via merging the VSETVLIInfos in transferBefore with equally zero AVLs. Rather than trying to conservatively prevent these cases, this inserts a copy of the AVL instead if we don't know we'll be able to extend it. This is likely to be more robust, and even if the extra copy is undesirable these cases should be rare in practice.
1 parent 34bfed6 commit 557ef04

File tree

4 files changed

+100
-24
lines changed

4 files changed

+100
-24
lines changed

llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -950,12 +950,6 @@ void RISCVInsertVSETVLI::forwardVSETVLIAVL(VSETVLIInfo &Info) const {
950950
VSETVLIInfo DefInstrInfo = getInfoForVSETVLI(*DefMI);
951951
if (!DefInstrInfo.hasSameVLMAX(Info))
952952
return;
953-
// If the AVL is a register with multiple definitions, don't forward it. We
954-
// might not be able to extend its LiveInterval without clobbering other val
955-
// nums.
956-
if (DefInstrInfo.hasAVLReg() &&
957-
!LIS->getInterval(DefInstrInfo.getAVLReg()).containsOneValue())
958-
return;
959953
Info.setAVL(DefInstrInfo);
960954
}
961955

@@ -1149,15 +1143,32 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
11491143
.addImm(Info.encodeVTYPE());
11501144
if (LIS) {
11511145
LIS->InsertMachineInstrInMaps(*MI);
1152-
// Normally the AVL's live range will already extend past the inserted
1153-
// vsetvli because the pseudos below will already use the AVL. But this
1154-
// isn't always the case, e.g. PseudoVMV_X_S doesn't have an AVL operand or
1155-
// we've taken the AVL from the VL output of another vsetvli.
11561146
LiveInterval &LI = LIS->getInterval(AVLReg);
11571147
SlotIndex SI = LIS->getInstructionIndex(*MI).getRegSlot();
1158-
assert((LI.liveAt(SI) && LI.getVNInfoAt(SI) == Info.getAVLVNInfo()) ||
1159-
(!LI.liveAt(SI) && LI.containsOneValue()));
1160-
LIS->extendToIndices(LI, SI);
1148+
// If the AVL value isn't live at MI, do a quick check to see if it's easily
1149+
// extendable. Otherwise, we need to copy it.
1150+
if (LI.getVNInfoBefore(SI) != Info.getAVLVNInfo()) {
1151+
if (!LI.liveAt(SI) && LI.containsOneValue())
1152+
LIS->extendToIndices(LI, SI);
1153+
else {
1154+
Register AVLCopyReg =
1155+
MRI->createVirtualRegister(&RISCV::GPRNoX0RegClass);
1156+
MachineBasicBlock::iterator II;
1157+
if (Info.getAVLVNInfo()->isPHIDef())
1158+
II = LIS->getMBBFromIndex(Info.getAVLVNInfo()->def)->getFirstNonPHI();
1159+
else {
1160+
II = LIS->getInstructionFromIndex(Info.getAVLVNInfo()->def);
1161+
II = std::next(II);
1162+
}
1163+
assert(II.isValid());
1164+
auto AVLCopy =
1165+
BuildMI(*II->getParent(), II, DL, TII->get(RISCV::COPY), AVLCopyReg)
1166+
.addReg(AVLReg);
1167+
LIS->InsertMachineInstrInMaps(*AVLCopy);
1168+
MI->getOperand(1).setReg(AVLCopyReg);
1169+
LIS->createAndComputeVirtRegInterval(AVLCopyReg);
1170+
}
1171+
}
11611172
}
11621173
}
11631174

llvm/test/CodeGen/RISCV/rvv/vsetvli-insert-crossbb.ll

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,12 +1126,13 @@ exit:
11261126
ret void
11271127
}
11281128

1129-
; Check that we don't forward an AVL if we wouldn't be able to extend its
1130-
; LiveInterval without clobbering other val nos.
1131-
define <vscale x 4 x i32> @unforwardable_avl(i64 %n, <vscale x 4 x i32> %v, i1 %cmp) {
1132-
; CHECK-LABEL: unforwardable_avl:
1129+
; Check that if we forward an AVL whose value is clobbered in its LiveInterval
1130+
; we emit a copy instead.
1131+
define <vscale x 4 x i32> @clobbered_forwarded_avl(i64 %n, <vscale x 4 x i32> %v, i1 %cmp) {
1132+
; CHECK-LABEL: clobbered_forwarded_avl:
11331133
; CHECK: # %bb.0: # %entry
1134-
; CHECK-NEXT: vsetvli a2, a0, e32, m2, ta, ma
1134+
; CHECK-NEXT: mv a2, a0
1135+
; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma
11351136
; CHECK-NEXT: andi a1, a1, 1
11361137
; CHECK-NEXT: .LBB27_1: # %for.body
11371138
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1

llvm/test/CodeGen/RISCV/rvv/vsetvli-insert-crossbb.mir

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,11 @@
134134
ret void
135135
}
136136

137-
define void @unforwardable_avl() {
137+
define void @clobberred_forwarded_avl() {
138+
ret void
139+
}
140+
141+
define void @clobberred_forwarded_phi_avl() {
138142
ret void
139143
}
140144

@@ -995,16 +999,17 @@ body: |
995999
PseudoBR %bb.1
9961000
...
9971001
---
998-
name: unforwardable_avl
1002+
name: clobberred_forwarded_avl
9991003
tracksRegLiveness: true
10001004
body: |
1001-
; CHECK-LABEL: name: unforwardable_avl
1005+
; CHECK-LABEL: name: clobberred_forwarded_avl
10021006
; CHECK: bb.0:
10031007
; CHECK-NEXT: successors: %bb.1(0x80000000)
10041008
; CHECK-NEXT: liveins: $x10, $v8m2
10051009
; CHECK-NEXT: {{ $}}
10061010
; CHECK-NEXT: %avl:gprnox0 = COPY $x10
1007-
; CHECK-NEXT: %outvl:gprnox0 = PseudoVSETVLI %avl, 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
1011+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY %avl
1012+
; CHECK-NEXT: dead %outvl:gprnox0 = PseudoVSETVLI %avl, 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
10081013
; CHECK-NEXT: {{ $}}
10091014
; CHECK-NEXT: bb.1:
10101015
; CHECK-NEXT: successors: %bb.2(0x80000000)
@@ -1017,7 +1022,7 @@ body: |
10171022
; CHECK-NEXT: {{ $}}
10181023
; CHECK-NEXT: dead [[PseudoVSETVLIX0_:%[0-9]+]]:gpr = PseudoVSETVLIX0 killed $x0, 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
10191024
; CHECK-NEXT: renamable $v10m2 = PseudoVADD_VV_M2 undef renamable $v10m2, renamable $v8m2, renamable $v8m2, -1, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
1020-
; CHECK-NEXT: dead $x0 = PseudoVSETVLI %outvl, 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
1025+
; CHECK-NEXT: dead $x0 = PseudoVSETVLI [[COPY]], 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
10211026
; 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
10221027
; CHECK-NEXT: PseudoRET implicit $v8m2
10231028
bb.0:
@@ -1034,3 +1039,63 @@ body: |
10341039
renamable $v10m2 = PseudoVADD_VV_M2 undef renamable $v10m2, renamable $v8m2, renamable $v8m2, -1, 5, 0
10351040
renamable $v8m2 = PseudoVADD_VV_M2 undef renamable $v8m2, killed renamable $v10m2, killed renamable $v8m2, %outvl:gprnox0, 5, 0
10361041
PseudoRET implicit $v8m2
1042+
...
1043+
---
1044+
name: clobberred_forwarded_phi_avl
1045+
tracksRegLiveness: true
1046+
body: |
1047+
; CHECK-LABEL: name: clobberred_forwarded_phi_avl
1048+
; CHECK: bb.0:
1049+
; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000)
1050+
; CHECK-NEXT: liveins: $x10, $x11, $v8m2
1051+
; CHECK-NEXT: {{ $}}
1052+
; CHECK-NEXT: %v:vrm2 = COPY $v8m2
1053+
; CHECK-NEXT: [[ADDI:%[0-9]+]]:gprnox0 = ADDI $x0, 1
1054+
; CHECK-NEXT: %x:gpr = COPY $x10
1055+
; CHECK-NEXT: %y:gpr = COPY $x11
1056+
; CHECK-NEXT: BEQ %x, %y, %bb.2
1057+
; CHECK-NEXT: {{ $}}
1058+
; CHECK-NEXT: bb.1:
1059+
; CHECK-NEXT: successors: %bb.2(0x80000000)
1060+
; CHECK-NEXT: {{ $}}
1061+
; CHECK-NEXT: [[ADDI:%[0-9]+]]:gprnox0 = ADDI $x0, 2
1062+
; CHECK-NEXT: {{ $}}
1063+
; CHECK-NEXT: bb.2:
1064+
; CHECK-NEXT: successors: %bb.3(0x80000000)
1065+
; CHECK-NEXT: {{ $}}
1066+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY [[ADDI]]
1067+
; CHECK-NEXT: dead %outvl:gprnox0 = PseudoVSETVLI [[ADDI]], 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
1068+
; CHECK-NEXT: {{ $}}
1069+
; CHECK-NEXT: bb.3:
1070+
; CHECK-NEXT: successors: %bb.4(0x80000000)
1071+
; CHECK-NEXT: {{ $}}
1072+
; CHECK-NEXT: dead [[ADDI:%[0-9]+]]:gprnox0 = ADDI [[ADDI]], 1
1073+
; CHECK-NEXT: {{ $}}
1074+
; CHECK-NEXT: bb.4:
1075+
; CHECK-NEXT: dead [[PseudoVSETVLIX0_:%[0-9]+]]:gpr = PseudoVSETVLIX0 killed $x0, 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
1076+
; CHECK-NEXT: renamable $v10m2 = PseudoVADD_VV_M2 undef renamable $v10m2, %v, %v, -1, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
1077+
; CHECK-NEXT: dead $x0 = PseudoVSETVLI [[COPY]], 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
1078+
; CHECK-NEXT: renamable $v8m2 = PseudoVADD_VV_M2 undef renamable $v8m2, killed renamable $v10m2, %v, $noreg, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
1079+
; CHECK-NEXT: PseudoRET implicit $v8m2
1080+
bb.0:
1081+
liveins: $x10, $x11, $v8m2
1082+
%v:vrm2 = COPY $v8m2
1083+
%a:gpr = ADDI $x0, 1
1084+
%x:gpr = COPY $x10
1085+
%y:gpr = COPY $x11
1086+
BEQ %x, %y, %bb.2
1087+
1088+
bb.1:
1089+
%b:gpr = ADDI $x0, 2
1090+
1091+
bb.2:
1092+
%avl:gprnox0 = PHI %a, %bb.0, %b, %bb.1
1093+
%outvl:gprnox0 = PseudoVSETVLI %avl:gprnox0, 209, implicit-def dead $vl, implicit-def dead $vtype
1094+
1095+
bb.3:
1096+
%avl:gprnox0 = ADDI %avl:gprnox0, 1
1097+
1098+
bb.4:
1099+
renamable $v10m2 = PseudoVADD_VV_M2 undef renamable $v10m2, %v, %v, -1, 5, 0
1100+
renamable $v8m2 = PseudoVADD_VV_M2 undef renamable $v8m2, killed renamable $v10m2, killed %v, %outvl:gprnox0, 5, 0
1101+
PseudoRET implicit $v8m2

llvm/test/Transforms/LoopStrengthReduce/RISCV/lsr-drop-solution.ll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ define ptr @foo(ptr %a0, ptr %a1, i64 %a2) {
2020
; CHECK-NEXT: mv a3, a0
2121
; CHECK-NEXT: .LBB0_3: # %do.body
2222
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
23-
; CHECK-NEXT: vsetvli zero, a4, e8, m8, ta, ma
2423
; CHECK-NEXT: vle8.v v8, (a1)
2524
; CHECK-NEXT: vse8.v v8, (a3)
2625
; CHECK-NEXT: add a3, a3, a4

0 commit comments

Comments
 (0)