[llvm-commits] [PATCH] Add support to ValueTracking for determining that a pointer is non-null by virtue of inbounds GEPs that preclude a null pointer.

Chandler Carruth chandlerc at gmail.com
Thu Dec 6 15:42:17 PST 2012


  New version of patch, addressing most of Duncan's feedback.

Hi bkramer,

http://llvm-reviews.chandlerc.com/D160

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D160?vs=417&id=458#toc

BRANCH
  non-null

ARCANIST PROJECT
  llvm

Files:
  lib/Analysis/ValueTracking.cpp

Index: lib/Analysis/ValueTracking.cpp
===================================================================
--- lib/Analysis/ValueTracking.cpp
+++ lib/Analysis/ValueTracking.cpp
@@ -866,11 +866,16 @@
 ///
 /// Uses properties inherent in a GEP to try to determine whether it is known
 /// to be non-null.
+///
+/// Currently this routine does not support vector GEPs.
 static bool isGEPKnownNonNull(GEPOperator *GEP, const DataLayout *DL,
                               unsigned Depth) {
   if (!GEP->isInBounds() || GEP->getPointerAddressSpace() != 0)
     return false;
 
+  // FIXME: Support vector-GEPs.
+  assert(GEP->getType()->isPointerTy() && "We only support plain pointer GEP");
+
   // If the base pointer is non-null, we cannot walk to a null address with an
   // inbounds GEP in address space zero.
   if (isKnownNonZero(GEP->getPointerOperand(), DL, Depth))
@@ -885,26 +890,28 @@
   // inherently violate the inbounds contract within address space zero.
   for (gep_type_iterator GTI = gep_type_begin(GEP), GTE = gep_type_end(GEP);
        GTI != GTE; ++GTI) {
-    ConstantInt *OpC = dyn_cast<ConstantInt>(GTI.getOperand());
-    if (!OpC && Depth >= MaxDepth)
-      return false;
-
-    // If we have a non-zero constant or a known-non-zero value, we can try to
-    // reason about the GEP.
-    if ((!OpC && !isKnownNonZero(GTI.getOperand(), DL, Depth++)) ||
-        (OpC && OpC->isZero()))
-      continue;
-
+    // Struct types are easy -- they must always be indexed by a constant.
     if (StructType *STy = dyn_cast<StructType>(*GTI)) {
-      assert(OpC && "Only constants can index a struct!");
+      ConstantInt *OpC = cast<ConstantInt>(GTI.getOperand());
       unsigned ElementIdx = OpC->getZExtValue();
       const StructLayout *SL = DL->getStructLayout(STy);
       uint64_t ElementOffset = SL->getElementOffset(ElementIdx);
       if (ElementOffset > 0)
         return true;
-    } else if (DL->getTypeAllocSize(GTI.getIndexedType()) > 0) {
-      return true;
+      continue;
     }
+
+    // If we have a zero-sized type, the index doesn't matter. Keep looing.
+    if (DL->getTypeAllocSize(GTI.getIndexedType()) == 0)
+      continue;
+
+    // Check to see if the index is non-zero by recursing.
+    // Note that we don't increment Depth here because isKnownNonZero
+    // increments it for any non-constant operand. We want exactly that
+    // behavior, as we want to zip through constants, but not waste lots of
+    // time analyzing non-constants.
+    if (isKnownNonZero(GTI.getOperand(), DL, Depth))
+      return true;
   }
 
   return false;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D160.3.patch
Type: text/x-patch
Size: 2594 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20121206/b700125b/attachment.bin>


More information about the llvm-commits mailing list