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