<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 15 January 2015 at 10:49, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@google.com" target="_blank">chandlerc@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span>On Thu, Jan 15, 2015 at 10:30 AM, Sanjay Patel <span dir="ltr"><<a href="mailto:spatel@rotateright.com" target="_blank">spatel@rotateright.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div>Would it be wrong to generate the llvm.assume IR suggested below? in GVN?</div></div></blockquote><div><br></div></span><div>I think so... Because:</div><span><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div bgcolor="#FFFFFF" text="#000000"><div>One very small tweak you could make would be to add an llvm.assume
      inside the if case of the if condition.  (Yes, that is as silly as
      it sounds.)  I tested that, and it did optimize as expected.  It's
      essentially working around a deficiency in the optimizer around
      path constraints.<br></div></div></blockquote></div></div></div></div></div></blockquote><div><br></div></span><div>Once upon a time, there was an optimization for this called predsimplify. I believe Nick can tell you a long, glorious, tragic tale about its life and ultimate death.</div></div></div></div></blockquote><div><br></div><div>Okay, gather 'round the fire. ;-)</div><div><br></div><div>Predsimplify was the first optimization pass I tried to write, to fix PR807. The basis was that it would propagate properties (icmp's between two SSA values) down paths in the domtree. In its various rewrites it knew all sorts of tricks. For instance it could do:</div><div><br></div><div>  a = b + c</div><div>  if b == 5:</div><div>    if c == 3:</div><div>      print a   # replace 'a' with 8</div><div><br></div><div>which requires that it solve a bidirectional dataflow problem. It also knew that a < b implied b > 0, and a < b < c implies that c > 1. Some of the things predsimplify used to do are now implemented inside gvn's processEquality. Predsimplify also had an odd trick:</div><div><br></div><div>  a = phi [0, a.i]</div><div>  b = phi [10, x]</div><div>  if a == 1:</div><div>    # here we know that b == x. (x could still equal 10 though.)</div><div><br></div><div>which I haven't seen replicated elsewhere in llvm.</div><div><br></div><div>I went through many iterations of the implementation trying to minimize the compile time impact. So why predsimplify die?</div><div><br></div><div>The first largest problem is that it rarely fired. It turns out that people don't write code which needs this sort of optimization in C very often, or at least in the llvm test suite. Instcombine already does a ton of optimization that overlapped with predsimplify in its demanded bits analysis, and that does a much better job of getting the cases that show up in real-world code. The cost of the analysis that predsimplify was doing, eagerly building up its value graph was too expensive to fit in llvm, especially when instcombine's demanded bits analysis tended to get the cases already. If your IR looks different, it might be worth adding to the pass pipeline for you.</div><div><br></div><div>I think a future VRP (value range propagation) pass would need to be a superset of simplify-demanded-bits, so that we could remove the cost of running simplify-demanded-bits to help pay for the VRP. I've been thinking about the data structure we could use for that, but haven't worked out all the operations yet.</div><div><br></div><div>Nick</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>In particular:<br></div><span><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div bgcolor="#FFFFFF" text="#000000"><div>
      <br>
      define void @example_tweaked(i64* %x0) #0 {<br>
        %1 = load i64* %x0, align 8<span><br>
        %2 = and i64 %1, 3<br>
        %3 = icmp eq i64 %2, 2<br>
        br i1 %3, label %4, label %8<br>
      ; <label>:4                                       ; preds =
      %0<br></span>
        call void @llvm.assume(i1 %3)</div></div></blockquote></div></div></div></div></div></blockquote><div><br></div></span><div>We don't need the assume here. If we want to do predicate-based simplification, we can just have <whatever> look at dominating branch conditions, much like it looks at dominating assume calls. Worst case is that it requires more fancy-ness in the assumption tracking infrastructure to actually funnel queries through to different ways of saying "this value is true at this point".</div><div><br></div><div>However, that is the core essence of predsimplify. Historically, we have found a really terrifying amount of complexity and compile time hit for relatively small gains in terms of generated code quality. =/ Maybe we just need to handle the "obvious" cases much like the very limited calls to assumption tracker do, but I think this path needs to be trod with great care.</div><div><div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div bgcolor="#FFFFFF" text="#000000"><div><span><br>
        %5 = and i64 %1, -4                ; this should be optimized
      away<br>
        %6 = or i64 %5, 2                  ; this should be optimized
      away<br>
        %7 = add nsw i64 %6, 12<br></span>
        store i64 %7, i64* %x0, align 8<span><br>
        ret void<br>
      ; <label>:8                                       ; preds =
      %0<br>
        tail call void @go_error() #2<br>
        unreachable<br>
      }<br>
      <br></span>
      declare void @llvm.assume(i1)<br>
    </div>
    <br>
    <br>
    <blockquote type="cite"><div><div>
      <div dir="ltr">
        <div><br>
        </div>
        <div>Thanks for any ideas,</div>
        <div>/Lars</div>
        <br>
        /***************************************************/<br>
        <div><br>
        </div>
        <div>/*  The two LSB of x0 are 'tag bits'  */</div>
        <div>/*  that we want to manipulate.       */</div>
        <div>extern long x0;</div>
        <div><br>
        </div>
        <div>void go_error(void) __attribute__ ((noreturn));</div>
        <div><br>
        </div>
        <div>void example_not_optimized(void)</div>
        <div>{</div>
        <div>  if((x0 & 3) == 2) {</div>
        <div>    // Here the tag bits are removed and added</div>
        <div>    // with bitwise 'and' and 'or'.</div>
        <div>    x0 = ((x0 & ~3) | 2) + 12;</div>
        <div>  } else {</div>
        <div>    go_error();</div>
        <div>  }</div>
        <div>}</div>
        <div><br>
        </div>
        <div>/*</div>
        <div>define void @example_not_optimized() #0 {</div>
        <div>  %1 = load i64* @x0, align 8, !tbaa !1</div>
        <div>  %2 = and i64 %1, 3</div>
        <div>  %3 = icmp eq i64 %2, 2</div>
        <div>  br i1 %3, label %4, label %8</div>
        <div><br>
        </div>
        <div>; <label>:4                                       ;
          preds = %0</div>
        <div>  %5 = and i64 %1, -4                ; this should be
          optimized away</div>
        <div>  %6 = or i64 %5, 2                  ; this should be
          optimized away</div>
        <div>  %7 = add nsw i64 %6, 12</div>
        <div>  store i64 %7, i64* @x0, align 8, !tbaa !1</div>
        <div>  ret void</div>
        <div><br>
        </div>
        <div>; <label>:8                                       ;
          preds = %0</div>
        <div>  tail call void @go_error() #2</div>
        <div>  unreachable</div>
        <div>}</div>
        <div>*/</div>
        <div><br>
        </div>
        <div><br>
        </div>
        <div>void example_optimized(void)</div>
        <div>{</div>
        <div>  if((x0 & 3) == 2) {</div>
        <div>    // Here the tag bits are removed and added</div>
        <div>    // with subtraction and addition.</div>
        <div>    x0 = (x0 - (x0 & 3) + 2) + 12;</div>
        <div>  } else {</div>
        <div>    go_error();</div>
        <div>  }</div>
        <div>}</div>
        <div><br>
        </div>
        <div>/*</div>
        <div>define void @example_optimized() #0 {</div>
        <div>  %1 = load i64* @x0, align 8, !tbaa !1</div>
        <div>  %2 = and i64 %1, 3</div>
        <div>  %3 = icmp eq i64 %2, 2</div>
        <div>  br i1 %3, label %4, label %6</div>
        <div><br>
        </div>
        <div>; <label>:4                                       ;
          preds = %0</div>
        <div>  %5 = add i64 %1, 12</div>
        <div>  store i64 %5, i64* @x0, align 8, !tbaa !1</div>
        <div>  ret void</div>
        <div><br>
        </div>
        <div>; <label>:6                                       ;
          preds = %0</div>
        <div>  tail call void @go_error() #2</div>
        <div>  unreachable</div>
        <div>}</div>
        <div><br>
        </div>
        <div> */</div>
        <div><br>
        </div>
      </div>
      <br>
      <fieldset></fieldset>
      <br>
      </div></div><pre>_______________________________________________
LLVM Developers mailing list
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a>
</pre>
    </blockquote>
    <br>
  </div>

<br>_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br></blockquote></div><br></div></div></div></div>
<br>_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br></blockquote></div></div></div><br></div></div>
<br>_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br></blockquote></div><br></div></div>