Actually, while you are at it, sqlite3 is also showing a jump for the same commit range:<div>  <a href="http://llvm.org/perf/db_default/v4/nts/graph?plot.0=7.402.2&highlight_run=6629" target="_blank">http://llvm.org/perf/db_default/v4/nts/graph?plot.0=7.402.2&highlight_run=6629</a></div>

<div>sqlite3 also seems to not have liked:</div><div>  <a href="http://llvm.org/viewvc/llvm-project?view=rev&revision=169697" target="_blank">http://llvm.org/viewvc/llvm-project?view=rev&revision=169697</a></div>
<div><br></div><div> - Daniel</div>
<div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Dec 11, 2012 at 2:59 PM, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@gmail.com" target="_blank">chandlerc@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="font-family:arial,helvetica,sans-serif;font-size:10pt"><div dir="ltr">Yea, for a single source to regress stably is weird... i'll look.</div>
<div><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Dec 11, 2012 at 2:55 PM, Daniel Dunbar <span dir="ltr"><<a href="mailto:daniel@zuster.org" target="_blank">daniel@zuster.org</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hey Chandler,<div><br></div><div>It looks like this might have caused a small regression on:</div><div>  <span style="font-size:12px;font-family:Helvetica,sans-serif">SingleSource/Benchmarks/Shootout-C++/hash2</span></div>


<div><span style="font-size:12px;font-family:Helvetica,sans-serif">that seems to have stuck around:</span></div><div>  <a href="http://llvm.org/perf/db_default/v4/nts/graph?plot.0=7.41.2&highlight_run=6629" target="_blank">http://llvm.org/perf/db_default/v4/nts/graph?plot.0=7.41.2&highlight_run=6629</a><br>


</div><div><br></div><div>It's pretty small, but might be interesting if you feel like investigating.</div><span><font color="#888888"><div><br></div><div> - Daniel</div></font></span><div>
<div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Dec 6, 2012 at 6:08 PM, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@gmail.com" target="_blank">chandlerc@gmail.com</a>></span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: chandlerc<br>
Date: Thu Dec  6 20:08:58 2012<br>
New Revision: 169573<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=169573&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=169573&view=rev</a><br>
Log:<br>
Add support to ValueTracking for determining that a pointer is non-null<br>
by virtue of inbounds GEPs that preclude a null pointer.<br>
<br>
This is a very common pattern in the code generated by std::vector and<br>
other standard library routines which use allocators that test for null<br>
pervasively. This is one step closer to teaching Clang+LLVM to be able<br>
to produce an empty function for:<br>
<br>
  void f() {<br>
    std::vector<int> v;<br>
    v.push_back(1);<br>
    v.push_back(2);<br>
    v.push_back(3);<br>
    v.push_back(4);<br>
  }<br>
<br>
Which is related to getting them to completely fold SmallVector<br>
push_back sequences into constants when inlining and other optimizations<br>
make that a possibility.<br>
<br>
Modified:<br>
    llvm/trunk/lib/Analysis/ValueTracking.cpp<br>
    llvm/trunk/test/Transforms/InstSimplify/compare.ll<br>
<br>
Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=169573&r1=169572&r2=169573&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=169573&r1=169572&r2=169573&view=diff</a><br>



==============================================================================<br>
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)<br>
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Thu Dec  6 20:08:58 2012<br>
@@ -862,6 +862,72 @@<br>
   return false;<br>
 }<br>
<br>
+/// \brief Test whether a GEP's result is known to be non-null.<br>
+///<br>
+/// Uses properties inherent in a GEP to try to determine whether it is known<br>
+/// to be non-null.<br>
+///<br>
+/// Currently this routine does not support vector GEPs.<br>
+static bool isGEPKnownNonNull(GEPOperator *GEP, const DataLayout *DL,<br>
+                              unsigned Depth) {<br>
+  if (!GEP->isInBounds() || GEP->getPointerAddressSpace() != 0)<br>
+    return false;<br>
+<br>
+  // FIXME: Support vector-GEPs.<br>
+  assert(GEP->getType()->isPointerTy() && "We only support plain pointer GEP");<br>
+<br>
+  // If the base pointer is non-null, we cannot walk to a null address with an<br>
+  // inbounds GEP in address space zero.<br>
+  if (isKnownNonZero(GEP->getPointerOperand(), DL, Depth))<br>
+    return true;<br>
+<br>
+  // Past this, if we don't have DataLayout, we can't do much.<br>
+  if (!DL)<br>
+    return false;<br>
+<br>
+  // Walk the GEP operands and see if any operand introduces a non-zero offset.<br>
+  // If so, then the GEP cannot produce a null pointer, as doing so would<br>
+  // inherently violate the inbounds contract within address space zero.<br>
+  for (gep_type_iterator GTI = gep_type_begin(GEP), GTE = gep_type_end(GEP);<br>
+       GTI != GTE; ++GTI) {<br>
+    // Struct types are easy -- they must always be indexed by a constant.<br>
+    if (StructType *STy = dyn_cast<StructType>(*GTI)) {<br>
+      ConstantInt *OpC = cast<ConstantInt>(GTI.getOperand());<br>
+      unsigned ElementIdx = OpC->getZExtValue();<br>
+      const StructLayout *SL = DL->getStructLayout(STy);<br>
+      uint64_t ElementOffset = SL->getElementOffset(ElementIdx);<br>
+      if (ElementOffset > 0)<br>
+        return true;<br>
+      continue;<br>
+    }<br>
+<br>
+    // If we have a zero-sized type, the index doesn't matter. Keep looping.<br>
+    if (DL->getTypeAllocSize(GTI.getIndexedType()) == 0)<br>
+      continue;<br>
+<br>
+    // Fast path the constant operand case both for efficiency and so we don't<br>
+    // increment Depth when just zipping down an all-constant GEP.<br>
+    if (ConstantInt *OpC = dyn_cast<ConstantInt>(GTI.getOperand())) {<br>
+      if (!OpC->isZero())<br>
+        return true;<br>
+      continue;<br>
+    }<br>
+<br>
+    // We post-increment Depth here because while isKnownNonZero increments it<br>
+    // as well, when we pop back up that increment won't persist. We don't want<br>
+    // to recurse 10k times just because we have 10k GEP operands. We don't<br>
+    // bail completely out because we want to handle constant GEPs regardless<br>
+    // of depth.<br>
+    if (Depth++ >= MaxDepth)<br>
+      continue;<br>
+<br>
+    if (isKnownNonZero(GTI.getOperand(), DL, Depth))<br>
+      return true;<br>
+  }<br>
+<br>
+  return false;<br>
+}<br>
+<br>
 /// isKnownNonZero - Return true if the given value is known to be non-zero<br>
 /// when defined.  For vectors return true if every element is known to be<br>
 /// non-zero when defined.  Supports values with integer or pointer type and<br>
