Bug 63220 - error: inlining failed in call to always_inline
Summary: error: inlining failed in call to always_inline
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 5.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-09-11 00:05 UTC by davidxl
Modified: 2014-09-12 08:47 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
test case (1.30 KB, text/plain)
2014-09-11 00:05 UTC, davidxl
Details

Note You need to log in before you can comment on or make changes to this bug.
Description davidxl 2014-09-11 00:05:20 UTC
Created attachment 33466 [details]
test case

Compile the attached source with -std=gnu++11 -O1 option, the compilation will fail with the error message

 error: inlining failed in call to always_inline ....


There is no problem with O2.
Comment 1 Richard Biener 2014-09-11 09:40:58 UTC
First of all you should mark the functions 'inline' as well.  Then the issue
is that 'eq' is called indirectly which isn't allowed for always_inline
functions:

t.C:81:66: error: inlining failed in call to always_inline 'static constexpr bool std::__1::char_traits<char>::eq(std::__1::char_traits<char>::char_type, std::__1::char_traits<char>::char_type)': indirect function call with a yet undetermined callee
       __attribute__ (( __always_inline__)) static constexpr bool eq(char_type __c1, char_type __c2)  {
                                                                  ^
t.C:75:37: error: called from here
             if (!__pred(*__m1, *__m2)) { } 
                                     ^

which means this is a missed-optimization only.  The error is your fault.

Note that getting the error is unreliable so -O0 simply doesn't discover the
failed inlining.
Comment 2 davidxl 2014-09-11 14:54:03 UTC
(In reply to Richard Biener from comment #1)
> First of all you should mark the functions 'inline' as well.

This does not help.

  Then the issue
> is that 'eq' is called indirectly which isn't allowed for always_inline
> functions:


Is this documented somewhere? A function can be called indirectly and directly. What is the right way to force inlining the direct calls?

A warning is already emitted about always_inline might not be inlinable, why the error?

> 
> t.C:81:66: error: inlining failed in call to always_inline 'static constexpr
> bool std::__1::char_traits<char>::eq(std::__1::char_traits<char>::char_type,
> std::__1::char_traits<char>::char_type)': indirect function call with a yet
> undetermined callee
>        __attribute__ (( __always_inline__)) static constexpr bool
> eq(char_type __c1, char_type __c2)  {
>                                                                   ^
> t.C:75:37: error: called from here
>              if (!__pred(*__m1, *__m2)) { } 
>                                      ^
> 
> which means this is a missed-optimization only.  The error is your fault.
> 
> Note that getting the error is unreliable so -O0 simply doesn't discover the
> failed inlining.

-O2 works fine -- I have not debugged the problem -- but it seems to be some newly cloned cgraph edge to be in inconsistent state.

David
Comment 3 Richard Biener 2014-09-12 08:47:24 UTC
(In reply to davidxl from comment #2)
> (In reply to Richard Biener from comment #1)
> > First of all you should mark the functions 'inline' as well.
> 
> This does not help.
> 
>   Then the issue
> > is that 'eq' is called indirectly which isn't allowed for always_inline
> > functions:
> 
> 
> Is this documented somewhere? A function can be called indirectly and
> directly. What is the right way to force inlining the direct calls?
> 
> A warning is already emitted about always_inline might not be inlinable, why
> the error?

@item always_inline
@cindex @code{always_inline} function attribute
Generally, functions are not inlined unless optimization is specified.
For functions declared inline, this attribute inlines the function
independent of any restrictions that otherwise apply to inlining.
Failure to inline such a function is diagnosed as an error.
Note that if such a function is called indirectly the compiler may
or may not inline it depending on optimization level and a failure
to inline an indirect call may or may not be diagnosed.

always_inline is _not_ an optimization hint!  always_inline was meant
to mark functions that won't work correctly if not inlined.

There is no way to "force" only inlining of direct calls.

> > 
> > t.C:81:66: error: inlining failed in call to always_inline 'static constexpr
> > bool std::__1::char_traits<char>::eq(std::__1::char_traits<char>::char_type,
> > std::__1::char_traits<char>::char_type)': indirect function call with a yet
> > undetermined callee
> >        __attribute__ (( __always_inline__)) static constexpr bool
> > eq(char_type __c1, char_type __c2)  {
> >                                                                   ^
> > t.C:75:37: error: called from here
> >              if (!__pred(*__m1, *__m2)) { } 
> >                                      ^
> > 
> > which means this is a missed-optimization only.  The error is your fault.
> > 
> > Note that getting the error is unreliable so -O0 simply doesn't discover the
> > failed inlining.
> 
> -O2 works fine -- I have not debugged the problem -- but it seems to be some
> newly cloned cgraph edge to be in inconsistent state.
> 
> David