mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-06 02:45:25 +03:00
Avoid setting always-inline for functions that contain DMD-style inline assembly. (#4631)
As the presence of DMD-style inline assembly in a function causes never-inline to be set for that function.
This commit is contained in:
parent
696a18b70b
commit
48db5d5621
5 changed files with 66 additions and 7 deletions
|
@ -654,7 +654,22 @@ void DtoDeclareFunction(FuncDeclaration *fdecl, const bool willDefine) {
|
|||
irFunc->setNeverInline();
|
||||
} else {
|
||||
if (fdecl->inlining == PINLINE::always) {
|
||||
// If the function contains DMD-style inline assembly.
|
||||
if (fdecl->hasReturnExp & 32) {
|
||||
// The presence of DMD-style inline assembly in a function causes that
|
||||
// function to become never-inline. So, if this function contains DMD-style
|
||||
// inline assembly we'll emit an error as it can't be made always-inline.
|
||||
// However, we'll make an exception for C functions, as the C standard doesn't
|
||||
// actually require that `inline` functions be inlined. So, for C functions we just
|
||||
// ignore the attempt to make it always-inline.
|
||||
if (!fdecl->isCsymbol()) {
|
||||
error(fdecl->loc,
|
||||
"`%s` cannot be `pragma(inline, true)` as it contains DMD-style inline assembly",
|
||||
fdecl->toPrettyChars());
|
||||
}
|
||||
} else {
|
||||
irFunc->setAlwaysInline();
|
||||
}
|
||||
} else if (fdecl->inlining == PINLINE::never) {
|
||||
irFunc->setNeverInline();
|
||||
}
|
||||
|
|
15
tests/codegen/dmd_style_asm_in_inline_c_function.c
Normal file
15
tests/codegen/dmd_style_asm_in_inline_c_function.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
// ImportC treats `inline` C functions as though `pragma(inline, true)` was applied to them.
|
||||
// The presence of DMD-style inline assembly inhibits inlining,
|
||||
// so if `pragma(inline, true)` is also present, an error should occur; but C doesn't
|
||||
// require that an `inline` function is actually inlined, so we permit `inline` C functions
|
||||
// to contain DMD-style inline assembly,
|
||||
|
||||
// REQUIRES: Windows && target_X86
|
||||
// RUN: %ldc -mtriple=i686-pc-windows-msvc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
|
||||
|
||||
// CHECK-NOT: alwaysinline
|
||||
inline unsigned int hasDMDStyleAsm(unsigned int a) {
|
||||
asm {
|
||||
mov EAX, dword ptr [a];
|
||||
}
|
||||
}
|
|
@ -1,14 +1,11 @@
|
|||
module inputs.inlinables_asm;
|
||||
|
||||
import ldc.attributes;
|
||||
import ldc.llvmasm;
|
||||
|
||||
extern (C): // simplify mangling for easier function name matching
|
||||
|
||||
pragma(inline, true) extern (C) void naked_asm_func()
|
||||
pragma(inline, true) extern (C) @naked void naked_asm_func()
|
||||
{
|
||||
asm pure nothrow @nogc
|
||||
{
|
||||
naked;
|
||||
nop;
|
||||
}
|
||||
return __asm("nop", "");
|
||||
}
|
||||
|
|
15
tests/codegen/ldc_style_asm_in_inline_d_function.d
Normal file
15
tests/codegen/ldc_style_asm_in_inline_d_function.d
Normal file
|
@ -0,0 +1,15 @@
|
|||
// The presence of non-DMD-style inline assembly does not inhibit inlining,
|
||||
// so `pragma(inline, true)` should work for functions containing non-DMD-style inline assembly.
|
||||
|
||||
// REQUIRES: target_X86
|
||||
// RUN: %ldc -mtriple=i686-pc-windows-msvc -output-ll -of=%t.ll -c %s && FileCheck %s < %t.ll
|
||||
|
||||
import ldc.llvmasm;
|
||||
|
||||
// CHECK: alwaysinline
|
||||
// CHECK-NEXT: {{define.+hasLDCStyleAsm}}
|
||||
pragma(inline, true)
|
||||
uint hasLDCStyleAsm(uint a)
|
||||
{
|
||||
return __asm!uint("add 7, $0", "=r,0,~{flags}", a);
|
||||
}
|
17
tests/fail_compilation/dmd_style_asm_in_inline_d_function.d
Normal file
17
tests/fail_compilation/dmd_style_asm_in_inline_d_function.d
Normal file
|
@ -0,0 +1,17 @@
|
|||
// The presence of DMD-style inline assembly inhibits inlining,
|
||||
// so if `pragma(inline, true)` is also present, some kind of error should occur.
|
||||
|
||||
// REQUIRES: target_X86
|
||||
// RUN: not %ldc -mtriple=i686-pc-windows-msvc -c %s 2>&1 | FileCheck %s
|
||||
|
||||
module dmd_style_asm_in_inline_d_function;
|
||||
|
||||
// CHECK: `dmd_style_asm_in_inline_d_function.hasDMDStyleAsm` cannot be `pragma(inline, true)` as it contains DMD-style inline assembly
|
||||
pragma(inline, true)
|
||||
uint hasDMDStyleAsm(uint a)
|
||||
{
|
||||
asm
|
||||
{
|
||||
mov EAX, dword ptr [a];
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue