diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index 43419eb9fc0..e501ddc4b85 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(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(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 Ops(CE->op_begin()+1, CE->op_end()); - size_t Offset = TD->getIndexedOffset(PT, &Ops[0], Ops.size()); + const PointerType *OffsetType = + cast(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 646baa0de06..dbc7d31c392 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