Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame] | 1 | // RUN: %clang_cc1 %s -triple %itanium_abi_triple -fms-extensions -emit-llvm -o - | FileCheck %s |
| 2 | |
| 3 | // Test optnone on both function declarations and function definitions. |
| 4 | // Verify also that we don't generate invalid IR functions with |
| 5 | // both alwaysinline and noinline. (optnone implies noinline and wins |
| 6 | // over alwaysinline, in all cases.) |
| 7 | |
| 8 | // Test optnone on extern declaration only. |
| 9 | extern int decl_only(int a) __attribute__((optnone)); |
| 10 | |
| 11 | // This function should be marked 'optnone'. |
| 12 | int decl_only(int a) { |
| 13 | return a + a + a + a; |
| 14 | } |
| 15 | |
| 16 | // CHECK: define {{.*}} @_Z9decl_onlyi({{.*}}) [[OPTNONE:#[0-9]+]] |
| 17 | |
| 18 | // Test optnone on definition but not extern declaration. |
| 19 | extern int def_only(int a); |
| 20 | |
| 21 | __attribute__((optnone)) |
| 22 | int def_only(int a) { |
| 23 | return a + a + a + a; |
| 24 | } |
| 25 | |
| 26 | // Function def_only is a optnone function and therefore it should not be |
| 27 | // inlined inside 'user_of_def_only'. |
| 28 | int user_of_def_only() { |
| 29 | return def_only(5); |
| 30 | } |
| 31 | |
| 32 | // CHECK: define {{.*}} @_Z8def_onlyi({{.*}}) [[OPTNONE]] |
| 33 | // CHECK: define {{.*}} @_Z16user_of_def_onlyv() [[NORMAL:#[0-9]+]] |
| 34 | |
| 35 | // Test optnone on both definition and declaration. |
| 36 | extern int def_and_decl(int a) __attribute__((optnone)); |
| 37 | |
| 38 | __attribute__((optnone)) |
| 39 | int def_and_decl(int a) { |
| 40 | return a + a + a + a; |
| 41 | } |
| 42 | |
| 43 | // CHECK: define {{.*}} @_Z12def_and_decli({{.*}}) [[OPTNONE]] |
| 44 | |
| 45 | // Check that optnone wins over always_inline. |
| 46 | |
| 47 | // Test optnone on definition and always_inline on declaration. |
| 48 | extern int always_inline_function(int a) __attribute__((always_inline)); |
| 49 | |
| 50 | __attribute__((optnone)) |
| 51 | extern int always_inline_function(int a) { |
| 52 | return a + a + a + a; |
| 53 | } |
| 54 | // CHECK: define {{.*}} @_Z22always_inline_functioni({{.*}}) [[OPTNONE]] |
| 55 | |
| 56 | int user_of_always_inline_function() { |
| 57 | return always_inline_function(4); |
| 58 | } |
| 59 | |
| 60 | // CHECK: define {{.*}} @_Z30user_of_always_inline_functionv() [[NORMAL]] |
| 61 | |
| 62 | // Test optnone on declaration and always_inline on definition. |
| 63 | extern int optnone_function(int a) __attribute__((optnone)); |
| 64 | |
| 65 | __attribute__((always_inline)) |
| 66 | int optnone_function(int a) { |
| 67 | return a + a + a + a; |
| 68 | } |
| 69 | // CHECK: define {{.*}} @_Z16optnone_functioni({{.*}}) [[OPTNONE]] |
| 70 | |
| 71 | int user_of_optnone_function() { |
| 72 | return optnone_function(4); |
| 73 | } |
| 74 | |
| 75 | // CHECK: define {{.*}} @_Z24user_of_optnone_functionv() [[NORMAL]] |
| 76 | |
| 77 | // Test the combination of optnone with forceinline (optnone wins). |
| 78 | extern __forceinline int forceinline_optnone_function(int a, int b); |
| 79 | |
| 80 | __attribute__((optnone)) |
| 81 | extern int forceinline_optnone_function(int a, int b) { |
| 82 | return a + b; |
| 83 | } |
| 84 | |
| 85 | int user_of_forceinline_optnone_function() { |
| 86 | return forceinline_optnone_function(4,5); |
| 87 | } |
| 88 | |
| 89 | // CHECK: @_Z36user_of_forceinline_optnone_functionv() [[NORMAL]] |
| 90 | // CHECK: @_Z28forceinline_optnone_functionii({{.*}}) [[OPTNONE]] |
| 91 | |
| 92 | // CHECK: attributes [[OPTNONE]] = { noinline nounwind optnone {{.*}} } |
| 93 | // CHECK: attributes [[NORMAL]] = { nounwind {{.*}} } |
| 94 | |