aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2024-09-23 09:32:24 +0200
committerGitHub <noreply@github.com>2024-09-23 09:32:24 +0200
commit8a6248b739d705577fa5414b4010605dca38aa79 (patch)
tree5a281831de6f7e62a8b332ee4df2273dcf946ca4 /llvm/lib/Transforms/Utils/SimplifyCFG.cpp
parent5a4c6f97997f3cdfa9d98f7f0b546e331ee9cc4a (diff)
downloadllvm-8a6248b739d705577fa5414b4010605dca38aa79.zip
llvm-8a6248b739d705577fa5414b4010605dca38aa79.tar.gz
llvm-8a6248b739d705577fa5414b4010605dca38aa79.tar.bz2
[SimplifyCFG] Don't separate a load/store from its gep during sinking (#102318)
If we can sink the a load/store, but not the gep producing its pointer operand, don't sink the load/store either. This may prevent the gep from being folded into an addressing mode, and may also negatively affect further analysis. Fixes https://github.com/llvm/llvm-project/issues/96838.
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyCFG.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyCFG.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 03db86a..aa31e6c 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -2477,6 +2477,16 @@ static bool sinkCommonCodeFromPredecessors(BasicBlock *BB,
bool followedByDeoptOrUnreachable = IsBlockFollowedByDeoptOrUnreachable(BB);
if (!followedByDeoptOrUnreachable) {
+ // Check whether this is the pointer operand of a load/store.
+ auto IsMemOperand = [](Use &U) {
+ auto *I = cast<Instruction>(U.getUser());
+ if (isa<LoadInst>(I))
+ return U.getOperandNo() == LoadInst::getPointerOperandIndex();
+ if (isa<StoreInst>(I))
+ return U.getOperandNo() == StoreInst::getPointerOperandIndex();
+ return false;
+ };
+
// Okay, we *could* sink last ScanIdx instructions. But how many can we
// actually sink before encountering instruction that is unprofitable to
// sink?
@@ -2488,6 +2498,13 @@ static bool sinkCommonCodeFromPredecessors(BasicBlock *BB,
return InstructionsToSink.contains(V);
})) {
++NumPHIInsts;
+ // Do not separate a load/store from the gep producing the address.
+ // The gep can likely be folded into the load/store as an addressing
+ // mode. Additionally, a load of a gep is easier to analyze than a
+ // load of a phi.
+ if (IsMemOperand(U) &&
+ any_of(It->second, [](Value *V) { return isa<GEPOperator>(V); }))
+ return false;
// FIXME: this check is overly optimistic. We may end up not sinking
// said instruction, due to the very same profitability check.
// See @creating_too_many_phis in sink-common-code.ll.