diff --git a/llvm/lib/VMCore/ConstantHandling.cpp b/llvm/lib/VMCore/ConstantHandling.cpp index d86ef11ecf50..04ec28bfb83a 100644 --- a/llvm/lib/VMCore/ConstantHandling.cpp +++ b/llvm/lib/VMCore/ConstantHandling.cpp @@ -15,6 +15,7 @@ #include "llvm/iPHINode.h" #include "llvm/InstrTypes.h" #include "llvm/DerivedTypes.h" +#include "llvm/Support/GetElementPtrTypeIterator.h" #include using namespace llvm; @@ -159,22 +160,29 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, // TODO If C is null and all idx's are null, return null of the right type. - if (const ConstantExpr *CE = dyn_cast(C)) { + if (ConstantExpr *CE = dyn_cast(const_cast(C))) { // Combine Indices - If the source pointer to this getelementptr instruction // is a getelementptr instruction, combine the indices of the two // getelementptr instructions into a single instruction. // if (CE->getOpcode() == Instruction::GetElementPtr) { - if (CE->getOperand(CE->getNumOperands()-1)->getType() == Type::LongTy) { + const Type *LastTy = 0; + for (gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE); + I != E; ++I) + LastTy = *I; + + if (LastTy && isa(LastTy)) { std::vector NewIndices; NewIndices.reserve(IdxList.size() + CE->getNumOperands()); for (unsigned i = 1, e = CE->getNumOperands()-1; i != e; ++i) NewIndices.push_back(cast(CE->getOperand(i))); // Add the last index of the source with the first index of the new GEP. + // Make sure to handle the case when they are actually different types. Constant *Combined = - ConstantExpr::get(Instruction::Add, IdxList[0], - CE->getOperand(CE->getNumOperands()-1)); + ConstantExpr::get(Instruction::Add, + ConstantExpr::getCast(IdxList[0], Type::LongTy), + ConstantExpr::getCast(CE->getOperand(CE->getNumOperands()-1), Type::LongTy)); NewIndices.push_back(Combined); NewIndices.insert(NewIndices.end(), IdxList.begin()+1, IdxList.end()); diff --git a/llvm/lib/VMCore/Type.cpp b/llvm/lib/VMCore/Type.cpp index dd20b16987e0..3c2fd8ca47ff 100644 --- a/llvm/lib/VMCore/Type.cpp +++ b/llvm/lib/VMCore/Type.cpp @@ -261,10 +261,10 @@ const std::string &Type::getDescription() const { bool StructType::indexValid(const Value *V) const { - if (!isa(V)) return false; - if (V->getType() != Type::UByteTy) return false; - unsigned Idx = cast(V)->getValue(); - return Idx < ETypes.size(); + // Structure indexes require unsigned integer constants. + if (ConstantUInt *CU = dyn_cast(V)) + return CU->getValue() < ETypes.size(); + return false; } // getTypeAtIndex - Given an index value into the type, return the type of the @@ -272,11 +272,9 @@ bool StructType::indexValid(const Value *V) const { // const Type *StructType::getTypeAtIndex(const Value *V) const { assert(isa(V) && "Structure index must be a constant!!"); - assert(V->getType() == Type::UByteTy && "Structure index must be ubyte!"); unsigned Idx = cast(V)->getValue(); assert(Idx < ETypes.size() && "Structure index out of range!"); assert(indexValid(V) && "Invalid structure index!"); // Duplicate check - return ETypes[Idx]; }