Bug creation and email sending has been disabled, file new bugs at gcc.gnu.org/bugzilla
Bug 140 - Inlining certain trivial function fails
Summary: Inlining certain trivial function fails
Status: NEW
Alias: None
Product: GDC
Classification: Unclassified
Component: gdc (show other bugs)
Version: 4.9.x
Hardware: All All
: --- normal
Assignee: Iain Buclaw
URL:
Depends on:
Blocks:
 
Reported: 2014-07-12 16:39 CEST by art.08.09
Modified: 2014-07-21 10:56 CEST (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description art.08.09 2014-07-12 16:39:54 CEST
GDC fails to inline some trivial functions (like array.empty) in certain cases.
The simplest testcase (that i can think of) that still exhibits the problem:

   import std.array, std.algorithm;
   immutable a = [1];
   int main() {
      return a.filter!"true"().empty;
   }

This gets compiled to:

<_Dmain>:
   sub    $0x18,%rsp
   mov    $0x1,%edi
   mov    $0x65d968,%esi
   callq  <pure nothrow @property @safe bool std.array.empty!(int).empty(const(int[]))>
   add    $0x18,%rsp
   movzbl %al,%eax
   retq   


Originally reported on ML @ http://forum.dlang.org/post/mailman.75.1396605155.19942.d.gnu@puremagic.com ;
some more info in that thread.

Could be related to http://bugzilla.gdcproject.org/show_bug.cgi?id=120 ,
which I thought was the same bug, but it turns out that the testcase in #120 does *not* fail here.
Comment 1 Johannes Pfau 2014-07-12 19:21:09 CEST
Try to add @attribute("forceinline") to the failing function (you might have to copy std.algorith to some other file, name it xtd.algorithm or something), then compiling should fail with some error message and you can use dustmite to reduce the test case.
Comment 2 art.08.09 2014-07-12 20:50:40 CEST
(In reply to Johannes Pfau from comment #1)
> Try to add @attribute("forceinline") to the failing function (you might have
> to copy std.algorith to some other file, name it xtd.algorithm or
> something), then compiling should fail with some error message and you can
> use dustmite to reduce the test case.

Well, that results in basically the same testcase and a stripped-down std.array with just the necessary primitives.

But after adding the always_inline attribute I at least got a little more informative diagnostic:

std/algorithm.d: In member function 'pure nothrow @property @safe bool xstd.algorithm.__T12FilterResultS633std10functional36__T8unaryFunVAyaa8_612e6c656e677468Z8unaryFunTAAyaZ.FilterResult.empty()':
std/array.d:408: error: inlining failed in call to always_inline 'pure nothrow @property @safe bool xstd.array.empty!(immutable(char)[]).empty(const(immutable(char)[][]))': mismatched arguments
std/algorithm.d:1449: error: called from here


If I call std.array.empty /directly/ then there is no problem and `empty` is properly inlined. The problem appears only when calling it via eg std.algorithm.FilterResult.empty...
Comment 3 Johannes Pfau 2014-07-13 00:06:05 CEST
Reduced:

test.d
----------------------------------------------------
import xtd.array;

int main()
{
    void[] a = [];
    return (FilterResult!(void[])(a)).empty;
}

struct FilterResult(Range)
{
    Range _input;

    @property empty() { return xtd.array.empty(_input); }
}
----------------------------------------------------

xtd/array.d
----------------------------------------------------
import gcc.attribute;

@attribute("forceinline") @property empty(T)(in T[] a)
{
    return !a.length;
}
----------------------------------------------------

gdc test.d -finline
----------------------------------------------------
test.d: In member function 'empty':
xtd/array.d:3: error: inlining failed in call to always_inline 'empty': mismatched arguments
test.d:14: error: called from here
----------------------------------------------------


Merging array.d/test.d leads to a different error:
test.d
----------------------------------------------------
import gcc.attribute;

@attribute("forceinline") @property empty2(T)(in T[] a)
{
    return !a.length;
}


int main()
{
    void[] a = [];
    return (FilterResult!(void[])(a)).empty;
}

struct FilterResult(Range)
{
    Range _input;

    @property empty() { return empty2(_input); }
}
----------------------------------------------------

gdc test.d -finline
----------------------------------------------------
cc1d: /build/gdc/src/gcc-4.9.0/gcc/d/dfrontend/interpret.c:676: void FuncDeclaration::ctfeCompile(): Assertion `semanticRun == PASSsemantic3done' failed.
test.d: In member function 'empty':
test.d:18: internal compiler error: Aborted
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://bugs.archlinux.org/> for instructions.
----------------------------------------------------

This error vanishes if the forceinline attribute is removed.
Comment 4 Iain Buclaw 2014-07-21 10:56:39 CEST
The ICE has been fixed in:
https://github.com/D-Programming-GDC/GDC/commit/db6e514f7a5fef192bd70dc2ed4aa80a7eeac1fe