<div dir="ltr">Ah, that explains why the "small example above" is not showing the problem... <div><br></div><div>Thanks for the explanation.<br><br>Shall I raise a bug?</div><div><br></div><div>--</div><div>Mats</div></div><div class="gmail_extra"><br><div class="gmail_quote">2015-11-06 22:57 GMT+00:00 Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">On Fri, Nov 6, 2015 at 2:43 PM, mats petersson via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Actual source below. Now with:<br><br><div>$ clang++ --version</div><div>clang version 3.8.0 (<a href="http://llvm.org/git/clang.git" target="_blank">http://llvm.org/git/clang.git</a> 27b8a29273862fa1e9e296be8f9850a1459115c8) (<a href="http://llvm.org/git/llvm.git" target="_blank">http://llvm.org/git/llvm.git</a> 91950eea5582709ea263cc48bd97fdea817b53d1)</div><div>Target: x86_64-unknown-linux-gnu</div><div>Thread model: posix</div><div>InstalledDir: /usr/local/bin</div><div><br><br></div><div><div>#include <cstdio></div><div>#include <cstring></div><div><br></div><div>#define LOOP_COUNT 1000000000</div><div><br></div><div>unsigned long long rdtscl(void)</div><div>{</div><div>    unsigned int lo, hi;</div><div>    __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));</div><div>    return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );</div><div>}</div><div><br></div><div>int main()</div><div>{</div><div>    unsigned long long before = rdtscl();</div><div>    size_t ret;</div><div>    for (int i = 0; i < LOOP_COUNT; i++)</div><div>        ret = strlen("abcd");</div><div>    unsigned long long after = rdtscl();</div><div>    printf("Strlen %lld ret=%zd\n",(after - before),  ret);</div><div><br></div><div>    before = rdtscl();</div><div>    for (int i = 0; i < LOOP_COUNT; i++)</div><span><div>        ret = sizeof("abcd");</div></span><div>    after = rdtscl();</div><div>    printf("Strlen %lld ret=%zd\n",(after - before),  ret);</div><div>}</div></div><div><br></div><div><br>llvm generated:<br><br><div>; Function Attrs: nounwind uwtable</div><div>define i32 @main() #0 {</div><div>entry:</div><div>  %0 = tail call { i32, i32 } asm sideeffect "rdtsc", "={ax},={dx},~{dirflag},~{fpsr},~{flags}"() #2, !srcloc !1</div><div>  %asmresult1.i = extractvalue { i32, i32 } %0, 1</div><div>  %conv2.i = zext i32 %asmresult1.i to i64</div><div>  %shl.i = shl nuw i64 %conv2.i, 32</div><div>  %asmresult.i = extractvalue { i32, i32 } %0, 0</div><div>  %conv.i = zext i32 %asmresult.i to i64</div><div>  %or.i = or i64 %shl.i, %conv.i</div><div>  %1 = tail call { i32, i32 } asm sideeffect "rdtsc", "={ax},={dx},~{dirflag},~{fpsr},~{flags}"() #2, !srcloc !1</div><div>  %asmresult.i.25 = extractvalue { i32, i32 } %1, 0</div><div>  %asmresult1.i.26 = extractvalue { i32, i32 } %1, 1</div><div>  %conv.i.27 = zext i32 %asmresult.i.25 to i64</div><div>  %conv2.i.28 = zext i32 %asmresult1.i.26 to i64</div><div>  %shl.i.29 = shl nuw i64 %conv2.i.28, 32</div><div>  %or.i.30 = or i64 %shl.i.29, %conv.i.27</div><div>  %sub = sub i64 %or.i.30, %or.i</div><div>  %call2 = tail call i32 (i8*, ...) @printf(i8* nonnull getelementptr inbounds ([21 x i8], [21 x i8]* @.str, i64 0, i64 0), i64 %sub, i64 4)</div><div>  %2 = tail call { i32, i32 } asm sideeffect "rdtsc", "={ax},={dx},~{dirflag},~{fpsr},~{flags}"() #2, !srcloc !1</div><div>  %asmresult1.i.32 = extractvalue { i32, i32 } %2, 1</div><div>  %conv2.i.34 = zext i32 %asmresult1.i.32 to i64</div><div>  %shl.i.35 = shl nuw i64 %conv2.i.34, 32</div><div>  br label %for.cond.5</div><div><br></div><div>for.cond.5:                                       ; preds = %for.cond.5, %entry</div><div>  %i4.0 = phi i32 [ 0, %entry ], [ %inc10.18, %for.cond.5 ]</div><div>  %inc10.18 = add nsw i32 %i4.0, 19</div><div>  %exitcond.18 = icmp eq i32 %inc10.18, 1000000001</div><div>  br i1 %exitcond.18, label %for.cond.cleanup.7, label %for.cond.5</div><div><br></div><div>for.cond.cleanup.7:                               ; preds = %for.cond.5</div><div>  %asmresult.i.31 = extractvalue { i32, i32 } %2, 0</div><div>  %conv.i.33 = zext i32 %asmresult.i.31 to i64</div><div>  %or.i.36 = or i64 %shl.i.35, %conv.i.33</div><div>  %3 = tail call { i32, i32 } asm sideeffect "rdtsc", "={ax},={dx},~{dirflag},~{fpsr},~{flags}"() #2, !srcloc !1</div><div>  %asmresult.i.37 = extractvalue { i32, i32 } %3, 0</div><div>  %asmresult1.i.38 = extractvalue { i32, i32 } %3, 1</div><div>  %conv.i.39 = zext i32 %asmresult.i.37 to i64</div><div>  %conv2.i.40 = zext i32 %asmresult1.i.38 to i64</div><div>  %shl.i.41 = shl nuw i64 %conv2.i.40, 32</div><div>  %or.i.42 = or i64 %shl.i.41, %conv.i.39</div><div>  %sub13 = sub i64 %or.i.42, %or.i.36</div><div>  %call14 = tail call i32 (i8*, ...) @printf(i8* nonnull getelementptr inbounds ([21 x i8], [21 x i8]* @.str, i64 0, i64 0), i64 %sub13, i64 5)</div><div>  ret i32 0</div><div>}<br><br><br>Am I missing something? </div></div></div></blockquote><div><br></div></div></div><div>Definitely looks like a bug. It's a consequence of both loops using the same 'ret' variable. More specifically, the second loop body ends up with a phi for the value of 'ret', whose value is either 4 or 5 depending on whether the loop body is executed 0 times or more than 0 times, and the existence of that phi prevents us from removing the second loop. (The phi disappears once we remove the first loop, but we don't try to remove the second loop again afterwards.)</div><div><br></div><div>[The 'add 19' is a comical red herring; we unroll the loop 19 times (as 19 is a largeish factor of the trip count), then fold all 19 'add 1' instructions into one, but this happens after simplifycfg has already tried and failed to remove the second loop.]</div><span class=""><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>--</div><div>Mats</div></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On 6 November 2015 at 16:10, mats petersson <span dir="ltr"><<a href="mailto:mats@planetcatfish.com" target="_blank">mats@planetcatfish.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Just to be clear: I was using -O2, and the "first loop" which has strlen in it was optimised to a constant value and no loop, the second loop, with sizeof, was not "removed".<br><br>--<br></div>Mats<br></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On 6 November 2015 at 14:30, Renato Golin via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 6 November 2015 at 14:25, Joerg Sonnenberger via cfe-dev<br>
<span><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br>
> Also, if you look at IR make sure to run the appropiate passes first.<br>
> Clang output by default has very few optimisations in the -emit-llvm<br>
> output.<br>
<br>
</span>That's intentional. Try -O2 and your IR will look much nicer. :)<br>
<br>
--renato<br>
<div><div>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
<br></blockquote></span></div><br></div></div>
</blockquote></div><br></div>