<div dir="ltr"><div dir="ltr">I guess that somehow turns this inline declaration into the strong definition (despite the extern declaration coming after the inline definition). eg, that definition is emitted even without the call:<br><br><div style="color:rgb(212,212,212);background-color:rgb(30,30,30);font-family:Consolas,"Liberation Mono",Courier,monospace,Menlo,Monaco,"Courier New",monospace;font-size:14px;line-height:21px;white-space:pre"><div><span style="color:rgb(86,156,214)">inline</span> <span style="color:rgb(86,156,214)">int</span> foo<span style="color:rgb(220,220,220)">()</span> <span style="color:rgb(220,220,220)">{</span> <span style="color:rgb(220,220,220)">}</span></div><div><span style="color:rgb(86,156,214)">extern</span> <span style="color:rgb(86,156,214)">inline</span> <span style="color:rgb(86,156,214)">int</span> foo<span style="color:rgb(220,220,220)">();</span> </div><div><span style="color:rgb(86,156,214)">int</span> bar<span style="color:rgb(220,220,220)">()</span> <span style="color:rgb(220,220,220)">{</span> <span style="color:rgb(220,220,220)">}</span></div></div></div><br>But yeah, some way of specifying an extern definition (either separately, or by promoting the prior inline definition to an extern inline definition) is necessary. C inline is quirky (well, compared to C++ - they're probably all a bit quirky, just a matter of what you're used to).<br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Aug 2, 2021 at 12:38 PM <<a href="mailto:paul.robinson@sony.com">paul.robinson@sony.com</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">





