<div dir="ltr">constexpr is a red herring here - except in 4, where you've used the constexpr keyword to create a constexpr context, in 1-3 these are just normal function calls the compiler optimizes as it sees fit - and it seems it saw fit to unroll and optimize to a constant cases 1 and 2, but not case 3 (perhaps because it was too long/some other middle-end optimization decided to bail out).<br><br>I couldn't say for sure exactly which LLVM optimization bailed out early, or whether LLVM is using the same general approach as GCC here.<br><br>Adding/removing the constexpr keyword from count_x shouldn't affect anything in cases 1-3 (in either Clang or GCC, really). But looks like it makes a big difference to GCC - perhaps GCC tries to evaluate constexpr in the frontend even when the language doesn't require it. Sounds like a recipe for some problematic compile-time to me... but don't know.<br><br>- Dave</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Sep 25, 2019 at 12:37 PM Christopher Williams via cfe-users <<a href="mailto:cfe-users@lists.llvm.org">cfe-users@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Given the code below, clang produces a constant value for test1, test2<br>
and test4. Why doesn't it for test3?<br>
This is more of a curious query, than a request for help, but if someone<br>
does have the answer, I'd appreciate as much detail as possible.<br>
||<br>
<br>
    |staticconstexprintcount_x(constchar*str){intcount{};for(;*str<br>
    !=0;++str){count +=*str<br>
    =='x';}returncount;}#defineSTRx1"123456789x"#defineSTRx4STRx1STRx1STRx1STRx1#defineSTRx8STRx4STRx4#defineSTRx16STRx8STRx8inttest1(){returncount_x(STRx4);}inttest2(){returncount_x(STRx8);}inttest3(){returncount_x(STRx16);}inttest4(){constexprautok<br>
    =count_x(STRx16);returnk;}|<br>
<br>
<br>
    |test1():# @test1()mov eax,4ret test2():# @test2()mov eax,8ret<br>
    test3():# @test3()xor eax,eax mov dl,49mov ecx,offset<br>
    .L.str.2+1.LBB2_1:# =>This Inner Loop Header: Depth=1xor esi,esi cmp<br>
    dl,120sete sil add eax,esi movzx edx,byte ptr [rcx]add rcx,1test<br>
    dl,dl jne .LBB2_1 ret test4():# @test4()mov eax,16ret<br>
    .L.str.2:.asciz<br>
    "123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x"|<br>
<br>
gcc does:<br>
<br>
    |test1():mov eax,4ret test2():mov eax,8ret test3():mov eax,16ret<br>
    test4():mov eax,16ret|<br>
<br>
Compilation command lines used:<br>
<br>
|clang++-Ofast-std=c++2a-S -o --c src/test.cpp |grep -Ev$'^\t+\\.'gcc9<br>
-Ofast-std=c++2a-S -o --c src/test.cpp |grep -Ev$'^\t+\\.'|<br>
<br>
Compiler Explorer: <a href="https://godbolt.org/z/V-3MEp" rel="noreferrer" target="_blank">https://godbolt.org/z/V-3MEp</a><br>
<br>
<br>
<br>
_______________________________________________<br>
cfe-users mailing list<br>
<a href="mailto:cfe-users@lists.llvm.org" target="_blank">cfe-users@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users</a><br>
</blockquote></div>