diff options
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/CodeGen/always-inline.c | 2 | ||||
-rw-r--r-- | clang/test/CodeGen/always_inline-unused.c | 31 | ||||
-rw-r--r-- | clang/test/CodeGen/always_inline-wrappers.c | 108 | ||||
-rw-r--r-- | clang/test/CodeGen/always_inline.c | 18 | ||||
-rw-r--r-- | clang/test/CodeGen/function-attributes.c | 5 | ||||
-rw-r--r-- | clang/test/CodeGen/pr9614.c | 10 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/alwaysinline.cpp | 68 | ||||
-rw-r--r-- | clang/test/Frontend/optimization-remark-line-directive.c | 3 | ||||
-rw-r--r-- | clang/test/Frontend/optimization-remark.c | 6 | ||||
-rw-r--r-- | clang/test/Modules/cxx-irgen.cpp | 4 |
10 files changed, 238 insertions, 17 deletions
diff --git a/clang/test/CodeGen/always-inline.c b/clang/test/CodeGen/always-inline.c index c9fd1ae2d80..ed8ecc7bfa7 100644 --- a/clang/test/CodeGen/always-inline.c +++ b/clang/test/CodeGen/always-inline.c @@ -1,7 +1,9 @@ // RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s // RUN: %clang_cc1 -fno-inline -emit-llvm %s -o - | FileCheck %s +// CHECK-LABEL: define void @i_want_bar() // CHECK-NOT: foo +// CHECK: ret void void bar() { } diff --git a/clang/test/CodeGen/always_inline-unused.c b/clang/test/CodeGen/always_inline-unused.c new file mode 100644 index 00000000000..eb733f72c7e --- /dev/null +++ b/clang/test/CodeGen/always_inline-unused.c @@ -0,0 +1,31 @@ +// Test alwaysinline definitions w/o any non-direct-call uses. +// None of the declarations are emitted. Stub are only emitted when the original +// function can not be discarded. + +// RUN: %clang_cc1 -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s + +void __attribute__((__always_inline__)) f1() {} +inline void __attribute__((__always_inline__)) f2() {} +static inline void __attribute__((__always_inline__)) f3() {} +inline void __attribute__((gnu_inline, __always_inline__)) f4() {} +static inline void __attribute__((gnu_inline, __always_inline__)) f5() {} +inline void __attribute__((visibility("hidden"), __always_inline__)) f6() {} +inline void __attribute__((visibility("hidden"), gnu_inline, __always_inline__)) f7() {} + +void g() { + f1(); + f2(); + f3(); + f4(); + f5(); + f6(); + f7(); +} + +// CHECK: define void @f1() +// CHECK-NOT: void @f2() +// CHECK-NOT: void @f3() +// CHECK: define void @f4() +// CHECK-NOT: void @f5() +// CHECK-NOT: void @f6() +// CHECK: define hidden void @f7() diff --git a/clang/test/CodeGen/always_inline-wrappers.c b/clang/test/CodeGen/always_inline-wrappers.c new file mode 100644 index 00000000000..ba0b148a7c5 --- /dev/null +++ b/clang/test/CodeGen/always_inline-wrappers.c @@ -0,0 +1,108 @@ +// Test different kinds of alwaysinline definitions. + +// RUN: %clang_cc1 -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-INLINE +// RUN: %clang_cc1 -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-USE +// RUN: %clang_cc1 -disable-llvm-optzns -fno-inline -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK +// RUN: %clang_cc1 -disable-llvm-optzns -fno-inline -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-USE + +void __attribute__((__always_inline__)) f1() {} +inline void __attribute__((__always_inline__)) f2() {} +static inline void __attribute__((__always_inline__)) f3() {} +inline void __attribute__((gnu_inline, __always_inline__)) f4() {} +static inline void __attribute__((gnu_inline, __always_inline__)) f5() {} +inline void __attribute__((visibility("hidden"), __always_inline__)) f6() {} +inline void __attribute__((visibility("hidden"), gnu_inline, __always_inline__)) f7() {} + +void g() { + f1(); + f2(); + f3(); + f4(); + f5(); + f6(); + f7(); +} + +void (*p)(void); +void h() { + p = f1; + p = f2; + p = f3; + p = f4; + p = f5; + p = f6; + p = f7; +} + +void (*const cp1)(void) = f1; +void (*p1)(void) = f1; +void (*p2)(int) = (void (*)(int))f1; + +void __attribute__((__always_inline__)) f8(void(*f)(void)) {} + +void call() { + f8(f1); +} + +// CHECK-DAG: define internal void @f1.alwaysinline() #[[AI:[0-9]+]] +// CHECK-DAG: define internal void @f2.alwaysinline() #[[AI_IH:[0-9]+]] +// CHECK-DAG: define internal void @f3.alwaysinline() #[[AI_IH]] +// CHECK-DAG: define internal void @f4.alwaysinline() #[[AI_IH]] +// CHECK-DAG: define internal void @f5.alwaysinline() #[[AI_IH]] +// CHECK-DAG: define internal void @f6.alwaysinline() #[[AI_IH]] +// CHECK-DAG: define internal void @f7.alwaysinline() #[[AI_IH]] + + +// CHECK-DAG: define void @f1() #[[NOAI:[01-9]+]] +// CHECK-DAG: musttail call void @f1.alwaysinline() + +// CHECK-DAG: declare void @f2() #[[NOAI:[01-9]+]] + +// CHECK-DAG: define internal void @f3() #[[NOAI:[01-9]+]] +// CHECK-DAG: musttail call void @f3.alwaysinline() + +// CHECK-DAG: define void @f4() #[[NOAI:[01-9]+]] +// CHECK-DAG: musttail call void @f4.alwaysinline() + +// CHECK-DAG: define internal void @f5() #[[NOAI:[01-9]+]] +// CHECK-DAG: musttail call void @f5.alwaysinline() + +// CHECK-DAG: declare hidden void @f6() #[[NOAI:[01-9]+]] + +// CHECK-DAG: define hidden void @f7() #[[NOAI:[01-9]+]] +// CHECK-DAG: musttail call void @f7.alwaysinline() + + +// CHECK-DAG: @cp1 = constant void ()* @f1, align +// CHECK-DAG: @p1 = global void ()* @f1, align +// CHECK-DAG: @p2 = global void (i32)* bitcast (void ()* @f1 to void (i32)*), align + +// CHECK: attributes #[[AI]] = {{.*alwaysinline.*}} +// CHECK-INLINE: attributes #[[AI_IH]] = {{.*alwaysinline.*inlinehint.*}} +// CHECK-NOT: attributes #[[NOAI]] = {{.*alwaysinline.*}} + +// CHECK-USE-LABEL: define void @g() +// CHECK-USE-NOT: ret void +// CHECK-USE: call void @f1.alwaysinline() +// CHECK-USE-NEXT: call void @f2.alwaysinline() +// CHECK-USE-NEXT: call void @f3.alwaysinline() +// CHECK-USE-NEXT: call void @f4.alwaysinline() +// CHECK-USE-NEXT: call void @f5.alwaysinline() +// CHECK-USE-NEXT: call void @f6.alwaysinline() +// CHECK-USE-NEXT: call void @f7.alwaysinline() +// CHECK-USE-NEXT: ret void + +// CHECK-USE-LABEL: define void @h() +// CHECK-USE-NOT: ret void +// CHECK-USE: store void ()* @f1, +// CHECK-USE-NEXT: store void ()* @f2, +// CHECK-USE-NEXT: store void ()* @f3, +// CHECK-USE-NEXT: store void ()* @f4, +// CHECK-USE-NEXT: store void ()* @f5, +// CHECK-USE-NEXT: store void ()* @f6, +// CHECK-USE-NEXT: store void ()* @f7, +// CHECK-USE-NEXT: ret void + +// CHECK-USE-LABEL: define void @call() +// CHECK-USE: call void @f8.alwaysinline(void ()* @f1) +// CHECK-USE: ret void diff --git a/clang/test/CodeGen/always_inline.c b/clang/test/CodeGen/always_inline.c index c91fd43f276..00b4234dc71 100644 --- a/clang/test/CodeGen/always_inline.c +++ b/clang/test/CodeGen/always_inline.c @@ -1,8 +1,5 @@ -// RUN: %clang -emit-llvm -S -o %t %s -// RUN: not grep '@f0' %t -// RUN: not grep 'call ' %t -// RUN: %clang -mllvm -disable-llvm-optzns -emit-llvm -S -o %t %s -// RUN: grep '@f0' %t | count 2 +// RUN: %clang -target x86_64-pc-linux-gnu -emit-llvm -S -o - %s | FileCheck %s +// RUN: %clang -target x86_64-pc-linux-gnu -mllvm -disable-llvm-optzns -emit-llvm -S -o - %s | FileCheck %s --check-prefix=CHECK-NO-OPTZNS //static int f0() { static int __attribute__((always_inline)) f0() { @@ -18,3 +15,14 @@ inline int f2() __attribute__((always_inline)); int f2() { return 7; } int f3(void) { return f2(); } +// CHECK-LABEL: define i32 @f1() +// CHECK: ret i32 1 +// CHECK-LABEL: define i32 @f2() +// CHECK: ret i32 7 +// CHECK-LABEL: define i32 @f3() +// CHECK: ret i32 7 + +// CHECK-NO-OPTZNS: define i32 @f3() +// CHECK-NO-OPTZNS-NOT: ret i32 +// CHECK-NO-OPTZNS: call i32 @f2.alwaysinline() +// CHECK-NO-OPTZNS-NEXT: ret i32 diff --git a/clang/test/CodeGen/function-attributes.c b/clang/test/CodeGen/function-attributes.c index 177ad848f74..4a7d4fc0edb 100644 --- a/clang/test/CodeGen/function-attributes.c +++ b/clang/test/CodeGen/function-attributes.c @@ -25,8 +25,8 @@ void f6(signed short x) { } void f7(unsigned short x) { } -// CHECK-LABEL: define void @f8() -// CHECK: [[AI:#[0-9]+]] +// CHECK: define void @f8() +// CHECK: [[NUW:#[0-9]+]] // CHECK: { void __attribute__((always_inline)) f8(void) { } @@ -129,7 +129,6 @@ void f20(void) { } // CHECK: attributes [[NUW]] = { nounwind optsize readnone{{.*}} } -// CHECK: attributes [[AI]] = { alwaysinline nounwind optsize readnone{{.*}} } // CHECK: attributes [[ALIGN]] = { nounwind optsize readnone alignstack=16{{.*}} } // CHECK: attributes [[RT]] = { nounwind optsize returns_twice{{.*}} } // CHECK: attributes [[NR]] = { noreturn nounwind optsize } diff --git a/clang/test/CodeGen/pr9614.c b/clang/test/CodeGen/pr9614.c index 63cb5af1868..d264ef3a9ee 100644 --- a/clang/test/CodeGen/pr9614.c +++ b/clang/test/CodeGen/pr9614.c @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK0 +// RUN: %clang_cc1 -triple x86_64-pc-linux -O1 -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK1 extern void foo_alias (void) __asm ("foo"); inline void foo (void) { @@ -24,7 +25,7 @@ extern inline __attribute__((__always_inline__, __gnu_inline__)) void *memchr(vo void f(void) { foo(); - abs(0); + int x = abs(0); strrchr_foo("", '.'); prefetch(); memchr("", '.', 0); @@ -32,9 +33,10 @@ void f(void) { // CHECK-LABEL: define void @f() // CHECK: call void @foo() -// CHECK: call i32 @abs(i32 0) +// CHECK: call i32 @abs( // CHECK: call i8* @strrchr( -// CHECK: call void @llvm.prefetch( +// CHECK0: call void @llvm.prefetch( +// CHECK1: call void @prefetch.alwaysinline( // CHECK: call i8* @memchr( // CHECK: ret void diff --git a/clang/test/CodeGenCXX/alwaysinline.cpp b/clang/test/CodeGenCXX/alwaysinline.cpp new file mode 100644 index 00000000000..c694ae41d22 --- /dev/null +++ b/clang/test/CodeGenCXX/alwaysinline.cpp @@ -0,0 +1,68 @@ +// Test different kinds of alwaysinline *structor definitions. + +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-CALL + +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -mconstructor-aliases -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -mconstructor-aliases -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-CALL + +struct A1 { + __attribute__((__always_inline__)) A1() {} + __attribute__((__always_inline__)) ~A1() {} +}; + +void g1() { + A1 a1; +} + +struct A2 { + inline __attribute__((__always_inline__)) A2() {} + inline __attribute__((__always_inline__)) ~A2() {} +}; + +void g2() { + A2 a2; +} + +struct A3 { + inline __attribute__((gnu_inline, __always_inline__)) A3() {} + inline __attribute__((gnu_inline, __always_inline__)) ~A3() {} +}; + +void g3() { + A3 a3; +} + +// CHECK-DAG: define internal void @_ZN2A1C1Ev.alwaysinline(%struct.A1* %this) unnamed_addr #[[AI:[01-9]+]] +// CHECK-DAG: define internal void @_ZN2A1C2Ev.alwaysinline(%struct.A1* %this) unnamed_addr #[[AI]] +// CHECK-DAG: define internal void @_ZN2A1D1Ev.alwaysinline(%struct.A1* %this) unnamed_addr #[[AI]] +// CHECK-DAG: define internal void @_ZN2A1D2Ev.alwaysinline(%struct.A1* %this) unnamed_addr #[[AI]] + +// CHECK-DAG: define internal void @_ZN2A2C1Ev.alwaysinline(%struct.A2* %this) unnamed_addr #[[AIIH:[01-9]+]] +// CHECK-DAG: define internal void @_ZN2A2C2Ev.alwaysinline(%struct.A2* %this) unnamed_addr #[[AIIH]] +// CHECK-DAG: define internal void @_ZN2A2D1Ev.alwaysinline(%struct.A2* %this) unnamed_addr #[[AIIH]] +// CHECK-DAG: define internal void @_ZN2A2D2Ev.alwaysinline(%struct.A2* %this) unnamed_addr #[[AIIH]] + +// CHECK-DAG: define internal void @_ZN2A3C1Ev.alwaysinline(%struct.A3* %this) unnamed_addr #[[AIIH]] +// CHECK-DAG: define internal void @_ZN2A3C2Ev.alwaysinline(%struct.A3* %this) unnamed_addr #[[AIIH]] +// CHECK-DAG: define internal void @_ZN2A3D1Ev.alwaysinline(%struct.A3* %this) unnamed_addr #[[AIIH]] +// CHECK-DAG: define internal void @_ZN2A3D2Ev.alwaysinline(%struct.A3* %this) unnamed_addr #[[AIIH]] + +// CHECK-DAG: attributes #[[AI]] = {{.*alwaysinline.*}} +// CHECK-DAG: attributes #[[AIIH]] = {{.*alwaysinline.*inlinehint.*}} +// CHECK-NOT: attributes #[[NOAI]] = {{.*alwaysinline.*}} + +// CHECK-CALL-LABEL: define void @_Z2g1v() +// CHECK-CALL: call void @_ZN2A1C1Ev.alwaysinline +// CHECK-CALL: call void @_ZN2A1D1Ev.alwaysinline +// CHECK-CALL: ret void + +// CHECK-CALL-LABEL: define void @_Z2g2v() +// CHECK-CALL: call void @_ZN2A2C1Ev.alwaysinline +// CHECK-CALL: call void @_ZN2A2D1Ev.alwaysinline +// CHECK-CALL: ret void + +// CHECK-CALL-LABEL: define void @_Z2g3v() +// CHECK-CALL: call void @_ZN2A3C1Ev.alwaysinline +// CHECK-CALL: call void @_ZN2A3D1Ev.alwaysinline +// CHECK-CALL: ret void diff --git a/clang/test/Frontend/optimization-remark-line-directive.c b/clang/test/Frontend/optimization-remark-line-directive.c index f4c0011fb4f..23d63c9aa1e 100644 --- a/clang/test/Frontend/optimization-remark-line-directive.c +++ b/clang/test/Frontend/optimization-remark-line-directive.c @@ -5,8 +5,9 @@ // RUN: %clang_cc1 %s -Rpass=inline -gline-tables-only -dwarf-column-info -emit-llvm-only -verify int foo(int x, int y) __attribute__((always_inline)); +// expected-remark@+1 {{foo.alwaysinline inlined into foo}} int foo(int x, int y) { return x + y; } -// expected-remark@+2 {{foo inlined into bar}} expected-note@+2 {{could not determine the original source location for /bad/path/to/original.c:1230:25}} +// expected-remark@+2 {{foo.alwaysinline inlined into bar}} expected-note@+2 {{could not determine the original source location for /bad/path/to/original.c:1230:25}} #line 1230 "/bad/path/to/original.c" int bar(int j) { return foo(j, j - 2); } diff --git a/clang/test/Frontend/optimization-remark.c b/clang/test/Frontend/optimization-remark.c index 6ada0030a70..604fec00204 100644 --- a/clang/test/Frontend/optimization-remark.c +++ b/clang/test/Frontend/optimization-remark.c @@ -32,6 +32,8 @@ // CHECK-NOT: !llvm.dbg.cu = !{ int foo(int x, int y) __attribute__((always_inline)); +// expected-remark@+2 {{foo.alwaysinline should always be inlined}} +// expected-remark@+1 {{foo.alwaysinline inlined into foo}} int foo(int x, int y) { return x + y; } float foz(int x, int y) __attribute__((noinline)); @@ -45,7 +47,7 @@ int bar(int j) { // expected-remark@+5 {{foz will not be inlined into bar}} // expected-remark@+4 {{foz should never be inlined}} // expected-remark@+3 {{foz will not be inlined into bar}} -// expected-remark@+2 {{foo should always be inlined}} -// expected-remark@+1 {{foo inlined into bar}} +// expected-remark@+2 {{foo.alwaysinline should always be inlined}} +// expected-remark@+1 {{foo.alwaysinline inlined into bar}} return foo(j, j - 2) * foz(j - 2, j); } diff --git a/clang/test/Modules/cxx-irgen.cpp b/clang/test/Modules/cxx-irgen.cpp index 7cdb0d6eb59..73d17467892 100644 --- a/clang/test/Modules/cxx-irgen.cpp +++ b/clang/test/Modules/cxx-irgen.cpp @@ -26,14 +26,14 @@ namespace EmitInlineMethods { }; } -// CHECK-DAG: define available_externally hidden {{.*}}{{signext i32|i32}} @_ZN1SIiE1gEv({{.*}} #[[ALWAYS_INLINE:.*]] align +// CHECK-DAG: define internal i32 @_ZN1SIiE1gEv.alwaysinline() #[[ALWAYS_INLINE:.*]] align int a = S<int>::g(); int b = h(); // CHECK-DAG: define linkonce_odr {{.*}}{{signext i32|i32}} @_Z3minIiET_S0_S0_(i32 int c = min(1, 2); -// CHECK: define available_externally {{.*}}{{signext i32|i32}} @_ZN1SIiE1fEv({{.*}} #[[ALWAYS_INLINE]] align +// CHECK-DAG: define internal {{.*}}{{signext i32|i32}} @_ZN1SIiE1fEv.alwaysinline() #[[ALWAYS_INLINE]] align namespace ImplicitSpecialMembers { // CHECK-LABEL: define {{.*}} @_ZN22ImplicitSpecialMembers1BC2ERKS0_( |