summaryrefslogtreecommitdiffstats
path: root/llvm/lib/VMCore
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/VMCore')
-rw-r--r--llvm/lib/VMCore/ConstantFold.cpp33
-rw-r--r--llvm/lib/VMCore/Constants.cpp4
2 files changed, 33 insertions, 4 deletions
diff --git a/llvm/lib/VMCore/ConstantFold.cpp b/llvm/lib/VMCore/ConstantFold.cpp
index ddd55878cb9..24b78ae969a 100644
--- a/llvm/lib/VMCore/ConstantFold.cpp
+++ b/llvm/lib/VMCore/ConstantFold.cpp
@@ -415,9 +415,38 @@ Constant *llvm::ConstantFoldCastInstruction(LLVMContext &Context,
return ConstantPointerNull::get(cast<PointerType>(DestTy));
return 0; // Other pointer types cannot be casted
case Instruction::PtrToInt: // always treated as unsigned
- if (V->isNullValue()) // is it a null pointer value?
+ // Is it a null pointer value?
+ if (V->isNullValue())
return ConstantInt::get(DestTy, 0);
- return 0; // Other pointer types cannot be casted
+ // If this is a sizeof of an array or vector, pull out a multiplication
+ // by the element size to expose it to subsequent folding.
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ if (CE->getOpcode() == Instruction::GetElementPtr &&
+ CE->getNumOperands() == 2 &&
+ CE->getOperand(0)->isNullValue())
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(CE->getOperand(1)))
+ if (CI->isOne()) {
+ const Type *Ty =
+ cast<PointerType>(CE->getOperand(0)->getType())->getElementType();
+ if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
+ Constant *N = ConstantInt::get(DestTy, ATy->getNumElements());
+ Constant *E = ConstantExpr::getSizeOf(ATy->getElementType());
+ E = ConstantExpr::getCast(CastInst::getCastOpcode(E, false,
+ DestTy, false),
+ E, DestTy);
+ return ConstantExpr::getMul(N, E);
+ }
+ if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) {
+ Constant *N = ConstantInt::get(DestTy, VTy->getNumElements());
+ Constant *E = ConstantExpr::getSizeOf(VTy->getElementType());
+ E = ConstantExpr::getCast(CastInst::getCastOpcode(E, false,
+ DestTy, false),
+ E, DestTy);
+ return ConstantExpr::getMul(N, E);
+ }
+ }
+ // Other pointer types cannot be casted
+ return 0;
case Instruction::UIToFP:
case Instruction::SIToFP:
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
diff --git a/llvm/lib/VMCore/Constants.cpp b/llvm/lib/VMCore/Constants.cpp
index 436083f62b0..9e1154e95e3 100644
--- a/llvm/lib/VMCore/Constants.cpp
+++ b/llvm/lib/VMCore/Constants.cpp
@@ -1479,10 +1479,10 @@ Constant* ConstantExpr::getSizeOf(const Type* Ty) {
}
Constant* ConstantExpr::getAlignOf(const Type* Ty) {
- // alignof is implemented as: (i64) gep ({i8,Ty}*)null, 0, 1
+ // alignof is implemented as: (i64) gep ({i1,Ty}*)null, 0, 1
// Note that a non-inbounds gep is used, as null isn't within any object.
const Type *AligningTy = StructType::get(Ty->getContext(),
- Type::getInt8Ty(Ty->getContext()), Ty, NULL);
+ Type::getInt1Ty(Ty->getContext()), Ty, NULL);
Constant *NullPtr = Constant::getNullValue(AligningTy->getPointerTo());
Constant *Zero = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 0);
Constant *One = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
OpenPOWER on IntegriCloud