<div lang="EN-US" style="overflow-wrap: break-word;">
<div class="gmail-m_-978280245012855987WordSection1">
<p class="MsoNormal">Clarification: According to the link provided earlier,<u></u><u></u></p>
<p class="MsoNormal"><a href="https://urldefense.com/v3/__https:/www.iar.com/knowledge/support/technical-notes/compiler/linker-error-undefined-external-for-inline-functions/__;!!JmoZiZGBv3RvKRSx!paBsrfUr-uf55wvDrS1ZhpJyGUWkUvK3z1VJ0TJpsN40LC2e5h7vMT7ROvhd9mOxyQ$" target="_blank">https://www.iar.com/knowledge/support/technical-notes/compiler/linker-error-undefined-external-for-inline-functions/</a><br>
you need (exactly one) extern _<i>declaration</i>_ of the inline function, to keep it from vanishing.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">inline int foo() { stuff; }<u></u><u></u></p>
<p class="MsoNormal">extern inline int foo(); // not a definition<u></u><u></u></p>
<p class="MsoNormal">int bar() { return foo(); }<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">--paulr<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div style="border-top:none;border-right:none;border-bottom:none;border-left:1.5pt solid blue;padding:0in 0in 0in 4pt">
<div>
<div style="border-right:none;border-bottom:none;border-left:none;border-top:1pt solid rgb(225,225,225);padding:3pt 0in 0in">
<p class="MsoNormal"><b>From:</b> llvm-dev <<a href="mailto:llvm-dev-bounces@lists.llvm.org" target="_blank">llvm-dev-bounces@lists.llvm.org</a>> <b>On Behalf Of
</b>David Blaikie via llvm-dev<br>
<b>Sent:</b> Monday, August 2, 2021 3:18 PM<br>
<b>To:</b> Mariusz Sikora <<a href="mailto:msikora87@gmail.com" target="_blank">msikora87@gmail.com</a>><br>
<b>Cc:</b> llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>Subject:</b> Re: [llvm-dev] Inline function not eventually inlined is removed<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">Looks like both Clang and GCC discard the inline function definition even if the function is not inlined and the definition is needed (because C requires there be a separate non-inline definition for correctness): <a href="https://urldefense.com/v3/__https:/godbolt.org/z/hPjv1d1db__;!!JmoZiZGBv3RvKRSx!paBsrfUr-uf55wvDrS1ZhpJyGUWkUvK3z1VJ0TJpsN40LC2e5h7vMT7ROvhjMD0L0A$" target="_blank">https://godbolt.org/z/hPjv1d1db</a><br>
<br>
This code is probably (in C++ standard terminology, I'm not sure what terminology the C standard uses) "invalid, no diagnostic required" - that's usually the language for stuff that can cause linker errors like this.<u></u><u></u></p>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal">On Mon, Aug 2, 2021 at 10:05 AM Mariusz Sikora <<a href="mailto:msikora87@gmail.com" target="_blank">msikora87@gmail.com</a>> wrote:<u></u><u></u></p>
</div>
<blockquote style="border-top:none;border-right:none;border-bottom:none;border-left:1pt solid rgb(204,204,204);padding:0in 0in 0in 6pt;margin-left:4.8pt;margin-right:0in">
<div>
<p class="MsoNormal">I'm just trying to understand is this _Code_ undefined behavior or this is a bug in LLVM? Because why LLVM is removing functions without inlining it? For example GCC is not removing function event after inlining it.<u></u><u></u></p>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal">On Fri, Jul 30, 2021 at 7:16 PM Fangrui Song <<a href="mailto:maskray@google.com" target="_blank">maskray@google.com</a>> wrote:<u></u><u></u></p>
</div>
<blockquote style="border-top:none;border-right:none;border-bottom:none;border-left:1pt solid rgb(204,204,204);padding:0in 0in 0in 6pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal" style="margin-bottom:12pt">On 2021-07-30, David Blaikie via llvm-dev wrote:<br>
>You're probably looking for some documentation about C inline semantics:<br>
><a href="https://urldefense.com/v3/__https:/www.iar.com/knowledge/support/technical-notes/compiler/linker-error-undefined-external-for-inline-functions/__;!!JmoZiZGBv3RvKRSx!paBsrfUr-uf55wvDrS1ZhpJyGUWkUvK3z1VJ0TJpsN40LC2e5h7vMT7ROvhd9mOxyQ$" target="_blank">https://www.iar.com/knowledge/support/technical-notes/compiler/linker-error-undefined-external-for-inline-functions/</a><br>
<br>
Additional notes: I think the -fgnu89-inline & C99 inline semantics were<br>
designed explicitly the way so that vague linkage<br>
(<a href="https://urldefense.com/v3/__https:/itanium-cxx-abi.github.io/cxx-abi/abi/prop-72-comdat.html__;!!JmoZiZGBv3RvKRSx!paBsrfUr-uf55wvDrS1ZhpJyGUWkUvK3z1VJ0TJpsN40LC2e5h7vMT7ROvga_9S8Zw$" target="_blank">https://itanium-cxx-abi.github.io/cxx-abi/abi/prop-72-comdat.html</a>)
 can<br>
be avoided. The C inline behaviors are like always explicit<br>
instantiation in C++.<br>
<br>
(Seems that GNU has extensions for weak symbols on the a.out binary<br>
format. Otherwise, if a binary format has neither weak symbol nor<br>
COMDAT, vague linkage is not representable.)<br>
<br>
>On Fri, Jul 30, 2021 at 9:16 AM Mariusz Sikora via llvm-dev <<br>
><a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br>
><br>
>> Hello,<br>
>><br>
>> I'm trying to understand why LLVM-12 is removing function which is marked<br>
>> inline despite the fact it was not inlined inside caller. Caller function<br>
>> still has a call to inline function and compilation is failing because of a<br>
>> lack of the symbol.<br>
>><br>
>> Looking at debug logs I see:<br>
>><br>
>> Inliner visiting SCC: sort: 1 call sites.<br>
>>       Analyzing call of calculate... (caller:sort)<br>
>>       .<br>
>>       Cost: 960<br>
>>       Threshold: 487<br>
>>     NOT Inlining (cost=960, threshold=487), Call:   call void<br>
>> @calculate(i32* %a, i32* %b)<br>
>><br>
>> Code:<br>
>> int global = 0;<br>
>> void inline calculate(int a[100], int b[100]) {<br>
>>     int i;<br>
>> #pragma unroll<br>
>>     for (i = 0; i < 50; i++) {<br>
>>         a[i] = b[i] + a[i];<br>
>>     }<br>
>> }<br>
>><br>
>> int sort(int a[100], int b[100]) {<br>
>>     calculate(a, b);<br>
>>     return a[20] + b[30] + global;<br>
>> }<br>
>><br>
>> cli: clang -O3 -c inline1.c -o inline1_clang.o<br>
>><br>
>> ll file:<br>
>> ; Function Attrs: nounwind uwtable<br>
>>  define dso_local i32 @sort(i32* %a, i32* %b) local_unnamed_addr #0 {<br>
>> entry:<br>
>>    tail call void @calculate(i32* %a, i32* %b)<br>
>>    %arrayidx = getelementptr inbounds i32, i32* %a, i64 20<br>
>>    %0 = load i32, i32* %arrayidx, align 4, !tbaa !2<br>
>>    %arrayidx1 = getelementptr inbounds i32, i32* %b, i64 30<br>
>>    %1 = load i32, i32* %arrayidx1, align 4, !tbaa !2<br>
>>    %add = add nsw i32 %1, %0<br>
>>    %2 = load i32, i32* @global, align 4, !tbaa !2<br>
>>    %add2 = add nsw i32 %add, %2<br>
>>    ret i32 %add2<br>
>> }<br>
>><br>
>> ; Function Attrs: inlinehint nounwind uwtable<br>
>>  declare dso_local void @calculate(i32*, i32*) local_unnamed_addr #1<br>
>><br>
>> Thanks<br>
>> Mariusz Sikora<br>
>> _______________________________________________<br>
>> LLVM Developers mailing list<br>
>> <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
>> <a href="https://urldefense.com/v3/__https:/lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev__;!!JmoZiZGBv3RvKRSx!paBsrfUr-uf55wvDrS1ZhpJyGUWkUvK3z1VJ0TJpsN40LC2e5h7vMT7ROviIkV2iRA$" target="_blank">
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
>><br>
<br>
>_______________________________________________<br>
>LLVM Developers mailing list<br>
><a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
><a href="https://urldefense.com/v3/__https:/lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev__;!!JmoZiZGBv3RvKRSx!paBsrfUr-uf55wvDrS1ZhpJyGUWkUvK3z1VJ0TJpsN40LC2e5h7vMT7ROviIkV2iRA$" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><u></u><u></u></p>
</blockquote>
</div>
<p class="MsoNormal"><br clear="all">
<u></u><u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<p class="MsoNormal">-- <u></u><u></u></p>
<div>
<p class="MsoNormal">Pozdrawiam<u></u><u></u></p>
<div>
<p class="MsoNormal">Mariusz Sikora<u></u><u></u></p>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>

</blockquote></div></div>