blob: ee7fa86a85dd7639643812afbff22bbfeb92f77f [file] [edit]
// RUN: %clang_cc1 -O1 -disable-llvm-passes -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
template <typename T>
[[clang::noinline]] void foo(T) {}
// Explicit specializations should not inherit noinline
template <>
[[clang::always_inline]] void foo<int>(int) {}
template <>
void foo<long>(long) {}
void caller() {
foo<float>(4.2f); // expect noinline on function
foo<int>(42); // expect alwaysinline on function
foo<long>(42L); // expect no noinline attribute
}
// CHECK: define {{.*}}void @_Z3fooIiEvT_({{.*}}) #[[ALWAYSINLINE:[0-9]+]]
// CHECK: define {{.*}}void @_Z3fooIlEvT_({{.*}}) #[[BARE:[0-9]+]]
// CHECK: define {{.*}}void @_Z3fooIfEvT_({{.*}}) #[[NOINLINE:[0-9]+]]
// Inner function should not clobber non-conflicting attributes
void inner_fn();
void outer_fn() {
[[clang::noinline]]
{
[[clang::nomerge]] // unrelated to inlining
inner_fn();
}
}
// CHECK: call void @_Z8inner_fnv() #[[NOINLINE_NOMERGE:[0-9]+]]
void inner_fn2();
void outer_fn2() {
[[clang::nomerge]]
{
[[clang::noinline]] // unrelated to nomerge
inner_fn2();
}
}
// CHECK: call void @_Z9inner_fn2v() #[[NOINLINE_NOMERGE]]
[[clang::convergent]]
void inner_fn3();
void outer_fn3() {
[[clang::always_inline]]
{
[[clang::noconvergent]] // unrelated to inlining
inner_fn3();
}
}
// CHECK: call void @_Z9inner_fn3v() #[[ALWAYSINLINE_ONLY:[0-9]+]]
[[clang::convergent]]
void inner_fn4();
void outer_fn4() {
[[clang::noconvergent]]
{
[[clang::always_inline]] // unrelated to noconvergent
inner_fn4();
}
}
// CHECK: call void @_Z9inner_fn4v() #[[ALWAYSINLINE_ONLY]]
// Inner function should clobber a conflicting attribute
void inner_fn5();
void outer_fn5() {
[[clang::noinline]]
{
[[clang::always_inline]]
inner_fn5();
}
}
// CHECK: call void @_Z9inner_fn5v() #[[ALWAYSINLINE_ONLY]]
// CHECK: attributes #[[ALWAYSINLINE]] = {
// CHECK-SAME: alwaysinline
// CHECK-NOT: noinline
// CHECK: attributes #[[BARE]] = {
// CHECK-NOT: alwaysinline
// CHECK-NOT: noinline
// CHECK: attributes #[[NOINLINE]] = {
// CHECK-SAME: noinline
// CHECK-NOT: alwaysinline
// CHECK: attributes #[[NOINLINE_NOMERGE]] = { noinline nomerge }
// CHECK: attributes #[[ALWAYSINLINE_ONLY]] = { alwaysinline }