aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/IPO/GlobalOpt.cpp19
-rw-r--r--lib/VMCore/ConstantFold.cpp8
-rw-r--r--lib/VMCore/Constants.cpp26
3 files changed, 38 insertions, 15 deletions
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp
index b995a3d..63bc03d 100644
--- a/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/lib/Transforms/IPO/GlobalOpt.cpp
@@ -2045,25 +2045,14 @@ static bool isSimpleEnoughPointerToCommit(Constant *C, LLVMContext &Context) {
if (!GV->hasDefinitiveInitializer())
return false;
- gep_type_iterator GEPI = gep_type_begin(CE), E = gep_type_end(CE);
- User::op_iterator OI = next(CE->op_begin());
-
// The first index must be zero.
- ConstantInt *CI = dyn_cast<ConstantInt>(*OI);
+ ConstantInt *CI = dyn_cast<ConstantInt>(*next(CE->op_begin()));
if (!CI || !CI->isZero()) return false;
- ++GEPI;
- ++OI;
// The remaining indices must be compile-time known integers within the
- // bounds of the corresponding static array types.
- for (; GEPI != E; ++GEPI, ++OI) {
- CI = dyn_cast<ConstantInt>(*OI);
- if (!CI) return false;
- if (const ArrayType *ATy = dyn_cast<ArrayType>(*GEPI))
- if (CI->getValue().getActiveBits() > 64 ||
- CI->getZExtValue() >= ATy->getNumElements())
- return false;
- }
+ // notional bounds of the corresponding static array types.
+ if (!CE->isGEPWithNoNotionalOverIndexing())
+ return false;
return ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE,
Context);
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index 701a195..da6c8d4 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -1329,6 +1329,14 @@ static ICmpInst::Predicate evaluateICmpRelation(LLVMContext &Context,
// ordering of the resultant pointers.
unsigned i = 1;
+ // The logic below assumes that the result of the comparison
+ // can be determined by finding the first index that differs.
+ // This doesn't work if there is over-indexing in any
+ // subsequent indices, so check for that case first.
+ if (!CE1->isGEPWithNoNotionalOverIndexing() ||
+ !CE2->isGEPWithNoNotionalOverIndexing())
+ return ICmpInst::BAD_ICMP_PREDICATE; // Might be equal.
+
// Compare all of the operands the GEP's have in common.
gep_type_iterator GTI = gep_type_begin(CE1);
for (;i != CE1->getNumOperands() && i != CE2->getNumOperands();
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index a5b4f28..54445cd 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -28,6 +28,7 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/System/Mutex.h"
#include "llvm/System/RWMutex.h"
#include "llvm/System/Threading.h"
@@ -652,6 +653,31 @@ bool ConstantExpr::isCompare() const {
return getOpcode() == Instruction::ICmp || getOpcode() == Instruction::FCmp;
}
+bool ConstantExpr::isGEPWithNoNotionalOverIndexing() const {
+ if (getOpcode() != Instruction::GetElementPtr) return false;
+
+ gep_type_iterator GEPI = gep_type_begin(this), E = gep_type_end(this);
+ User::const_op_iterator OI = next(this->op_begin());
+
+ // Skip the first index, as it has no static limit.
+ ++GEPI;
+ ++OI;
+
+ // The remaining indices must be compile-time known integers within the
+ // bounds of the corresponding notional static array types.
+ for (; GEPI != E; ++GEPI, ++OI) {
+ ConstantInt *CI = dyn_cast<ConstantInt>(*OI);
+ if (!CI) return false;
+ if (const ArrayType *ATy = dyn_cast<ArrayType>(*GEPI))
+ if (CI->getValue().getActiveBits() > 64 ||
+ CI->getZExtValue() >= ATy->getNumElements())
+ return false;
+ }
+
+ // All the indices checked out.
+ return true;
+}
+
bool ConstantExpr::hasIndices() const {
return getOpcode() == Instruction::ExtractValue ||
getOpcode() == Instruction::InsertValue;