Skip to content

Commit f93af23

Browse files
committed
[RISCV] Allow vsetvlis with same register AVL in doLocalPostpass
One of the requirements to be able to delete a vsetvli in the backwards pass is that the preceding vsetvli must have the same AVL. This handles the case where the AVLs are registers by using MachineRegisterInfo to check if there are any definitions between the two vsetvlis. The Dominates helper was taken from MachineDominatorTree and scans through the instructions in the block which is less than ideal. But it's only called whenever the two registers are the same, which should be rare. This also replaces the equally-zero check with the existing hasEquallyZeroAVL function, which is needed to handle the case where the AVLs are the same. Based off the draft patch in llvm#75544 (comment).
1 parent 9e1ad3c commit f93af23

File tree

3 files changed

+43
-24
lines changed

3 files changed

+43
-24
lines changed

llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,20 +1459,6 @@ static void doUnion(DemandedFields &A, DemandedFields B) {
14591459
A.MaskPolicy |= B.MaskPolicy;
14601460
}
14611461

1462-
static bool isNonZeroAVL(const MachineOperand &MO,
1463-
const MachineRegisterInfo &MRI) {
1464-
if (MO.isReg()) {
1465-
if (MO.getReg() == RISCV::X0)
1466-
return true;
1467-
if (MachineInstr *MI = MRI.getVRegDef(MO.getReg());
1468-
MI && isNonZeroLoadImmediate(*MI))
1469-
return true;
1470-
return false;
1471-
}
1472-
assert(MO.isImm());
1473-
return 0 != MO.getImm();
1474-
}
1475-
14761462
// Return true if we can mutate PrevMI to match MI without changing any the
14771463
// fields which would be observed.
14781464
static bool canMutatePriorConfig(const MachineInstr &PrevMI,
@@ -1491,16 +1477,52 @@ static bool canMutatePriorConfig(const MachineInstr &PrevMI,
14911477
if (Used.VLZeroness) {
14921478
if (isVLPreservingConfig(PrevMI))
14931479
return false;
1494-
if (!isNonZeroAVL(MI.getOperand(1), MRI) ||
1495-
!isNonZeroAVL(PrevMI.getOperand(1), MRI))
1480+
if (!getInfoForVSETVLI(PrevMI).hasEquallyZeroAVL(getInfoForVSETVLI(MI),
1481+
MRI))
14961482
return false;
14971483
}
14981484

1499-
// TODO: Track whether the register is defined between
1500-
// PrevMI and MI.
15011485
if (MI.getOperand(1).isReg() &&
15021486
RISCV::X0 != MI.getOperand(1).getReg())
15031487
return false;
1488+
1489+
// Taken from MachineDominatorTree::dominates
1490+
auto Dominates = [](const MachineInstr &A, const MachineInstr &B) {
1491+
assert(A.getParent() == B.getParent());
1492+
// Loop through the basic block until we find A or B.
1493+
MachineBasicBlock::const_iterator I = A.getParent()->begin();
1494+
for (; I != A && I != B; ++I)
1495+
/*empty*/;
1496+
return I == A;
1497+
};
1498+
1499+
// Given A and B are in the same block and A comes before (dominates) B,
1500+
// return whether or not Reg is defined between A and B.
1501+
auto IsDefinedBetween = [&MRI, &Dominates](const Register Reg,
1502+
const MachineInstr &A,
1503+
const MachineInstr &B) {
1504+
assert(Dominates(A, B));
1505+
for (const auto &Def : MRI.def_instructions(Reg)) {
1506+
if (Def.getParent() != A.getParent())
1507+
continue;
1508+
// If B defines Reg, assume it early clobbers for now.
1509+
if (&Def == &B)
1510+
return true;
1511+
if (Dominates(Def, A) && !Dominates(Def, B))
1512+
return true;
1513+
}
1514+
1515+
// Reg isn't defined between PrevMI and MI.
1516+
return false;
1517+
};
1518+
1519+
auto &AVL = MI.getOperand(1);
1520+
auto &PrevAVL = PrevMI.getOperand(1);
1521+
bool AreSameAVL = AVL.isReg() && PrevAVL.isReg() &&
1522+
AVL.getReg() == PrevAVL.getReg() &&
1523+
!IsDefinedBetween(AVL.getReg(), PrevMI, MI);
1524+
if (AVL.isReg() && AVL.getReg() != RISCV::X0 && !AreSameAVL)
1525+
return false;
15041526
}
15051527

15061528
if (!PrevMI.getOperand(2).isImm() || !MI.getOperand(2).isImm())

llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,8 @@ define <32 x i32> @insertelt_v32i32_31(<32 x i32> %a, i32 %y) {
6363
; CHECK-LABEL: insertelt_v32i32_31:
6464
; CHECK: # %bb.0:
6565
; CHECK-NEXT: li a1, 32
66-
; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma
67-
; CHECK-NEXT: vmv.s.x v16, a0
6866
; CHECK-NEXT: vsetvli zero, a1, e32, m8, ta, ma
67+
; CHECK-NEXT: vmv.s.x v16, a0
6968
; CHECK-NEXT: vslideup.vi v8, v16, 31
7069
; CHECK-NEXT: ret
7170
%b = insertelement <32 x i32> %a, i32 %y, i32 31
@@ -101,9 +100,8 @@ define <64 x i32> @insertelt_v64i32_63(<64 x i32> %a, i32 %y) {
101100
; CHECK-LABEL: insertelt_v64i32_63:
102101
; CHECK: # %bb.0:
103102
; CHECK-NEXT: li a1, 32
104-
; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma
105-
; CHECK-NEXT: vmv.s.x v24, a0
106103
; CHECK-NEXT: vsetvli zero, a1, e32, m8, ta, ma
104+
; CHECK-NEXT: vmv.s.x v24, a0
107105
; CHECK-NEXT: vslideup.vi v16, v24, 31
108106
; CHECK-NEXT: ret
109107
%b = insertelement <64 x i32> %a, i32 %y, i32 63

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -643,9 +643,8 @@ define <vscale x 2 x float> @fp_reduction_vfmv_s_f(float %0, <vscale x 8 x float
643643
define dso_local <vscale x 2 x i32> @int_reduction_vmv_s_x(i32 signext %0, <vscale x 8 x i32> %1, i64 %2) {
644644
; CHECK-LABEL: int_reduction_vmv_s_x:
645645
; CHECK: # %bb.0:
646-
; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma
647-
; CHECK-NEXT: vmv.s.x v12, a0
648646
; CHECK-NEXT: vsetvli zero, a1, e32, m4, ta, ma
647+
; CHECK-NEXT: vmv.s.x v12, a0
649648
; CHECK-NEXT: vredsum.vs v8, v8, v12
650649
; CHECK-NEXT: ret
651650
%4 = tail call <vscale x 8 x i32> @llvm.riscv.vmv.s.x.nxv8i32.i64(<vscale x 8 x i32> poison, i32 %0, i64 %2)

0 commit comments

Comments
 (0)