aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Christopher <echristo@apple.com>2010-02-13 23:38:01 +0000
committerEric Christopher <echristo@apple.com>2010-02-13 23:38:01 +0000
commit77ffe3b31e32fbbcb06e71c8a68129df6266a492 (patch)
treebf6f2d2f17063adf9d10b578348cba9aafe3edba
parent18c67b994c1f437aa1b61d60f9eecf62f2762952 (diff)
downloadexternal_llvm-77ffe3b31e32fbbcb06e71c8a68129df6266a492.zip
external_llvm-77ffe3b31e32fbbcb06e71c8a68129df6266a492.tar.gz
external_llvm-77ffe3b31e32fbbcb06e71c8a68129df6266a492.tar.bz2
Fix a problem where we had bitcasted operands that gave us
odd offsets since the bitcasted pointer size and the offset pointer size are going to be different types for the GEP vs base object. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96134 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/InstCombine/InstCombineCalls.cpp14
-rw-r--r--test/Transforms/InstCombine/objsize.ll9
2 files changed, 18 insertions, 5 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 43419eb..e501ddc 100644
--- a/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -334,17 +334,21 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
// Make sure we're not a constant offset from an external
// global.
Value *Operand = GEP->getPointerOperand();
+ Operand = Operand->stripPointerCasts();
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Operand))
if (!GV->hasDefinitiveInitializer()) break;
- // Get what we're pointing to and its size.
- const PointerType *PT =
+ // Get what we're pointing to and its size.
+ const PointerType *BaseType =
cast<PointerType>(Operand->getType());
- size_t Size = TD->getTypeAllocSize(PT->getElementType());
+ size_t Size = TD->getTypeAllocSize(BaseType->getElementType());
- // Get the current byte offset into the thing.
+ // Get the current byte offset into the thing. Use the original
+ // operand in case we're looking through a bitcast.
SmallVector<Value*, 8> Ops(CE->op_begin()+1, CE->op_end());
- size_t Offset = TD->getIndexedOffset(PT, &Ops[0], Ops.size());
+ const PointerType *OffsetType =
+ cast<PointerType>(GEP->getPointerOperand()->getType());
+ size_t Offset = TD->getIndexedOffset(OffsetType, &Ops[0], Ops.size());
assert(Size >= Offset);
diff --git a/test/Transforms/InstCombine/objsize.ll b/test/Transforms/InstCombine/objsize.ll
index 646baa0..dbc7d31 100644
--- a/test/Transforms/InstCombine/objsize.ll
+++ b/test/Transforms/InstCombine/objsize.ll
@@ -63,4 +63,13 @@ entry:
unreachable
}
+@.str5 = private constant [9 x i32] [i32 97, i32 98, i32 99, i32 100, i32 0, i32
+ 101, i32 102, i32 103, i32 0], align 4 ;
+define i32 @test2() nounwind {
+; CHECK: @test2
+; CHECK-NEXT: ret i32 34
+ %1 = call i32 @llvm.objectsize.i32(i8* getelementptr (i8* bitcast ([9 x i32]* @.str5 to i8*), i32 2), i1 false)
+ ret i32 %1
+}
+
declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly \ No newline at end of file