summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Nemet <anemet@apple.com>2016-05-26 07:08:05 +0000
committerAdam Nemet <anemet@apple.com>2016-05-26 07:08:05 +0000
commitc68534bd13be1d79a55f26c9e3073405a0bdaa9d (patch)
treef6794fa2a1a0fbc9f1cba5138cbd6e60986cd06d
parent6f08cebf36b84d6dfb2a270e74bfd2594eaf24d7 (diff)
downloadbcm5719-llvm-c68534bd13be1d79a55f26c9e3073405a0bdaa9d.tar.gz
bcm5719-llvm-c68534bd13be1d79a55f26c9e3073405a0bdaa9d.zip
[ConstantFold] Fix incorrect index rewrites for GEPs
Summary: If an index for a vector or array type is out-of-range GEP constant folding tries to factor it into preceding dimensions. The code however does not consider addressing of structure field padding which should not qualify as out-of-range index. As demonstrated by the testcase, this can occur if the indexing performed on a vector type and the preceding index is an array type. SROA generates GEPs for example involving padding bytes as it slices an alloca. My fix disables this folding if the element type is a vector type. I believe that this is the only way we can end up with padding. (We have no access to DataLayout so I am not sure if there is actual robust way of actually checking the presence of padding.) Reviewers: majnemer Subscribers: llvm-commits, Gerolf Differential Revision: http://reviews.llvm.org/D20663 llvm-svn: 270826
-rw-r--r--llvm/lib/IR/ConstantFold.cpp2
-rw-r--r--llvm/test/Transforms/InstCombine/getelementptr-folding.ll13
2 files changed, 14 insertions, 1 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp
index 623ce701b60..bf0887f143e 100644
--- a/llvm/lib/IR/ConstantFold.cpp
+++ b/llvm/lib/IR/ConstantFold.cpp
@@ -2193,7 +2193,7 @@ static Constant *ConstantFoldGetElementPtrImpl(Type *PointeeTy, Constant *C,
for (unsigned i = 1, e = Idxs.size(); i != e;
Prev = Ty, Ty = cast<CompositeType>(Ty)->getTypeAtIndex(Idxs[i]), ++i) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(Idxs[i])) {
- if (isa<ArrayType>(Ty) || isa<VectorType>(Ty))
+ if (isa<ArrayType>(Ty))
if (CI->getSExtValue() > 0 &&
!isIndexInRangeOfSequentialType(cast<SequentialType>(Ty), CI)) {
if (isa<SequentialType>(Prev)) {
diff --git a/llvm/test/Transforms/InstCombine/getelementptr-folding.ll b/llvm/test/Transforms/InstCombine/getelementptr-folding.ll
new file mode 100644
index 00000000000..11e7e43a6b4
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/getelementptr-folding.ll
@@ -0,0 +1,13 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s
+
+%struct.matrix_float3x3 = type { [3 x <3 x float>] }
+
+; We used to fold this by rewriting the indices to 0, 0, 2, 0. This is
+; invalid because there is a 4-byte padding after each <3 x float> field.
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+@matrix_identity_float3x3 = external global %struct.matrix_float3x3, align 16
+@bbb = global float* getelementptr inbounds (%struct.matrix_float3x3, %struct.matrix_float3x3* @matrix_identity_float3x3, i64 0, i32 0, i64 1, i64 3)
+; CHECK: @bbb = global float* getelementptr inbounds (%struct.matrix_float3x3, %struct.matrix_float3x3* @matrix_identity_float3x3, i64 0, i32 0, i64 1, i64 3)
OpenPOWER on IntegriCloud