1 // RUN: %clang_cc1 -x c++ -std=c++11 -triple x86_64-unknown-linux -emit-llvm -O2 < %s | FileCheck %s 2 3 #pragma clang optimize off 4 5 // This is a macro definition and therefore its text is not present after 6 // preprocessing. The pragma has no effect here. 7 #define CREATE_FUNC(name) \ 8 int name (int param) { \ 9 return param; \ 10 } \ 11 12 // This is a declaration and therefore it is not decorated with `optnone`. 13 extern int foo(int a, int b); 14 // CHECK-DAG: @_Z3fooii{{.*}} [[ATTRFOO:#[0-9]+]] 15 16 // This is a definition and therefore it will be decorated with `optnone`. 17 int bar(int x, int y) { 18 for(int i = 0; i < x; ++i) 19 y += x; 20 return y + foo(x, y); 21 } 22 // CHECK-DAG: @_Z3barii{{.*}} [[ATTRBAR:#[0-9]+]] 23 24 // The function "int created (int param)" created by the macro invocation 25 // is also decorated with the `optnone` attribute because it is within a 26 // region of code affected by the functionality (not because of the position 27 // of the macro definition). 28 CREATE_FUNC (created) 29 // CHECK-DAG: @_Z7createdi{{.*}} [[ATTRCREATED:#[0-9]+]] 30 31 class MyClass { 32 public: 33 // The declaration of the method is not decorated with `optnone`. 34 int method(int blah); 35 }; 36 37 // The definition of the method instead is decorated with `optnone`. 38 int MyClass::method(int blah) { 39 return blah + 1; 40 } 41 // CHECK-DAG: @_ZN7MyClass6methodEi{{.*}} [[ATTRMETHOD:#[0-9]+]] 42 43 // A template declaration will not be decorated with `optnone`. 44 template <typename T> T twice (T param); 45 46 // The template definition will be decorated with the attribute `optnone`. 47 template <typename T> T thrice (T param) { 48 return 3 * param; 49 } 50 51 // This function definition will not be decorated with `optnone` because the 52 // attribute would conflict with `always_inline`. 53 int __attribute__((always_inline)) baz(int z) { 54 return foo(z, 2); 55 } 56 // CHECK-DAG: @_Z3bazi{{.*}} [[ATTRBAZ:#[0-9]+]] 57 58 #pragma clang optimize on 59 60 // The function "int wombat(int param)" created by the macro is not 61 // decorated with `optnone`, because the pragma applies its effects only 62 // after preprocessing. The position of the macro definition is not 63 // relevant. 64 CREATE_FUNC (wombat) 65 // CHECK-DAG: @_Z6wombati{{.*}} [[ATTRWOMBAT:#[0-9]+]] 66 67 // This instantiation of the "twice" template function with a "float" type 68 // will not have an `optnone` attribute because the template declaration was 69 // not affected by the pragma. 70 float container (float par) { 71 return twice(par); 72 } 73 // CHECK-DAG: @_Z9containerf{{.*}} [[ATTRCONTAINER:#[0-9]+]] 74 // CHECK-DAG: @_Z5twiceIfET_S0_{{.*}} [[ATTRTWICE:#[0-9]+]] 75 76 // This instantiation of the "thrice" template function with a "float" type 77 // will have an `optnone` attribute because the template definition was 78 // affected by the pragma. 79 float container2 (float par) { 80 return thrice(par); 81 } 82 // CHECK-DAG: @_Z10container2f{{.*}} [[ATTRCONTAINER2:#[0-9]+]] 83 // CHECK-DAG: @_Z6thriceIfET_S0_{{.*}} [[ATTRTHRICEFLOAT:#[0-9]+]] 84 85 86 // A template specialization is a new definition and it will not be 87 // decorated with an `optnone` attribute because it is now outside of the 88 // affected region. 89 template<> int thrice(int par) { 90 return (par << 1) + par; 91 } 92 int container3 (int par) { 93 return thrice(par); 94 } 95 // CHECK-DAG: @_Z10container3i{{.*}} [[ATTRCONTAINER3:#[0-9]+]] 96 // CHECK-DAG: @_Z6thriceIiET_S0_{{.*}} [[ATTRTHRICEINT:#[0-9]+]] 97 98 99 // Check for both noinline and optnone on each function that should have them. 100 // CHECK-DAG: attributes [[ATTRBAR]] = { {{.*}}noinline{{.*}}optnone{{.*}} } 101 // CHECK-DAG: attributes [[ATTRCREATED]] = { {{.*}}noinline{{.*}}optnone{{.*}} } 102 // CHECK-DAG: attributes [[ATTRMETHOD]] = { {{.*}}noinline{{.*}}optnone{{.*}} } 103 // CHECK-DAG: attributes [[ATTRTHRICEFLOAT]] = { {{.*}}noinline{{.*}}optnone{{.*}} } 104 105 // Check that the other functions do NOT have optnone. 106 // CHECK-DAG-NOT: attributes [[ATTRFOO]] = { {{.*}}optnone{{.*}} } 107 // CHECK-DAG-NOT: attributes [[ATTRBAZ]] = { {{.*}}optnone{{.*}} } 108 // CHECK-DAG-NOT: attributes [[ATTRWOMBAT]] = { {{.*}}optnone{{.*}} } 109 // CHECK-DAG-NOT: attributes [[ATTRCONTAINER]] = { {{.*}}optnone{{.*}} } 110 // CHECK-DAG-NOT: attributes [[ATTRTWICE]] = { {{.*}}optnone{{.*}} } 111 // CHECK-DAG-NOT: attributes [[ATTRCONTAINER2]] = { {{.*}}optnone{{.*}} } 112 // CHECK-DAG-NOT: attributes [[ATTRCONTAINER3]] = { {{.*}}optnone{{.*}} } 113 // CHECK-DAG-NOT: attributes [[ATTRTHRICEINT]] = { {{.*}}optnone{{.*}} } 114