[llvm] [GlobalISel] Fast-path single reg loads and stores in IRTranslator (PR #195245)
via llvm-commits
llvm-commits at lists.llvm.org
Fri May 1 02:49:33 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
Author: Cullen Rhodes (c-rhodes)
<details>
<summary>Changes</summary>
IRTranslator::translateLoad is hot in compile-time profiles of sqlite on aarch64-O0-g. Aggregates are flattened into multiple vregs with offsets. Most loads and stores lower to a single register so this offset materialization can be avoided.
Small -0.07% geomean improvement on aarch64-O0-g with -0.24% for sqlite.
https://llvm-compile-time-tracker.com/compare.php?from=a7a2dc59616a8cb1198d933bcdf55ebdbd78894c&to=e535e96fd0952cfa646d48ef84cf5948c0a8a2ab&stat=instructions%3Au
---
Full diff: https://github.com/llvm/llvm-project/pull/195245.diff
1 Files Affected:
- (modified) llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp (+30-13)
``````````diff
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index b5b73332bac62..e80b786a13ec5 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -1387,13 +1387,10 @@ bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) {
return true;
ArrayRef<Register> Regs = getOrCreateVRegs(LI);
- ArrayRef<uint64_t> Offsets = *VMap.getOffsets(LI);
Register Base = getOrCreateVReg(*LI.getPointerOperand());
AAMDNodes AAInfo = LI.getAAMetadata();
const Value *Ptr = LI.getPointerOperand();
- Type *OffsetIRTy = DL->getIndexType(Ptr->getType());
- LLT OffsetTy = getLLTForType(*OffsetIRTy, *DL);
if (CLI->supportSwiftError() && isSwiftError(Ptr)) {
assert(Regs.size() == 1 && "swifterror should be single pointer");
@@ -1412,18 +1409,30 @@ bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) {
}
}
- const MDNode *Ranges =
- Regs.size() == 1 ? LI.getMetadata(LLVMContext::MD_range) : nullptr;
+ // Fast-path the common single-register load.
+ if (Regs.size() == 1) {
+ auto MMO = MF->getMachineMemOperand(
+ MachinePointerInfo(LI.getPointerOperand()), Flags,
+ MRI->getType(Regs[0]), getMemOpAlign(LI), AAInfo,
+ LI.getMetadata(LLVMContext::MD_range), LI.getSyncScopeID(),
+ LI.getOrdering());
+ MIRBuilder.buildLoad(Regs[0], Base, *MMO);
+ return true;
+ }
+
+ ArrayRef<uint64_t> Offsets = *VMap.getOffsets(LI);
+ Type *OffsetIRTy = DL->getIndexType(Ptr->getType());
+ LLT OffsetTy = getLLTForType(*OffsetIRTy, *DL);
for (unsigned i = 0; i < Regs.size(); ++i) {
Register Addr;
MIRBuilder.materializeObjectPtrOffset(Addr, Base, OffsetTy, Offsets[i]);
MachinePointerInfo Ptr(LI.getPointerOperand(), Offsets[i]);
Align BaseAlign = getMemOpAlign(LI);
- auto MMO =
- MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Regs[i]),
- commonAlignment(BaseAlign, Offsets[i]), AAInfo,
- Ranges, LI.getSyncScopeID(), LI.getOrdering());
+ auto MMO = MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Regs[i]),
+ commonAlignment(BaseAlign, Offsets[i]),
+ AAInfo, nullptr, LI.getSyncScopeID(),
+ LI.getOrdering());
MIRBuilder.buildLoad(Regs[i], Addr, *MMO);
}
@@ -1436,12 +1445,8 @@ bool IRTranslator::translateStore(const User &U, MachineIRBuilder &MIRBuilder) {
return true;
ArrayRef<Register> Vals = getOrCreateVRegs(*SI.getValueOperand());
- ArrayRef<uint64_t> Offsets = *VMap.getOffsets(*SI.getValueOperand());
Register Base = getOrCreateVReg(*SI.getPointerOperand());
- Type *OffsetIRTy = DL->getIndexType(SI.getPointerOperandType());
- LLT OffsetTy = getLLTForType(*OffsetIRTy, *DL);
-
if (CLI->supportSwiftError() && isSwiftError(SI.getPointerOperand())) {
assert(Vals.size() == 1 && "swifterror should be single pointer");
@@ -1452,7 +1457,19 @@ bool IRTranslator::translateStore(const User &U, MachineIRBuilder &MIRBuilder) {
}
MachineMemOperand::Flags Flags = TLI->getStoreMemOperandFlags(SI, *DL);
+ // Fast-path the common single-register store.
+ if (Vals.size() == 1) {
+ auto MMO = MF->getMachineMemOperand(
+ MachinePointerInfo(SI.getPointerOperand()), Flags,
+ MRI->getType(Vals[0]), getMemOpAlign(SI), SI.getAAMetadata(), nullptr,
+ SI.getSyncScopeID(), SI.getOrdering());
+ MIRBuilder.buildStore(Vals[0], Base, *MMO);
+ return true;
+ }
+ ArrayRef<uint64_t> Offsets = *VMap.getOffsets(*SI.getValueOperand());
+ Type *OffsetIRTy = DL->getIndexType(SI.getPointerOperandType());
+ LLT OffsetTy = getLLTForType(*OffsetIRTy, *DL);
for (unsigned i = 0; i < Vals.size(); ++i) {
Register Addr;
MIRBuilder.materializeObjectPtrOffset(Addr, Base, OffsetTy, Offsets[i]);
``````````
</details>
https://github.com/llvm/llvm-project/pull/195245
More information about the llvm-commits
mailing list