mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-25 21:00:00 +00:00
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
This commit is contained in:
parent
f87052a55a
commit
26d0e892e3
@ -308,9 +308,14 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
|||||||
Value *Op1 = II->getOperand(1);
|
Value *Op1 = II->getOperand(1);
|
||||||
bool Min = (cast<ConstantInt>(II->getOperand(2))->getZExtValue() == 1);
|
bool Min = (cast<ConstantInt>(II->getOperand(2))->getZExtValue() == 1);
|
||||||
|
|
||||||
|
// We need target data for just about everything so depend on it.
|
||||||
if (!TD) break;
|
if (!TD) break;
|
||||||
|
|
||||||
|
// Get to the real allocated thing and offset as fast as possible.
|
||||||
Op1 = Op1->stripPointerCasts();
|
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<GlobalVariable>(Op1)) {
|
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op1)) {
|
||||||
if (GV->hasDefinitiveInitializer()) {
|
if (GV->hasDefinitiveInitializer()) {
|
||||||
Constant *C = GV->getInitializer();
|
Constant *C = GV->getInitializer();
|
||||||
@ -320,7 +325,27 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
|||||||
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)) {
|
||||||
|
|
||||||
|
// Only handle constant GEPs here.
|
||||||
|
if (CE->getOpcode() != Instruction::GetElementPtr) break;
|
||||||
|
GEPOperator *GEP = cast<GEPOperator>(CE);
|
||||||
|
|
||||||
|
// Get what we're pointing to and its size.
|
||||||
|
const PointerType *PT =
|
||||||
|
cast<PointerType>(GEP->getPointerOperand()->getType());
|
||||||
|
size_t Size = TD->getTypeAllocSize(PT->getElementType());
|
||||||
|
|
||||||
|
// Get the current byte offset into the thing.
|
||||||
|
SmallVector<Value*, 8> 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:
|
case Intrinsic::bswap:
|
||||||
// bswap(bswap(x)) -> x
|
// bswap(bswap(x)) -> x
|
||||||
|
@ -31,10 +31,9 @@ cond.false:
|
|||||||
ret i8* %2;
|
ret i8* %2;
|
||||||
}
|
}
|
||||||
|
|
||||||
; FIXME: Should be ret i32 0
|
|
||||||
define i32 @f() nounwind {
|
define i32 @f() nounwind {
|
||||||
; CHECK: @f
|
; 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)
|
%1 = call i32 @llvm.objectsize.i32(i8* getelementptr ([60 x i8]* @a, i32 1, i32 0), i1 false)
|
||||||
ret i32 %1
|
ret i32 %1
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user