@@ -881,6 +947,13 @@<br>
   if (Depth++ >= MaxDepth)<br>
     return false;<br>
<br>
+  // Check for pointer simplifications.<br>
+  if (V->getType()->isPointerTy()) {<br>
+    if (GEPOperator *GEP = dyn_cast<GEPOperator>(V))<br>
+      if (isGEPKnownNonNull(GEP, TD, Depth))<br>
+        return true;<br>
+  }<br>
+<br>
   unsigned BitWidth = getBitWidth(V->getType(), TD);<br>
<br>
   // X | Y != 0 if X != 0 or Y != 0.<br>
<br>
Modified: llvm/trunk/test/Transforms/InstSimplify/compare.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/compare.ll?rev=169573&r1=169572&r2=169573&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/compare.ll?rev=169573&r1=169572&r2=169573&view=diff</a><br>



==============================================================================<br>
--- llvm/trunk/test/Transforms/InstSimplify/compare.ll (original)<br>
+++ llvm/trunk/test/Transforms/InstSimplify/compare.ll Thu Dec  6 20:08:58 2012<br>
@@ -165,6 +165,46 @@<br>
   ret i1 %cmp<br>
 }<br>
<br>
+define i1 @gep13(i8* %ptr) {<br>
+; CHECK: @gep13<br>
+; We can prove this GEP is non-null because it is inbounds.<br>
+  %x = getelementptr inbounds i8* %ptr, i32 1<br>
+  %cmp = icmp eq i8* %x, null<br>
+  ret i1 %cmp<br>
+; CHECK-NEXT: ret i1 false<br>
+}<br>
+<br>
+define i1 @gep14({ {}, i8 }* %ptr) {<br>
+; CHECK: @gep14<br>
+; We can't simplify this because the offset of one in the GEP actually doesn't<br>
+; move the pointer.<br>
+  %x = getelementptr inbounds { {}, i8 }* %ptr, i32 0, i32 1<br>
+  %cmp = icmp eq i8* %x, null<br>
+  ret i1 %cmp<br>
+; CHECK-NOT: ret i1 false<br>
+}<br>
+<br>
+define i1 @gep15({ {}, [4 x {i8, i8}]}* %ptr, i32 %y) {<br>
+; CHECK: @gep15<br>
+; We can prove this GEP is non-null even though there is a user value, as we<br>
+; would necessarily violate inbounds on one side or the other.<br>
+  %x = getelementptr inbounds { {}, [4 x {i8, i8}]}* %ptr, i32 0, i32 1, i32 %y, i32 1<br>
+  %cmp = icmp eq i8* %x, null<br>
+  ret i1 %cmp<br>
+; CHECK-NEXT: ret i1 false<br>
+}<br>
+<br>
+define i1 @gep16(i8* %ptr, i32 %a) {<br>
+; CHECK: @gep16<br>
+; We can prove this GEP is non-null because it is inbounds and because we know<br>
+; %b is non-zero even though we don't know its value.<br>
+  %b = or i32 %a, 1<br>
+  %x = getelementptr inbounds i8* %ptr, i32 %b<br>
+  %cmp = icmp eq i8* %x, null<br>
+  ret i1 %cmp<br>
+; CHECK-NEXT: ret i1 false<br>
+}<br>
+<br>
 define i1 @zext(i32 %x) {<br>
 ; CHECK: @zext<br>
   %e1 = zext i32 %x to i64<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br></blockquote></div><br></div></div></div></div>
</blockquote></div><br></div>