<div dir="ltr">The semantic reason is that the optimizer is required to assume that the i32 stores could be storing to the storage of myarray. LLVM IR does not permit optimizers to optimize based on the nominal types of memory objects or memory accesses.<div>
<br></div><div>This gets optimized in C, because the C compiler adds special TBAA metadata annotations to the loads and stores which say that the stores of "int" do not interfere with the loads of "pointer". It also gets optimized if myarray is const, because the optimizer knows that const memory is not modified by stores. It also gets optimized if myarray is an actual array, because then the address of the array is constant, rather than being a value loaded from memory.</div>
<div><div><br></div><div style>Dan</div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Apr 24, 2013 at 10:40 AM, Scott Pakin <span dir="ltr"><<a href="mailto:pakin@lanl.gov" target="_blank">pakin@lanl.gov</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I was suprised to find that some bitcode I'm generating isn't getting<br>
optimized.  Here, I'm doing the equivalent of "myarray[5]++" (on an<br>
"extern int *myarray"), repeated three times:<br>
<br>
    @myarray = external global i32*<br>
<br>
    define void @update_array() #0 {<br>
      %1 = load i32** @myarray, align 8<br>
      %2 = getelementptr inbounds i32* %1, i64 5<br>
      %3 = load i32* %2, align 4<br>
      %4 = add nsw i32 %3, 1<br>
      store i32 %4, i32* %2, align 4<br>
      %5 = load i32** @myarray, align 8<br>
      %6 = getelementptr inbounds i32* %5, i64 5<br>
      %7 = load i32* %6, align 4<br>
      %8 = add nsw i32 %7, 1<br>
      store i32 %8, i32* %6, align 4<br>
      %9 = load i32** @myarray, align 8<br>
      %10 = getelementptr inbounds i32* %9, i64 5<br>
      %11 = load i32* %10, align 4<br>
      %12 = add nsw i32 %11, 1<br>
      store i32 %12, i32* %10, align 4<br>
      ret void<br>
    }<br>
<br>
Running "opt -std-compile-opts" or even "opt -O3" doesn't seem to<br>
change the bitcode any.  I had expected the three increments by 1 to<br>
be collapsed into a single increment by 3:<br>
<br>
    @myarray = external global i32*<br>
<br>
    define void @update_array() #0 {<br>
      %1 = load i32** @myarray, align 8<br>
      %2 = load i32* %1, align 4<br>
      %3 = add nsw i32 %2, 3<br>
      store i32 %3, i32* %1, align 4<br>
      ret void<br>
    }<br>
<br>
Even the (x86-64) code generator doesn't do any last-minute<br>
optimizations:<br>
<br>
    movq    myarray(%rip), %rax<br>
    incl    20(%rax)<br>
    movq    myarray(%rip), %rax<br>
    incl    20(%rax)<br>
    movq    myarray(%rip), %rax<br>
    incl    20(%rax)<br>
<br>
This is with LLVM revision 180116.<br>
<br>
Is there some semantic reason that the increments aren't allowed to be<br>
combined, or is this a missed optimization opportunity in LLVM?<br>
<br>
Thanks,<br>
-- Scott<br>
______________________________<u></u>_________________<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/<u></u>mailman/listinfo/llvmdev</a><br>
</blockquote></div><br></div>