@@ -1544,10 +1544,53 @@ RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
1544
1544
return Offset;
1545
1545
}
1546
1546
1547
+ static MCRegister getRVVBaseRegister (const RISCVRegisterInfo &TRI,
1548
+ const Register &Reg) {
1549
+ MCRegister BaseReg = TRI.getSubReg (Reg, RISCV::sub_vrm1_0);
1550
+ // If it's not a grouped vector register, it doesn't have subregister, so
1551
+ // the base register is just itself.
1552
+ if (BaseReg == RISCV::NoRegister)
1553
+ BaseReg = Reg;
1554
+ return BaseReg;
1555
+ }
1556
+
1547
1557
void RISCVFrameLowering::determineCalleeSaves (MachineFunction &MF,
1548
1558
BitVector &SavedRegs,
1549
1559
RegScavenger *RS) const {
1550
1560
TargetFrameLowering::determineCalleeSaves (MF, SavedRegs, RS);
1561
+
1562
+ // In TargetFrameLowering::determineCalleeSaves, any vector register is marked
1563
+ // as saved if any of its subregister is clobbered, this is not correct in
1564
+ // vector registers. We only want the vector register to be marked as saved
1565
+ // if all of its subregisters are clobbered.
1566
+ // For example:
1567
+ // Original behavior: If v24 is marked, v24m2, v24m4, v24m8 are also marked.
1568
+ // Correct behavior: v24m2 is marked only if v24 and v25 are marked.
1569
+ const MachineRegisterInfo &MRI = MF.getRegInfo ();
1570
+ const MCPhysReg *CSRegs = MRI.getCalleeSavedRegs ();
1571
+ const RISCVRegisterInfo &TRI = *STI.getRegisterInfo ();
1572
+ for (unsigned i = 0 ; CSRegs[i]; ++i) {
1573
+ unsigned CSReg = CSRegs[i];
1574
+ // Only vector registers need special care.
1575
+ if (!RISCV::VRRegClass.contains (getRVVBaseRegister (TRI, CSReg)))
1576
+ continue ;
1577
+
1578
+ SavedRegs.reset (CSReg);
1579
+
1580
+ auto SubRegs = TRI.subregs (CSReg);
1581
+ // Set the register and all its subregisters.
1582
+ if (!MRI.def_empty (CSReg) || MRI.getUsedPhysRegsMask ().test (CSReg)) {
1583
+ SavedRegs.set (CSReg);
1584
+ llvm::for_each (SubRegs, [&](unsigned Reg) { return SavedRegs.set (Reg); });
1585
+ }
1586
+
1587
+ // Combine to super register if all of its subregisters are marked.
1588
+ if (!SubRegs.empty () && llvm::all_of (SubRegs, [&](unsigned Reg) {
1589
+ return SavedRegs.test (Reg);
1590
+ }))
1591
+ SavedRegs.set (CSReg);
1592
+ }
1593
+
1551
1594
// Unconditionally spill RA and FP only if the function uses a frame
1552
1595
// pointer.
1553
1596
if (hasFP (MF)) {
@@ -2137,16 +2180,6 @@ static unsigned getCalleeSavedRVVNumRegs(const Register &BaseReg) {
2137
2180
: 8 ;
2138
2181
}
2139
2182
2140
- static MCRegister getRVVBaseRegister (const RISCVRegisterInfo &TRI,
2141
- const Register &Reg) {
2142
- MCRegister BaseReg = TRI.getSubReg (Reg, RISCV::sub_vrm1_0);
2143
- // If it's not a grouped vector register, it doesn't have subregister, so
2144
- // the base register is just itself.
2145
- if (BaseReg == RISCV::NoRegister)
2146
- BaseReg = Reg;
2147
- return BaseReg;
2148
- }
2149
-
2150
2183
void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI (
2151
2184
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, bool HasFP) const {
2152
2185
MachineFunction *MF = MBB.getParent ();
0 commit comments