diff options
Diffstat (limited to 'llvm/lib/VMCore')
| -rw-r--r-- | llvm/lib/VMCore/ConstantFold.cpp | 33 | ||||
| -rw-r--r-- | llvm/lib/VMCore/Constants.cpp | 4 |
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); |

