From 26d0e892e36e8dcc4248a8ccc8bedbd2d235eaee Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Thu, 11 Feb 2010 01:48:54 +0000 Subject: [PATCH] Add ConstantExpr handling to Intrinsic::objectsize lowering. Update testcase accordingly now that we can optimize another section. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95846 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineCalls.cpp | 27 ++++++++++++++++++- test/Transforms/InstCombine/objsize.ll | 3 +-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index 4929f4070ff..1371fa7f1ad 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -308,9 +308,14 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { Value *Op1 = II->getOperand(1); bool Min = (cast(II->getOperand(2))->getZExtValue() == 1); + // We need target data for just about everything so depend on it. if (!TD) break; + + // Get to the real allocated thing and offset as fast as possible. Op1 = Op1->stripPointerCasts(); + // If we've stripped down to a single global variable that we + // can know the size of then just return that. if (GlobalVariable *GV = dyn_cast(Op1)) { if (GV->hasDefinitiveInitializer()) { Constant *C = GV->getInitializer(); @@ -320,7 +325,27 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { Constant *RetVal = ConstantInt::get(ReturnTy, Min ? 0 : -1ULL); return ReplaceInstUsesWith(CI, RetVal); } - } + } else if (ConstantExpr *CE = dyn_cast(Op1)) { + + // Only handle constant GEPs here. + if (CE->getOpcode() != Instruction::GetElementPtr) break; + GEPOperator *GEP = cast(CE); + + // Get what we're pointing to and its size. + const PointerType *PT = + cast(GEP->getPointerOperand()->getType()); + size_t Size = TD->getTypeAllocSize(PT->getElementType()); + + // Get the current byte offset into the thing. + SmallVector Ops(CE->op_begin()+1, CE->op_end()); + size_t Offset = TD->getIndexedOffset(PT, &Ops[0], Ops.size()); + + assert(Size >= Offset); + + Constant *RetVal = ConstantInt::get(ReturnTy, Size-Offset); + return ReplaceInstUsesWith(CI, RetVal); + + } } case Intrinsic::bswap: // bswap(bswap(x)) -> x diff --git a/test/Transforms/InstCombine/objsize.ll b/test/Transforms/InstCombine/objsize.ll index 69e09f61f7c..2bcdd914e33 100644 --- a/test/Transforms/InstCombine/objsize.ll +++ b/test/Transforms/InstCombine/objsize.ll @@ -31,10 +31,9 @@ cond.false: ret i8* %2; } -; FIXME: Should be ret i32 0 define i32 @f() nounwind { ; CHECK: @f -; CHECK-NEXT: llvm.objectsize.i32 +; CHECK-NEXT: ret i32 0 %1 = call i32 @llvm.objectsize.i32(i8* getelementptr ([60 x i8]* @a, i32 1, i32 0), i1 false) ret i32 %1 } -- 2.34.1