Skip to content

[llvm-mca][AArch64] Add AArch64 version of clearsSuperRegisters. #92548

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
May 22, 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
49 changes: 49 additions & 0 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,55 @@ class AArch64MCInstrAnalysis : public MCInstrAnalysis {
return false;
}

bool clearsSuperRegisters(const MCRegisterInfo &MRI, const MCInst &Inst,
APInt &Mask) const override {
const MCInstrDesc &Desc = Info->get(Inst.getOpcode());
unsigned NumDefs = Desc.getNumDefs();
unsigned NumImplicitDefs = Desc.implicit_defs().size();
assert(Mask.getBitWidth() == NumDefs + NumImplicitDefs &&
"Unexpected number of bits in the mask!");
// 32-bit General Purpose Register class.
const MCRegisterClass &GPR32RC = MRI.getRegClass(AArch64::GPR32RegClassID);
// Floating Point Register classes.
const MCRegisterClass &FPR8RC = MRI.getRegClass(AArch64::FPR8RegClassID);
const MCRegisterClass &FPR16RC = MRI.getRegClass(AArch64::FPR16RegClassID);
const MCRegisterClass &FPR32RC = MRI.getRegClass(AArch64::FPR32RegClassID);
const MCRegisterClass &FPR64RC = MRI.getRegClass(AArch64::FPR64RegClassID);
const MCRegisterClass &FPR128RC =
MRI.getRegClass(AArch64::FPR128RegClassID);

auto ClearsSuperReg = [=](unsigned RegID) {
// An update to the lower 32 bits of a 64 bit integer register is
// architecturally defined to zero extend the upper 32 bits on a write.
if (GPR32RC.contains(RegID))
return true;
// SIMD&FP instructions operating on scalar data only acccess the lower
// bits of a register, the upper bits are zero extended on a write. For
// SIMD vector registers smaller than 128-bits, the upper 64-bits of the
// register are zero extended on a write.
// When VL is higher than 128 bits, any write to a SIMD&FP register sets
// bits higher than 128 to zero.
return FPR8RC.contains(RegID) || FPR16RC.contains(RegID) ||
FPR32RC.contains(RegID) || FPR64RC.contains(RegID) ||
FPR128RC.contains(RegID);
};

Mask.clearAllBits();
for (unsigned I = 0, E = NumDefs; I < E; ++I) {
const MCOperand &Op = Inst.getOperand(I);
if (ClearsSuperReg(Op.getReg()))
Mask.setBit(I);
}

for (unsigned I = 0, E = NumImplicitDefs; I < E; ++I) {
const MCPhysReg Reg = Desc.implicit_defs()[I];
if (ClearsSuperReg(Reg))
Mask.setBit(NumDefs + I);
}

return Mask.getBoolValue();
}

std::vector<std::pair<uint64_t, uint64_t>>
findPltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents,
const Triple &TargetTriple) const override {
Expand Down
Loading
Loading