1 // RUN: %clang_cc1 %s -triple %itanium_abi_triple -fms-extensions -O2 -disable-llvm-passes -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'. decl_only(int a)12int 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)) def_only(int a)22int 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'. user_of_def_only()28int 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)) def_and_decl(int a)39int 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)) always_inline_function(int a)51extern int always_inline_function(int a) { 52 return a + a + a + a; 53 } 54 // CHECK: define {{.*}} @_Z22always_inline_functioni({{.*}}) [[OPTNONE]] 55 user_of_always_inline_function()56int 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)) optnone_function(int a)66int optnone_function(int a) { 67 return a + a + a + a; 68 } 69 // CHECK: define {{.*}} @_Z16optnone_functioni({{.*}}) [[OPTNONE]] 70 user_of_optnone_function()71int 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)) forceinline_optnone_function(int a,int b)81extern int forceinline_optnone_function(int a, int b) { 82 return a + b; 83 } 84 user_of_forceinline_optnone_function()85int 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]] = 94 // CHECK-NOT: noinline 95 // CHECK-NOT: optnone 96