[llvm-commits] [llvm] r81478 - in /llvm/trunk: include/llvm/Constants.h lib/Transforms/IPO/GlobalOpt.cpp lib/VMCore/ConstantFold.cpp lib/VMCore/Constants.cpp test/Transforms/InstCombine/getelementptr.ll
Dan Gohman
gohman at apple.com
Thu Sep 10 16:37:56 PDT 2009
Author: djg
Date: Thu Sep 10 18:37:55 2009
New Revision: 81478
URL: http://llvm.org/viewvc/llvm-project?rev=81478&view=rev
Log:
Factor out the code for checking that all indices in a getelementptr are
within the notional bounds of the static type of the getelementptr (which
is not the same as "inbounds") from GlobalOpt into a utility routine,
and use it in ConstantFold.cpp to check whether there are any mis-behaved
indices.
Modified:
llvm/trunk/include/llvm/Constants.h
llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
llvm/trunk/lib/VMCore/ConstantFold.cpp
llvm/trunk/lib/VMCore/Constants.cpp
llvm/trunk/test/Transforms/InstCombine/getelementptr.ll
Modified: llvm/trunk/include/llvm/Constants.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=81478&r1=81477&r2=81478&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Constants.h (original)
+++ llvm/trunk/include/llvm/Constants.h Thu Sep 10 18:37:55 2009
@@ -713,6 +713,13 @@
/// and the getIndices() method may be used.
bool hasIndices() const;
+ /// @brief Return true if this is a getelementptr expression and all
+ /// the index operands are compile-time known integers within the
+ /// corresponding notional static array extents. Note that this is
+ /// not equivalant to, a subset of, or a superset of the "inbounds"
+ /// property.
+ bool isGEPWithNoNotionalOverIndexing() const;
+
/// Select constant expr
///
static Constant *getSelect(Constant *C, Constant *V1, Constant *V2) {
Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=81478&r1=81477&r2=81478&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Thu Sep 10 18:37:55 2009
@@ -2045,25 +2045,14 @@
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);
Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=81478&r1=81477&r2=81478&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/ConstantFold.cpp (original)
+++ llvm/trunk/lib/VMCore/ConstantFold.cpp Thu Sep 10 18:37:55 2009
@@ -1329,6 +1329,14 @@
// 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();
Modified: llvm/trunk/lib/VMCore/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=81478&r1=81477&r2=81478&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Constants.cpp (original)
+++ llvm/trunk/lib/VMCore/Constants.cpp Thu Sep 10 18:37:55 2009
@@ -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 @@
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;
Modified: llvm/trunk/test/Transforms/InstCombine/getelementptr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/getelementptr.ll?rev=81478&r1=81477&r2=81478&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/getelementptr.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/getelementptr.ll Thu Sep 10 18:37:55 2009
@@ -459,3 +459,12 @@
; CHECK: ret i8* getelementptr ([11 x i8]* @array, i64 1676976733973595601, i64 4)
}
+; Instcombine shouldn't assume that gep(A,0,1) != gep(A,1,0).
+ at A37 = external constant [1 x i8]
+define i1 @test37() nounwind {
+; CHECK: @test37
+; CHECK: ret i1 icmp eq (i8* getelementptr ([1 x i8]* @A37, i64 0, i64 1), i8* getelementptr ([1 x i8]* @A37, i64 1, i64 0))
+ %t = icmp eq i8* getelementptr ([1 x i8]* @A37, i64 0, i64 1),
+ getelementptr ([1 x i8]* @A37, i64 1, i64 0)
+ ret i1 %t
+}
More information about the llvm-commits
mailing list