aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2012-07-25 09:14:54 +0000
committerDuncan Sands <baldrick@free.fr>2012-07-25 09:14:54 +0000
commitf2124cc6c1d4e675526e87bcc9fccd3ef4664dcb (patch)
tree5cc43d177c56f99d0c974cdac28c04ac091923a1
parentde4a1274706d7449870dac5bed05d27a6772d4ed (diff)
downloadexternal_llvm-f2124cc6c1d4e675526e87bcc9fccd3ef4664dcb.zip
external_llvm-f2124cc6c1d4e675526e87bcc9fccd3ef4664dcb.tar.gz
external_llvm-f2124cc6c1d4e675526e87bcc9fccd3ef4664dcb.tar.bz2
When folding a load from a global constant, if the load started in the middle
of an array element (rather than at the beginning of the element) and extended into the next element, then the load from the second element was being handled wrong due to incorrect updating of the notion of which byte to load next. This fixes PR13442. Thanks to Chris Smowton for reporting the problem, analyzing it and providing a fix. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160711 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/ConstantFolding.cpp13
-rw-r--r--test/Transforms/InstCombine/2012-07-25-LoadPart.ll12
2 files changed, 20 insertions, 5 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index 7ced848..a7c9e55 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -358,17 +358,20 @@ static bool ReadDataFromGlobal(Constant *C, uint64_t ByteOffset,
NumElts = AT->getNumElements();
else
NumElts = cast<VectorType>(C->getType())->getNumElements();
-
+
for (; Index != NumElts; ++Index) {
if (!ReadDataFromGlobal(C->getAggregateElement(Index), Offset, CurPtr,
BytesLeft, TD))
return false;
- if (EltSize >= BytesLeft)
+
+ uint64_t BytesWritten = EltSize - Offset;
+ assert(BytesWritten <= EltSize && "Not indexing into this element?");
+ if (BytesWritten >= BytesLeft)
return true;
-
+
Offset = 0;
- BytesLeft -= EltSize;
- CurPtr += EltSize;
+ BytesLeft -= BytesWritten;
+ CurPtr += BytesWritten;
}
return true;
}
diff --git a/test/Transforms/InstCombine/2012-07-25-LoadPart.ll b/test/Transforms/InstCombine/2012-07-25-LoadPart.ll
new file mode 100644
index 0000000..01dce7c
--- /dev/null
+++ b/test/Transforms/InstCombine/2012-07-25-LoadPart.ll
@@ -0,0 +1,12 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+; PR13442
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
+
+@test = constant [4 x i32] [i32 1, i32 2, i32 3, i32 4]
+
+define i64 @foo() {
+ %ret = load i64* bitcast (i8* getelementptr (i8* bitcast ([4 x i32]* @test to i8*), i64 2) to i64*)
+ ret i64 %ret
+ ; CHECK: ret i64 844424930263040
+}