summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
diff options
context:
space:
mode:
authorHiroshi Yamauchi <yamauchi@google.com>2017-07-27 18:27:11 +0000
committerHiroshi Yamauchi <yamauchi@google.com>2017-07-27 18:27:11 +0000
commit60855214c25286fc7ee4bf61aee8dea8822486fa (patch)
tree99e6ebb3a056d3973af3f53381e9b8bab7e20713 /llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
parenteacdf04fdda7c6156b4e063cfce28f643493f76e (diff)
downloadbcm5719-llvm-60855214c25286fc7ee4bf61aee8dea8822486fa.tar.gz
bcm5719-llvm-60855214c25286fc7ee4bf61aee8dea8822486fa.zip
[InstCombine] Simplify pointer difference subtractions (GEP-GEP) where GEPs have other uses and one non-constant index
Summary: Pointer difference simplifications currently happen only if input GEPs don't have other uses or their indexes are all constants, to avoid duplicating indexing arithmetic. This patch enables cases with exactly one non-constant index among input GEPs to happen where there is no duplicated arithmetic or code size increase even if input GEPs have other uses. For example, this patch allows "(&A[42][i]-&A[42][0])" --> "i", which didn't happen previously, if the input GEP(s) have other uses. Reviewers: sanjoy, bkramer Reviewed By: sanjoy Subscribers: mcrosier, llvm-commits Differential Revision: https://reviews.llvm.org/D35499 llvm-svn: 309304
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp27
1 files changed, 23 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index ba9b4addd8b..0d14f62b3e9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1465,12 +1465,31 @@ Value *InstCombiner::OptimizePointerDifference(Value *LHS, Value *RHS,
}
}
- // Avoid duplicating the arithmetic if GEP2 has non-constant indices and
- // multiple users.
- if (!GEP1 ||
- (GEP2 && !GEP2->hasAllConstantIndices() && !GEP2->hasOneUse()))
+ if (!GEP1)
+ // No GEP found.
return nullptr;
+ if (GEP2) {
+ // (gep X, ...) - (gep X, ...)
+ //
+ // Avoid duplicating the arithmetic if there are more than one non-constant
+ // indices between the two GEPs and either GEP has a non-constant index and
+ // multiple users. If zero non-constant index, the result is a constant and
+ // there is no duplication. If one non-constant index, the result is an add
+ // or sub with a constant, which is no larger than the original code, and
+ // there's no duplicated arithmetic, even if either GEP has multiple
+ // users. If more than one non-constant indices combined, as long as the GEP
+ // with at least one non-constant index doesn't have multiple users, there
+ // is no duplication.
+ unsigned NumNonConstantIndices1 = GEP1->countNonConstantIndices();
+ unsigned NumNonConstantIndices2 = GEP2->countNonConstantIndices();
+ if (NumNonConstantIndices1 + NumNonConstantIndices2 > 1 &&
+ ((NumNonConstantIndices1 > 0 && !GEP1->hasOneUse()) ||
+ (NumNonConstantIndices2 > 0 && !GEP2->hasOneUse()))) {
+ return nullptr;
+ }
+ }
+
// Emit the offset of the GEP and an intptr_t.
Value *Result = EmitGEPOffset(GEP1);
OpenPOWER on IntegriCloud