diff options
author | Chris Lattner <sabre@nondot.org> | 2007-08-13 17:09:08 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-08-13 17:09:08 +0000 |
commit | aadc778782a65c1eb0bcbf07e6fcbd43d3d7c40d (patch) | |
tree | 85ab90b57cdb5a8fa7416a66c31c292aa3660733 | |
parent | 5ca98c657db0ffa4e6011dc9be3c03ebd811bc50 (diff) | |
download | bcm5719-llvm-aadc778782a65c1eb0bcbf07e6fcbd43d3d7c40d.tar.gz bcm5719-llvm-aadc778782a65c1eb0bcbf07e6fcbd43d3d7c40d.zip |
Constant fold: getelementptr (i8* inttoptr (i64 1 to i8*), i32 -1)
Into: inttoptr (i64 0 to i8*) -> null
This occurs in the example in PR1602. With this fixed, we now compile
the example in PR1602 into fully "devirtualized" code:
define void @_Z1g1S(%struct.S* noalias %s) {
entry: %tmp131415 = getelementptr %struct.S* %s, i32 0, i32 0 ; <i32 (...)***> [#uses=1] %tmp16 = load i32 (...)*** %tmp131415, align 4 ; <i32 (...)**> [#uses=1]
%tmp26277 = load i32 (...)** %tmp16 ; <i32 (...)*> [#uses=1]
%tmp2829 = bitcast i32 (...)* %tmp26277 to void (%struct.S*)* ; <void (%struct.S*)*> [#uses=1]
tail call void %tmp2829( %struct.S* %s )
ret void
}
This still has the vtable dispatch (as required) but does not have any pointer
to method cruft left.
llvm-svn: 41046
-rw-r--r-- | llvm/lib/VMCore/ConstantFold.cpp | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/llvm/lib/VMCore/ConstantFold.cpp b/llvm/lib/VMCore/ConstantFold.cpp index a7662fd6a25..c950e8d07ff 100644 --- a/llvm/lib/VMCore/ConstantFold.cpp +++ b/llvm/lib/VMCore/ConstantFold.cpp @@ -1427,7 +1427,7 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, // long 0, long 0) // To: int* getelementptr ([3 x int]* %X, long 0, long 0) // - if (CE->isCast() && NumIdx > 1 && Idx0->isNullValue()) + if (CE->isCast() && NumIdx > 1 && Idx0->isNullValue()) { if (const PointerType *SPT = dyn_cast<PointerType>(CE->getOperand(0)->getType())) if (const ArrayType *SAT = dyn_cast<ArrayType>(SPT->getElementType())) @@ -1436,6 +1436,28 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, if (CAT->getElementType() == SAT->getElementType()) return ConstantExpr::getGetElementPtr( (Constant*)CE->getOperand(0), Idxs, NumIdx); + } + + // Fold: getelementptr (i8* inttoptr (i64 1 to i8*), i32 -1) + // Into: inttoptr (i64 0 to i8*) + // This happens with pointers to member functions in C++. + if (CE->getOpcode() == Instruction::IntToPtr && NumIdx == 1 && + isa<ConstantInt>(CE->getOperand(0)) && isa<ConstantInt>(Idxs[0]) && + cast<PointerType>(CE->getType())->getElementType() == Type::Int8Ty) { + Constant *Base = CE->getOperand(0); + Constant *Offset = Idxs[0]; + + // Convert the smaller integer to the larger type. + if (Offset->getType()->getPrimitiveSizeInBits() < + Base->getType()->getPrimitiveSizeInBits()) + Offset = ConstantExpr::getSExt(Offset, Base->getType()); + else if (Base->getType()->getPrimitiveSizeInBits() < + Offset->getType()->getPrimitiveSizeInBits()) + Base = ConstantExpr::getZExt(Base, Base->getType()); + + Base = ConstantExpr::getAdd(Base, Offset); + return ConstantExpr::getIntToPtr(Base, CE->getType()); + } } return 0; } |