mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
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
This commit is contained in:
parent
54b799dc76
commit
8674db5fbf
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user