summaryrefslogtreecommitdiff
path: root/lib/Transforms/InstCombine/InstCombineCalls.cpp
diff options
context:
space:
mode:
authorNuno Lopes <nunoplopes@sapo.pt>2012-05-10 23:17:35 +0000
committerNuno Lopes <nunoplopes@sapo.pt>2012-05-10 23:17:35 +0000
commit9d236f909cec671ef2ff186c8fce6d2e1540a0a9 (patch)
tree49729dbb18282aae564c029b4effaf97f90f7b01 /lib/Transforms/InstCombine/InstCombineCalls.cpp
parentdeaa3f3e523183b611249bba636876cb05c5881a (diff)
downloadllvm-9d236f909cec671ef2ff186c8fce6d2e1540a0a9.tar.gz
llvm-9d236f909cec671ef2ff186c8fce6d2e1540a0a9.tar.bz2
llvm-9d236f909cec671ef2ff186c8fce6d2e1540a0a9.tar.xz
objectsize: add support for GEPs with non-constant indexes
add an additional parameter to InstCombiner::EmitGEPOffset() to force it to *not* emit operations with NUW flag git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156585 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/InstCombine/InstCombineCalls.cpp')
-rw-r--r--lib/Transforms/InstCombine/InstCombineCalls.cpp61
1 files changed, 30 insertions, 31 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 82487a020f..ea3f95ed23 100644
--- a/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -173,7 +173,7 @@ static int computeAllocSize(Value *Alloc, uint64_t &Size, Value* &SizeValue,
uint64_t Penalty, TargetData *TD,
InstCombiner::BuilderTy *Builder) {
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Alloc)) {
- if (GV->hasUniqueInitializer()) {
+ if (GV->hasDefinitiveInitializer()) {
Constant *C = GV->getInitializer();
Size = TD->getTypeAllocSize(C->getType());
return 1;
@@ -198,7 +198,8 @@ static int computeAllocSize(Value *Alloc, uint64_t &Size, Value* &SizeValue,
if (Penalty < 2)
return 2;
- SizeValue = Builder->CreateMul(Builder->getInt64(Size), ArraySize);
+ SizeValue = ConstantInt::get(ArraySize->getType(), Size);
+ SizeValue = Builder->CreateMul(SizeValue, ArraySize);
return 0;
} else if (CallInst *MI = extractMallocCall(Alloc)) {
@@ -320,22 +321,12 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
// Get to the real allocated thing and offset as fast as possible.
Value *Op1 = II->getArgOperand(0)->stripPointerCasts();
+ GEPOperator *GEP;
- uint64_t Offset = 0;
- Value *OffsetValue;
- bool ConstOffset = true;
-
- // Try to look through constant GEPs.
- if (GEPOperator *GEP = dyn_cast<GEPOperator>(Op1)) {
- if (!GEP->hasAllConstantIndices()) return 0;
-
- // Get the current byte offset into the thing. Use the original
- // operand in case we're looking through a bitcast.
- SmallVector<Value*, 8> Ops(GEP->idx_begin(), GEP->idx_end());
- if (!GEP->getPointerOperandType()->isPointerTy())
+ if ((GEP = dyn_cast<GEPOperator>(Op1))) {
+ // check if we will be able to get the offset
+ if (!GEP->hasAllConstantIndices() && Penalty < 2)
return 0;
- Offset = TD->getIndexedOffset(GEP->getPointerOperandType(), Ops);
-
Op1 = GEP->getPointerOperand()->stripPointerCasts();
}
@@ -349,28 +340,36 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
if (ConstAlloc == 2)
return 0;
- if (ConstOffset && ConstAlloc) {
+ uint64_t Offset = 0;
+ Value *OffsetValue = 0;
+
+ if (GEP) {
+ if (GEP->hasAllConstantIndices()) {
+ SmallVector<Value*, 8> Ops(GEP->idx_begin(), GEP->idx_end());
+ assert(GEP->getPointerOperandType()->isPointerTy());
+ Offset = TD->getIndexedOffset(GEP->getPointerOperandType(), Ops);
+ } else
+ OffsetValue = EmitGEPOffset(GEP, true /*NoNUW*/);
+ }
+
+ if (!OffsetValue && ConstAlloc) {
if (Size < Offset) {
// Out of bounds
return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, 0));
}
return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, Size-Offset));
+ }
- } else if (Penalty >= 2) {
- if (ConstOffset)
- OffsetValue = Builder->getInt64(Offset);
- if (ConstAlloc)
- SizeValue = Builder->getInt64(Size);
-
- Value *Val = Builder->CreateSub(SizeValue, OffsetValue);
- Val = Builder->CreateTrunc(Val, ReturnTy);
- // return 0 if there's an overflow
- Value *Cmp = Builder->CreateICmpULT(SizeValue, OffsetValue);
- Val = Builder->CreateSelect(Cmp, ConstantInt::get(ReturnTy, 0), Val);
- return ReplaceInstUsesWith(CI, Val);
+ if (!OffsetValue)
+ OffsetValue = ConstantInt::get(ReturnTy, Offset);
+ if (ConstAlloc)
+ SizeValue = ConstantInt::get(ReturnTy, Size);
- } else
- return 0;
+ Value *Val = Builder->CreateSub(SizeValue, OffsetValue);
+ // return 0 if there's an overflow
+ Value *Cmp = Builder->CreateICmpULT(SizeValue, OffsetValue);
+ Val = Builder->CreateSelect(Cmp, ConstantInt::get(ReturnTy, 0), Val);
+ return ReplaceInstUsesWith(CI, Val);
}
case Intrinsic::bswap:
// bswap(bswap(x)) -> x