mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 06:30:16 +00:00
Instcombine should turn llvm.objectsize of a alloca with static size to an integer.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97827 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
10718492c8
commit
a862326bc7
@ -304,29 +304,39 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
|||||||
switch (II->getIntrinsicID()) {
|
switch (II->getIntrinsicID()) {
|
||||||
default: break;
|
default: break;
|
||||||
case Intrinsic::objectsize: {
|
case Intrinsic::objectsize: {
|
||||||
const Type *ReturnTy = CI.getType();
|
|
||||||
Value *Op1 = II->getOperand(1);
|
|
||||||
bool Min = (cast<ConstantInt>(II->getOperand(2))->getZExtValue() == 1);
|
|
||||||
|
|
||||||
// We need target data for just about everything so depend on it.
|
// We need target data for just about everything so depend on it.
|
||||||
if (!TD) break;
|
if (!TD) break;
|
||||||
|
|
||||||
|
const Type *ReturnTy = CI.getType();
|
||||||
|
bool Min = (cast<ConstantInt>(II->getOperand(2))->getZExtValue() == 1);
|
||||||
|
|
||||||
// Get to the real allocated thing and offset as fast as possible.
|
// Get to the real allocated thing and offset as fast as possible.
|
||||||
Op1 = Op1->stripPointerCasts();
|
Value *Op1 = II->getOperand(1)->stripPointerCasts();
|
||||||
|
|
||||||
// If we've stripped down to a single global variable that we
|
// If we've stripped down to a single global variable that we
|
||||||
// can know the size of then just return that.
|
// can know the size of then just return that.
|
||||||
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op1)) {
|
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op1)) {
|
||||||
if (GV->hasDefinitiveInitializer()) {
|
if (GV->hasDefinitiveInitializer()) {
|
||||||
Constant *C = GV->getInitializer();
|
Constant *C = GV->getInitializer();
|
||||||
uint64_t globalSize = TD->getTypeAllocSize(C->getType());
|
uint64_t GlobalSize = TD->getTypeAllocSize(C->getType());
|
||||||
return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, globalSize));
|
return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, GlobalSize));
|
||||||
} else {
|
} else {
|
||||||
|
// Can't determine size of the GV.
|
||||||
Constant *RetVal = ConstantInt::get(ReturnTy, Min ? 0 : -1ULL);
|
Constant *RetVal = ConstantInt::get(ReturnTy, Min ? 0 : -1ULL);
|
||||||
return ReplaceInstUsesWith(CI, RetVal);
|
return ReplaceInstUsesWith(CI, RetVal);
|
||||||
}
|
}
|
||||||
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Op1)) {
|
} else if (AllocaInst *AI = dyn_cast<AllocaInst>(Op1)) {
|
||||||
|
// Get alloca size.
|
||||||
|
if (AI->getAllocatedType()->isSized()) {
|
||||||
|
uint64_t AllocaSize = TD->getTypeAllocSize(AI->getAllocatedType());
|
||||||
|
if (AI->isArrayAllocation()) {
|
||||||
|
const ConstantInt *C = dyn_cast<ConstantInt>(AI->getArraySize());
|
||||||
|
if (!C) break;
|
||||||
|
AllocaSize *= C->getZExtValue();
|
||||||
|
}
|
||||||
|
return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, AllocaSize));
|
||||||
|
}
|
||||||
|
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Op1)) {
|
||||||
// Only handle constant GEPs here.
|
// Only handle constant GEPs here.
|
||||||
if (CE->getOpcode() != Instruction::GetElementPtr) break;
|
if (CE->getOpcode() != Instruction::GetElementPtr) break;
|
||||||
GEPOperator *GEP = cast<GEPOperator>(CE);
|
GEPOperator *GEP = cast<GEPOperator>(CE);
|
||||||
@ -361,6 +371,9 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
|||||||
return ReplaceInstUsesWith(CI, RetVal);
|
return ReplaceInstUsesWith(CI, RetVal);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do not return "I don't know" here. Later optimization passes could
|
||||||
|
// make it possible to evaluate objectsize to a constant.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Intrinsic::bswap:
|
case Intrinsic::bswap:
|
||||||
|
@ -102,4 +102,24 @@ bb12:
|
|||||||
unreachable
|
unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; rdar://7718857
|
||||||
|
|
||||||
|
%struct.data = type { [100 x i32], [100 x i32], [1024 x i8] }
|
||||||
|
|
||||||
|
define i32 @test4() nounwind ssp {
|
||||||
|
; CHECK: @test4
|
||||||
|
entry:
|
||||||
|
%0 = alloca %struct.data, align 8
|
||||||
|
%1 = bitcast %struct.data* %0 to i8*
|
||||||
|
%2 = call i64 @llvm.objectsize.i64(i8* %1, i1 false) nounwind
|
||||||
|
; CHECK-NOT: @llvm.objectsize
|
||||||
|
; CHECK: @__memset_chk(i8* %1, i32 0, i64 1824, i64 1824)
|
||||||
|
%3 = call i8* @__memset_chk(i8* %1, i32 0, i64 1824, i64 %2) nounwind
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i8* @__memset_chk(i8*, i32, i64, i64) nounwind
|
||||||
|
|
||||||
declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
|
declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
|
||||||
|
|
||||||
|
declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readonly
|
||||||
|
Loading…
x
Reference in New Issue
Block a user