David Blaikie via llvm-dev
2021-Aug-02 19:18 UTC
[llvm-dev] Inline function not eventually inlined is removed
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): https://godbolt.org/z/hPjv1d1db 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. On Mon, Aug 2, 2021 at 10:05 AM Mariusz Sikora <msikora87 at gmail.com> wrote:> 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. > > On Fri, Jul 30, 2021 at 7:16 PM Fangrui Song <maskray at google.com> wrote: > >> On 2021-07-30, David Blaikie via llvm-dev wrote: >> >You're probably looking for some documentation about C inline semantics: >> > >> https://www.iar.com/knowledge/support/technical-notes/compiler/linker-error-undefined-external-for-inline-functions/ >> >> Additional notes: I think the -fgnu89-inline & C99 inline semantics were >> designed explicitly the way so that vague linkage >> (https://itanium-cxx-abi.github.io/cxx-abi/abi/prop-72-comdat.html) can >> be avoided. The C inline behaviors are like always explicit >> instantiation in C++. >> >> (Seems that GNU has extensions for weak symbols on the a.out binary >> format. Otherwise, if a binary format has neither weak symbol nor >> COMDAT, vague linkage is not representable.) >> >> >On Fri, Jul 30, 2021 at 9:16 AM Mariusz Sikora via llvm-dev < >> >llvm-dev at lists.llvm.org> wrote: >> > >> >> Hello, >> >> >> >> I'm trying to understand why LLVM-12 is removing function which is >> marked >> >> inline despite the fact it was not inlined inside caller. Caller >> function >> >> still has a call to inline function and compilation is failing because >> of a >> >> lack of the symbol. >> >> >> >> Looking at debug logs I see: >> >> >> >> Inliner visiting SCC: sort: 1 call sites. >> >> Analyzing call of calculate... (caller:sort) >> >> . >> >> Cost: 960 >> >> Threshold: 487 >> >> NOT Inlining (cost=960, threshold=487), Call: call void >> >> @calculate(i32* %a, i32* %b) >> >> >> >> Code: >> >> int global = 0; >> >> void inline calculate(int a[100], int b[100]) { >> >> int i; >> >> #pragma unroll >> >> for (i = 0; i < 50; i++) { >> >> a[i] = b[i] + a[i]; >> >> } >> >> } >> >> >> >> int sort(int a[100], int b[100]) { >> >> calculate(a, b); >> >> return a[20] + b[30] + global; >> >> } >> >> >> >> cli: clang -O3 -c inline1.c -o inline1_clang.o >> >> >> >> ll file: >> >> ; Function Attrs: nounwind uwtable >> >> define dso_local i32 @sort(i32* %a, i32* %b) local_unnamed_addr #0 { >> >> entry: >> >> tail call void @calculate(i32* %a, i32* %b) >> >> %arrayidx = getelementptr inbounds i32, i32* %a, i64 20 >> >> %0 = load i32, i32* %arrayidx, align 4, !tbaa !2 >> >> %arrayidx1 = getelementptr inbounds i32, i32* %b, i64 30 >> >> %1 = load i32, i32* %arrayidx1, align 4, !tbaa !2 >> >> %add = add nsw i32 %1, %0 >> >> %2 = load i32, i32* @global, align 4, !tbaa !2 >> >> %add2 = add nsw i32 %add, %2 >> >> ret i32 %add2 >> >> } >> >> >> >> ; Function Attrs: inlinehint nounwind uwtable >> >> declare dso_local void @calculate(i32*, i32*) local_unnamed_addr #1 >> >> >> >> Thanks >> >> Mariusz Sikora >> >> _______________________________________________ >> >> LLVM Developers mailing list >> >> llvm-dev at lists.llvm.org >> >> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> >> >> >> >_______________________________________________ >> >LLVM Developers mailing list >> >llvm-dev at lists.llvm.org >> >https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> >> > > -- > Pozdrawiam > Mariusz Sikora >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210802/f664987d/attachment.html>
via llvm-dev
2021-Aug-02 19:38 UTC
[llvm-dev] Inline function not eventually inlined is removed
Clarification: According to the link provided earlier,
https://www.iar.com/knowledge/support/technical-notes/compiler/linker-error-undefined-external-for-inline-functions/<https://urldefense.com/v3/__https:/www.iar.com/knowledge/support/technical-notes/compiler/linker-error-undefined-external-for-inline-functions/__;!!JmoZiZGBv3RvKRSx!paBsrfUr-uf55wvDrS1ZhpJyGUWkUvK3z1VJ0TJpsN40LC2e5h7vMT7ROvhd9mOxyQ$>
you need (exactly one) extern _declaration_ of the inline function, to keep it
from vanishing.
inline int foo() { stuff; }
extern inline int foo(); // not a definition
int bar() { return foo(); }
--paulr
From: llvm-dev <llvm-dev-bounces at lists.llvm.org> On Behalf Of David
Blaikie via llvm-dev
Sent: Monday, August 2, 2021 3:18 PM
To: Mariusz Sikora <msikora87 at gmail.com>
Cc: llvm-dev <llvm-dev at lists.llvm.org>
Subject: Re: [llvm-dev] Inline function not eventually inlined is removed
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):
https://godbolt.org/z/hPjv1d1db<https://urldefense.com/v3/__https:/godbolt.org/z/hPjv1d1db__;!!JmoZiZGBv3RvKRSx!paBsrfUr-uf55wvDrS1ZhpJyGUWkUvK3z1VJ0TJpsN40LC2e5h7vMT7ROvhjMD0L0A$>
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.
On Mon, Aug 2, 2021 at 10:05 AM Mariusz Sikora <msikora87 at
gmail.com<mailto:msikora87 at gmail.com>> wrote:
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.
On Fri, Jul 30, 2021 at 7:16 PM Fangrui Song <maskray at
google.com<mailto:maskray at google.com>> wrote:
On 2021-07-30, David Blaikie via llvm-dev wrote:>You're probably looking for some documentation about C inline semantics:
>https://www.iar.com/knowledge/support/technical-notes/compiler/linker-error-undefined-external-for-inline-functions/<https://urldefense.com/v3/__https:/www.iar.com/knowledge/support/technical-notes/compiler/linker-error-undefined-external-for-inline-functions/__;!!JmoZiZGBv3RvKRSx!paBsrfUr-uf55wvDrS1ZhpJyGUWkUvK3z1VJ0TJpsN40LC2e5h7vMT7ROvhd9mOxyQ$>
Additional notes: I think the -fgnu89-inline & C99 inline semantics were
designed explicitly the way so that vague linkage
(https://itanium-cxx-abi.github.io/cxx-abi/abi/prop-72-comdat.html<https://urldefense.com/v3/__https:/itanium-cxx-abi.github.io/cxx-abi/abi/prop-72-comdat.html__;!!JmoZiZGBv3RvKRSx!paBsrfUr-uf55wvDrS1ZhpJyGUWkUvK3z1VJ0TJpsN40LC2e5h7vMT7ROvga_9S8Zw$>)
can
be avoided. The C inline behaviors are like always explicit
instantiation in C++.
(Seems that GNU has extensions for weak symbols on the a.out binary
format. Otherwise, if a binary format has neither weak symbol nor
COMDAT, vague linkage is not representable.)
>On Fri, Jul 30, 2021 at 9:16 AM Mariusz Sikora via llvm-dev <
>llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>>
wrote:
>
>> Hello,
>>
>> I'm trying to understand why LLVM-12 is removing function which is
marked
>> inline despite the fact it was not inlined inside caller. Caller
function
>> still has a call to inline function and compilation is failing because
of a
>> lack of the symbol.
>>
>> Looking at debug logs I see:
>>
>> Inliner visiting SCC: sort: 1 call sites.
>> Analyzing call of calculate... (caller:sort)
>> .
>> Cost: 960
>> Threshold: 487
>> NOT Inlining (cost=960, threshold=487), Call: call void
>> @calculate(i32* %a, i32* %b)
>>
>> Code:
>> int global = 0;
>> void inline calculate(int a[100], int b[100]) {
>> int i;
>> #pragma unroll
>> for (i = 0; i < 50; i++) {
>> a[i] = b[i] + a[i];
>> }
>> }
>>
>> int sort(int a[100], int b[100]) {
>> calculate(a, b);
>> return a[20] + b[30] + global;
>> }
>>
>> cli: clang -O3 -c inline1.c -o inline1_clang.o
>>
>> ll file:
>> ; Function Attrs: nounwind uwtable
>> define dso_local i32 @sort(i32* %a, i32* %b) local_unnamed_addr #0 {
>> entry:
>> tail call void @calculate(i32* %a, i32* %b)
>> %arrayidx = getelementptr inbounds i32, i32* %a, i64 20
>> %0 = load i32, i32* %arrayidx, align 4, !tbaa !2
>> %arrayidx1 = getelementptr inbounds i32, i32* %b, i64 30
>> %1 = load i32, i32* %arrayidx1, align 4, !tbaa !2
>> %add = add nsw i32 %1, %0
>> %2 = load i32, i32* @global, align 4, !tbaa !2
>> %add2 = add nsw i32 %add, %2
>> ret i32 %add2
>> }
>>
>> ; Function Attrs: inlinehint nounwind uwtable
>> declare dso_local void @calculate(i32*, i32*) local_unnamed_addr #1
>>
>> Thanks
>> Mariusz Sikora
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>
>>
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev<https://urldefense.com/v3/__https:/lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev__;!!JmoZiZGBv3RvKRSx!paBsrfUr-uf55wvDrS1ZhpJyGUWkUvK3z1VJ0TJpsN40LC2e5h7vMT7ROviIkV2iRA$>
>>
>_______________________________________________
>LLVM Developers mailing list
>llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>
>https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev<https://urldefense.com/v3/__https:/lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev__;!!JmoZiZGBv3RvKRSx!paBsrfUr-uf55wvDrS1ZhpJyGUWkUvK3z1VJ0TJpsN40LC2e5h7vMT7ROviIkV2iRA$>
--
Pozdrawiam
Mariusz Sikora
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20210802/43206c12/attachment.html>