<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Feb 10, 2016 at 12:18 PM, Paul Peet via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</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">Thank you for the hint.<div><br></div><div>I adjusted the code and it works:</div><div><br></div><div>The code after replacing inttoptr with getelementptr:</div><div><br></div><div><div>define { i32, i32, i8* } @test(i32 %foo, i32 %bar, i8* %sp) {</div><div>entry:</div><span class=""><div>  ; push foo (On "stack")</div></span><div>  %sp_1 = getelementptr i8, i8* %sp, i32 -4</div><div>  %sp_1_ptr = bitcast i8* %sp_1 to i32*</div><span class=""><div>  store i32 %foo, i32* %sp_1_ptr, align 4</div><div><br></div><div>  ; push bar</div></span><div>  %sp_2 = getelementptr i8, i8* %sp_1, i32 -4</div><div>  %sp_2_ptr = bitcast i8* %sp_2 to i32*</div><span class=""><div>  store i32 %bar, i32* %sp_2_ptr, align 4</div><div><br></div><div>  ; val1 = pop (val1 = bar)</div></span><div>  %sp_3_ptr = bitcast i8* %sp_2 to i32*</div><span class=""><div>  %val1 = load i32, i32* %sp_3_ptr, align 4</div></span><div>  %sp_3 = getelementptr i8, i8* %sp_2, i32 4</div><span class=""><div><br></div><div>  ; val2 = pop (val2 = foo)</div></span><div>  %sp_4_ptr = bitcast i8* %sp_3 to i32*</div><span class=""><div>  %val2 = load i32, i32* %sp_4_ptr, align 4</div></span><div>  %sp_4 = getelementptr i8, i8* %sp_3, i32 4</div><div><br></div><div>  %ret_1 = insertvalue { i32, i32, i8* } undef, i32 %val1, 0</div><div>  %ret_2 = insertvalue { i32, i32, i8* } %ret_1, i32 %val2, 1</div><div>  %ret_3 = insertvalue { i32, i32, i8* } %ret_2, i8* %sp_4, 2</div><div><br></div><div>  ret { i32, i32, i8* } %ret_3</div><div>}</div></div><div><br></div><div>After optimization ("opt -instcombine ./code.ll -S")</div><div><br></div><div><div>define { i32, i32, i8* } @test(i32 %foo, i32 %bar, i8* %sp) {</div><div>entry:</div><div>  %sp_1 = getelementptr i8, i8* %sp, i64 -4</div><div>  %sp_1_ptr = bitcast i8* %sp_1 to i32*</div><span class=""><div>  store i32 %foo, i32* %sp_1_ptr, align 4</div></span><div>  %sp_2 = getelementptr i8, i8* %sp, i64 -8</div><div>  %sp_2_ptr = bitcast i8* %sp_2 to i32*</div><span class=""><div>  store i32 %bar, i32* %sp_2_ptr, align 4</div></span><div>  %ret_1 = insertvalue { i32, i32, i8* } undef, i32 %bar, 0</div><div>  %ret_2 = insertvalue { i32, i32, i8* } %ret_1, i32 %foo, 1</div><div>  %ret_3 = insertvalue { i32, i32, i8* } %ret_2, i8* %sp, 2</div><div>  ret { i32, i32, i8* } %ret_3</div><div>}</div></div><div><br></div><div>My only questions are now:</div><div>- How is it that inttoptr cannot provide that specific alias information so it can optimize that store/load away ?</div></div></blockquote><div>Because nothing tracks what happens to the ints, and what happens when they are converted back to pointers and whether it's sane :)</div><div> <a href="http://llvm.org/docs/GetElementPtr.html#how-is-gep-different-from-ptrtoint-arithmetic-and-inttoptr">http://llvm.org/docs/GetElementPtr.html#how-is-gep-different-from-ptrtoint-arithmetic-and-inttoptr</a></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>- Might it be possible to get inttoptr providing such alias analysis ?</div></div></blockquote><div>It doesn't make a lot of sense to try in most cases.</div><div>Most of the cases ptrtoint/inttoptr is useful are those where you want to do crazy things to the pointer.</div><div><br></div><div> </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>- I came across MemorySSA while browsing though the llvm source. Is it possible that one can use MemorySSA to do such optimization without alias analysis ?</div></div></blockquote><div><br></div><div>MemorySSA relies on alias analysis to generate the SSA form.</div><div> </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>- Where do I have to look in the source which is doing this kind of optimization (Is it instcombine which uses lib/Analysis/Loads.cpp ?)</div><div><br></div></div></blockquote><div>It's probably a combination of opts. The most likely candidate is -gvn, but  I would look at the pass dumps after each opt </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>Regards,</div><div>Paul</div><div><br></div></div><div class=""><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">2016-02-10 0:26 GMT+01:00 Philip Reames <span dir="ltr"><<a href="mailto:listmail@philipreames.com" target="_blank">listmail@philipreames.com</a>></span>:<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 text="#000000" bgcolor="#FFFFFF">
    Two points:<br>
    - Using inttoptr is a mistake here.  GEPs are strongly preferred and
    provide strictly more aliasing information to the optimizer.<br>
    - The zext is a bit weird.  I'm not sure where that came from, but
    I'd not bother looking into until the preceding point is addressed. 
    <br>
    <br>
    In general, you may find these docs useful:<br>
    <a href="http://llvm.org/docs/Frontend/PerformanceTips.html" target="_blank">http://llvm.org/docs/Frontend/PerformanceTips.html</a><br>
    <br>
    Philip<div><div><br>
    <br>
    <br>
    <div>On 02/08/2016 06:54 AM, Paul Peet via
      llvm-dev wrote:<br>
    </div>
    </div></div><blockquote type="cite"><div><div>
      <div dir="ltr">Hello,
        <div><br>
        </div>
        <div>I am trying to emulate the "stack" as like on x86 when
          using push/pop so afterwards I can use LLVM's optimizer passes
          to simplify (reduce junk) the code.</div>
        <div><br>
        </div>
        <div>The LLVM IR code:</div>
        <div><br>
        </div>
        <div>
          <div>define { i32, i32, i32 } @test(i32 %foo, i32 %bar, i32
            %sp) {</div>
          <div>  ; push foo (On "stack")</div>
          <div>  %sp_1 = sub i32 %sp, 4</div>
          <div>  %sp_1_ptr = inttoptr i32 %sp_1 to i32*</div>
          <div>  store i32 %foo, i32* %sp_1_ptr, align 4</div>
          <div><br>
          </div>
          <div>  ; push bar</div>
          <div>  %sp_2 = sub i32 %sp_1, 4</div>
          <div>  %sp_2_ptr = inttoptr i32 %sp_2 to i32*</div>
          <div>  store i32 %bar, i32* %sp_2_ptr, align 4</div>
          <div><br>
          </div>
          <div>  ; val1 = pop (val1 = bar)</div>
          <div>  %sp_3_ptr = inttoptr i32 %sp_2 to i32*</div>
          <div>  %val1 = load i32, i32* %sp_3_ptr, align 4</div>
          <div>  %sp_3 = add i32 %sp_2, 4</div>
          <div><br>
          </div>
          <div>  ; val2 = pop (val2 = foo)</div>
          <div>  %sp_4_ptr = inttoptr i32 %sp_3 to i32*</div>
          <div>  %val2 = load i32, i32* %sp_4_ptr, align 4</div>
          <div>  %sp_4 = add i32 %sp_3, 4</div>
          <div><br>
          </div>
          <div>  %ret_1 = insertvalue { i32, i32, i32 } undef, i32
            %val1, 0</div>
          <div>  %ret_2 = insertvalue { i32, i32, i32 } %ret_1, i32
            %val2, 1</div>
          <div>  %ret_3 = insertvalue { i32, i32, i32 } %ret_2, i32
            %sp_4, 2</div>
          <div><br>
          </div>
          <div>  ret { i32, i32, i32 } %ret_3</div>
          <div>}</div>
        </div>
        <div><br>
        </div>
        <div>This code will "push" two values onto the stack and pop
          them in reverse order so afterwards "foo" and "bar" will be
          swapped and returned back.</div>
        <div><br>
        </div>
        <div>After running this through "opt -O2 ./test.ll", I am
          getting this:</div>
        <div><br>
        </div>
        <div>
          <div>define { i32, i32, i32 } @test(i32 %foo, i32 %bar, i32
            %sp) #0 {</div>
          <div>  %sp_1 = add i32 %sp, -4</div>
          <div>  %1 = zext i32 %sp_1 to i64</div>
          <div>  %sp_1_ptr = inttoptr i64 %1 to i32*</div>
          <div>  store i32 %foo, i32* %sp_1_ptr, align 4</div>
          <div>  %sp_2 = add i32 %sp, -8</div>
          <div>  %2 = zext i32 %sp_2 to i64</div>
          <div>  %sp_2_ptr = inttoptr i64 %2 to i32*</div>
          <div>  store i32 %bar, i32* %sp_2_ptr, align 4</div>
          <div>  %val2 = load i32, i32* %sp_1_ptr, align 4</div>
          <div>  %ret_1 = insertvalue { i32, i32, i32 } undef, i32 %bar,
            0 ; Swapped</div>
          <div>  %ret_2 = insertvalue { i32, i32, i32 } %ret_1, i32
            %val2, 1; Not Swapped (Not optimized; Should be %foo)</div>
          <div>  %ret_3 = insertvalue { i32, i32, i32 } %ret_2, i32 %sp,
            2</div>
          <div>  ret { i32, i32, i32 } %ret_3</div>
          <div>}</div>
        </div>
        <div><br>
        </div>
        <div>As you can see that the IR has got additional code, eg.
          zext. But the main problem here is that val2 hasn't been
          optimized.</div>
        <div>Could anyone show me some hints what is preventing the
          second val from being optimized? (My guess would be the zext
          because I am using %sp as a 32bit pointer although the
          "target" is 64bit).</div>
        <div><br>
        </div>
        <div>Regards,</div>
        <div>Paul</div>
      </div>
      <br>
      <fieldset></fieldset>
      <br>
      </div></div><pre>_______________________________________________
LLVM Developers mailing list
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a>
</pre>
    </blockquote>
    <br>
  </div>

</blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
<br></blockquote></div><br></div></div>