From b9da9c137d3062dd2277937eaafa502fba2ffe3f Mon Sep 17 00:00:00 2001 From: Chris Lattner <sabre@nondot.org> Date: Tue, 25 Nov 2003 21:21:46 +0000 Subject: [PATCH] Relax constrains on GEP type indexes git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10228 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/VMCore/ConstantFold.cpp | 16 ++++++++++++---- lib/VMCore/Type.cpp | 10 ++++------ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index d86ef11ecf5..04ec28bfb83 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -15,6 +15,7 @@ #include "llvm/iPHINode.h" #include "llvm/InstrTypes.h" #include "llvm/DerivedTypes.h" +#include "llvm/Support/GetElementPtrTypeIterator.h" #include <cmath> 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<ConstantExpr>(C)) { + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(const_cast<Constant*>(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<ArrayType>(LastTy)) { std::vector<Constant*> NewIndices; NewIndices.reserve(IdxList.size() + CE->getNumOperands()); for (unsigned i = 1, e = CE->getNumOperands()-1; i != e; ++i) NewIndices.push_back(cast<Constant>(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/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index dd20b16987e..3c2fd8ca47f 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -261,10 +261,10 @@ const std::string &Type::getDescription() const { bool StructType::indexValid(const Value *V) const { - if (!isa<Constant>(V)) return false; - if (V->getType() != Type::UByteTy) return false; - unsigned Idx = cast<ConstantUInt>(V)->getValue(); - return Idx < ETypes.size(); + // Structure indexes require unsigned integer constants. + if (ConstantUInt *CU = dyn_cast<ConstantUInt>(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<Constant>(V) && "Structure index must be a constant!!"); - assert(V->getType() == Type::UByteTy && "Structure index must be ubyte!"); unsigned Idx = cast<ConstantUInt>(V)->getValue(); assert(Idx < ETypes.size() && "Structure index out of range!"); assert(indexValid(V) && "Invalid structure index!"); // Duplicate check - return ETypes[Idx]; }