aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2025-07-22 10:15:04 +0200
committerGitHub <noreply@github.com>2025-07-22 10:15:04 +0200
commit07527596f3dc5f7180cfee79f217cf784b43f059 (patch)
tree2a1cb5fc6940178f4fa71753847019e10472af66 /llvm/lib
parent8c14d3f44f51be053e91612f4ad2d77bf04b6b3a (diff)
downloadllvm-07527596f3dc5f7180cfee79f217cf784b43f059.zip
llvm-07527596f3dc5f7180cfee79f217cf784b43f059.tar.gz
llvm-07527596f3dc5f7180cfee79f217cf784b43f059.tar.bz2
[AggressiveInstCombine] Support store merge with non-consecutive parts (#149807)
This is a minor extension of #147540, resolving one of the FIXMEs. If the collected parts contain some non-consecutive elements, we can still handle smaller ranges that *are* consecutive. This is not common in practice and mostly shows up when the same value is stored at two different offsets.
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp60
1 files changed, 39 insertions, 21 deletions
diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index a3a0e31..7fa6e6c5 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -886,35 +886,20 @@ static std::optional<PartStore> matchPartStore(Instruction &I,
return {{PtrBase, PtrOffset, Val, ValOffset, ValWidth, Store}};
}
-static bool mergePartStores(SmallVectorImpl<PartStore> &Parts,
- const DataLayout &DL, TargetTransformInfo &TTI) {
+static bool mergeConsecutivePartStores(ArrayRef<PartStore> Parts,
+ unsigned Width, const DataLayout &DL,
+ TargetTransformInfo &TTI) {
if (Parts.size() < 2)
return false;
- // We now have multiple parts of the same value stored to the same pointer.
- // Sort the parts by pointer offset, and make sure they are consistent with
- // the value offsets. Also check that the value is fully covered without
- // overlaps.
- // FIXME: We could support merging stores for only part of the value here.
- llvm::sort(Parts);
- int64_t LastEndOffsetFromFirst = 0;
- const PartStore &First = Parts[0];
- for (const PartStore &Part : Parts) {
- APInt PtrOffsetFromFirst = Part.PtrOffset - First.PtrOffset;
- int64_t ValOffsetFromFirst = Part.ValOffset - First.ValOffset;
- if (PtrOffsetFromFirst * 8 != ValOffsetFromFirst ||
- LastEndOffsetFromFirst != ValOffsetFromFirst)
- return false;
- LastEndOffsetFromFirst = ValOffsetFromFirst + Part.ValWidth;
- }
-
// Check whether combining the stores is profitable.
// FIXME: We could generate smaller stores if we can't produce a large one.
+ const PartStore &First = Parts.front();
LLVMContext &Ctx = First.Store->getContext();
- Type *NewTy = Type::getIntNTy(Ctx, LastEndOffsetFromFirst);
+ Type *NewTy = Type::getIntNTy(Ctx, Width);
unsigned Fast = 0;
if (!TTI.isTypeLegal(NewTy) ||
- !TTI.allowsMisalignedMemoryAccesses(Ctx, LastEndOffsetFromFirst,
+ !TTI.allowsMisalignedMemoryAccesses(Ctx, Width,
First.Store->getPointerAddressSpace(),
First.Store->getAlign(), &Fast) ||
!Fast)
@@ -941,6 +926,39 @@ static bool mergePartStores(SmallVectorImpl<PartStore> &Parts,
return true;
}
+static bool mergePartStores(SmallVectorImpl<PartStore> &Parts,
+ const DataLayout &DL, TargetTransformInfo &TTI) {
+ if (Parts.size() < 2)
+ return false;
+
+ // We now have multiple parts of the same value stored to the same pointer.
+ // Sort the parts by pointer offset, and make sure they are consistent with
+ // the value offsets. Also check that the value is fully covered without
+ // overlaps.
+ bool Changed = false;
+ llvm::sort(Parts);
+ int64_t LastEndOffsetFromFirst = 0;
+ const PartStore *First = &Parts[0];
+ for (const PartStore &Part : Parts) {
+ APInt PtrOffsetFromFirst = Part.PtrOffset - First->PtrOffset;
+ int64_t ValOffsetFromFirst = Part.ValOffset - First->ValOffset;
+ if (PtrOffsetFromFirst * 8 != ValOffsetFromFirst ||
+ LastEndOffsetFromFirst != ValOffsetFromFirst) {
+ Changed |= mergeConsecutivePartStores(ArrayRef(First, &Part),
+ LastEndOffsetFromFirst, DL, TTI);
+ First = &Part;
+ LastEndOffsetFromFirst = Part.ValWidth;
+ continue;
+ }
+
+ LastEndOffsetFromFirst = ValOffsetFromFirst + Part.ValWidth;
+ }
+
+ Changed |= mergeConsecutivePartStores(ArrayRef(First, Parts.end()),
+ LastEndOffsetFromFirst, DL, TTI);
+ return Changed;
+}
+
static bool foldConsecutiveStores(BasicBlock &BB, const DataLayout &DL,
TargetTransformInfo &TTI, AliasAnalysis &AA) {
// FIXME: Add big endian support.