diff options
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. |
