1 // RUN: %clang_cc1 -I %S/Inputs -x c++ -std=c++11 -triple x86_64-unknown-linux -emit-llvm -O2 < %s | FileCheck %s 2 // RUN: %clang_cc1 -I %S/Inputs -x c++ -std=c++11 -triple x86_64-unknown-linux -emit-llvm -Os < %s | FileCheck %s 3 // RUN: %clang_cc1 -I %S/Inputs -x c++ -std=c++11 -triple x86_64-unknown-linux -emit-llvm -Oz < %s | FileCheck %s 4 5 #pragma clang optimize off 6 7 // This is a macro definition and therefore its text is not present after 8 // preprocessing. The pragma has no effect here. 9 #define CREATE_FUNC(name) \ 10 int name (int param) { \ 11 return param; \ 12 } \ 13 14 // This is a declaration and therefore it is not decorated with `optnone`. 15 extern int foo(int a, int b); 16 // CHECK-DAG: @_Z3fooii{{.*}} [[ATTRFOO:#[0-9]+]] 17 18 // This is a definition and therefore it will be decorated with `optnone`. 19 int bar(int x, int y) { 20 for(int i = 0; i < x; ++i) 21 y += x; 22 return y + foo(x, y); 23 } 24 // CHECK-DAG: @_Z3barii{{.*}} [[ATTRBAR:#[0-9]+]] 25 26 // The function "int created (int param)" created by the macro invocation 27 // is also decorated with the `optnone` attribute because it is within a 28 // region of code affected by the functionality (not because of the position 29 // of the macro definition). 30 CREATE_FUNC (created) 31 // CHECK-DAG: @_Z7createdi{{.*}} [[ATTRCREATED:#[0-9]+]] 32 33 class MyClass { 34 public: 35 // The declaration of the method is not decorated with `optnone`. 36 int method(int blah); 37 }; 38 39 // The definition of the method instead is decorated with `optnone`. 40 int MyClass::method(int blah) { 41 return blah + 1; 42 } 43 // CHECK-DAG: @_ZN7MyClass6methodEi{{.*}} [[ATTRMETHOD:#[0-9]+]] 44 45 // A template declaration will not be decorated with `optnone`. 46 template <typename T> T twice (T param); 47 48 // The template definition will be decorated with the attribute `optnone`. 49 template <typename T> T thrice (T param) { 50 return 3 * param; 51 } 52 53 // This function definition will not be decorated with `optnone` because the 54 // attribute would conflict with `always_inline`. 55 int __attribute__((always_inline)) baz(int z) { 56 return foo(z, 2); 57 } 58 // CHECK-DAG: @_Z3bazi{{.*}} [[ATTRBAZ:#[0-9]+]] 59 60 // This function definition will not be decorated with `optnone` because the 61 // attribute would conflict with `minsize`. 62 int __attribute__((minsize)) bax(int z) { 63 return foo(z, 2); 64 } 65 // CHECK-DAG: @_Z3baxi{{.*}} [[ATTRBAX:#[0-9]+]] 66 67 #pragma clang optimize on 68 69 // The function "int wombat(int param)" created by the macro is not 70 // decorated with `optnone`, because the pragma applies its effects only 71 // after preprocessing. The position of the macro definition is not 72 // relevant. 73 CREATE_FUNC (wombat) 74 // CHECK-DAG: @_Z6wombati{{.*}} [[ATTRWOMBAT:#[0-9]+]] 75 76 // This instantiation of the "twice" template function with a "float" type 77 // will not have an `optnone` attribute because the template declaration was 78 // not affected by the pragma. 79 float container (float par) { 80 return twice(par); 81 } 82 // CHECK-DAG: @_Z9containerf{{.*}} [[ATTRCONTAINER:#[0-9]+]] 83 // CHECK-DAG: @_Z5twiceIfET_S0_{{.*}} [[ATTRTWICE:#[0-9]+]] 84 85 // This instantiation of the "thrice" template function with a "float" type 86 // will have an `optnone` attribute because the template definition was 87 // affected by the pragma. 88 float container2 (float par) { 89 return thrice(par); 90 } 91 // CHECK-DAG: @_Z10container2f{{.*}} [[ATTRCONTAINER2:#[0-9]+]] 92 // CHECK-DAG: @_Z6thriceIfET_S0_{{.*}} [[ATTRTHRICEFLOAT:#[0-9]+]] 93 94 95 // A template specialization is a new definition and it will not be 96 // decorated with an `optnone` attribute because it is now outside of the 97 // affected region. 98 template<> int thrice(int par) { 99 return (par << 1) + par; 100 } 101 int container3 (int par) { 102 return thrice(par); 103 } 104 // CHECK-DAG: @_Z10container3i{{.*}} [[ATTRCONTAINER3:#[0-9]+]] 105 // CHECK-DAG: @_Z6thriceIiET_S0_{{.*}} [[ATTRTHRICEINT:#[0-9]+]] 106 107 108 // Test that we can re-open and re-close an "off" region after the first one, 109 // and that this works as expected. 110 111 #pragma clang optimize off 112 113 int another_optnone(int x) { 114 return x << 1; 115 } 116 // CHECK-DAG: @_Z15another_optnonei{{.*}} [[ATTRANOTHEROPTNONE:#[0-9]+]] 117 118 #pragma clang optimize on 119 120 int another_normal(int x) { 121 return x << 2; 122 } 123 // CHECK-DAG: @_Z14another_normali{{.*}} [[ATTRANOTHERNORMAL:#[0-9]+]] 124 125 126 // Test that we can re-open an "off" region by including a header with the 127 // pragma and that this works as expected (i.e. the off region "falls through" 128 // the end of the header into this file). 129 130 #include <header-with-pragma-optimize-off.h> 131 132 int yet_another_optnone(int x) { 133 return x << 3; 134 } 135 // CHECK-DAG: @_Z19yet_another_optnonei{{.*}} [[ATTRYETANOTHEROPTNONE:#[0-9]+]] 136 137 #pragma clang optimize on 138 139 int yet_another_normal(int x) { 140 return x << 4; 141 } 142 // CHECK-DAG: @_Z18yet_another_normali{{.*}} [[ATTRYETANOTHERNORMAL:#[0-9]+]] 143 144 145 // Check for both noinline and optnone on each function that should have them. 146 // CHECK-DAG: attributes [[ATTRBAR]] = { {{.*}}noinline{{.*}}optnone{{.*}} } 147 // CHECK-DAG: attributes [[ATTRCREATED]] = { {{.*}}noinline{{.*}}optnone{{.*}} } 148 // CHECK-DAG: attributes [[ATTRMETHOD]] = { {{.*}}noinline{{.*}}optnone{{.*}} } 149 // CHECK-DAG: attributes [[ATTRTHRICEFLOAT]] = { {{.*}}noinline{{.*}}optnone{{.*}} } 150 // CHECK-DAG: attributes [[ATTRANOTHEROPTNONE]] = { {{.*}}noinline{{.*}}optnone{{.*}} } 151 // CHECK-DAG: attributes [[ATTRYETANOTHEROPTNONE]] = { {{.*}}noinline{{.*}}optnone{{.*}} } 152 153 // Check that the other functions do NOT have optnone. 154 // CHECK-NOT: attributes [[ATTRFOO]] = { {{.*}}optnone{{.*}} } 155 // CHECK-NOT: attributes [[ATTRBAZ]] = { {{.*}}optnone{{.*}} } 156 // CHECK-NOT: attributes [[ATTRBAX]] = { {{.*}}optnone{{.*}} } 157 // CHECK-NOT: attributes [[ATTRWOMBAT]] = { {{.*}}optnone{{.*}} } 158 // CHECK-NOT: attributes [[ATTRCONTAINER]] = { {{.*}}optnone{{.*}} } 159 // CHECK-NOT: attributes [[ATTRTWICE]] = { {{.*}}optnone{{.*}} } 160 // CHECK-NOT: attributes [[ATTRCONTAINER2]] = { {{.*}}optnone{{.*}} } 161 // CHECK-NOT: attributes [[ATTRCONTAINER3]] = { {{.*}}optnone{{.*}} } 162 // CHECK-NOT: attributes [[ATTRTHRICEINT]] = { {{.*}}optnone{{.*}} } 163 // CHECK-NOT: attributes [[ATTRANOTHERNORMAL]] = { {{.*}}optnone{{.*}} } 164 // CHECK-NOT: attributes [[ATTRYETANOTHERNORMAL]] = { {{.*}}optnone{{.*}} } 165