Home | History | Annotate | Download | only in SemaCXX
      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