diff options
| author | Nikita Popov <npopov@redhat.com> | 2024-09-23 09:32:24 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-23 09:32:24 +0200 |
| commit | 8a6248b739d705577fa5414b4010605dca38aa79 (patch) | |
| tree | 5a281831de6f7e62a8b332ee4df2273dcf946ca4 /llvm/lib/Transforms/Utils/SimplifyCFG.cpp | |
| parent | 5a4c6f97997f3cdfa9d98f7f0b546e331ee9cc4a (diff) | |
| download | llvm-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.cpp | 17 |
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. |
