diff options
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 981c527..7f605be 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -2146,13 +2146,33 @@ CommonPointerBase CommonPointerBase::compute(Value *LHS, Value *RHS) { return Base; } +bool CommonPointerBase::isExpensive() const { + unsigned NumGEPs = 0; + auto ProcessGEPs = [&NumGEPs](ArrayRef<GEPOperator *> GEPs) { + bool SeenMultiUse = false; + for (GEPOperator *GEP : GEPs) { + // Only count multi-use GEPs, excluding the first one. For the first one, + // we will directly reuse the offset. For one-use GEPs, their offset will + // be folded into a multi-use GEP. + if (!GEP->hasOneUse()) { + if (SeenMultiUse) + ++NumGEPs; + SeenMultiUse = true; + } + } + }; + ProcessGEPs(LHSGEPs); + ProcessGEPs(RHSGEPs); + return NumGEPs > 2; +} + /// Optimize pointer differences into the same array into a size. Consider: /// &A[10] - &A[0]: we should compile this to "10". LHS/RHS are the pointer /// operands to the ptrtoint instructions for the LHS/RHS of the subtract. Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS, Type *Ty, bool IsNUW) { CommonPointerBase Base = CommonPointerBase::compute(LHS, RHS); - if (!Base.Ptr) + if (!Base.Ptr || Base.isExpensive()) return nullptr; // To avoid duplicating the offset arithmetic, rewrite the GEP to use the |