xref: /minix3/external/bsd/llvm/dist/clang/test/SemaCXX/pragma-optimize.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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 Sambuc int 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 Sambuc int 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 Sambuc template <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 Sambuc int __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 Sambuc int __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 Sambuc CREATE_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 Sambuc float 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 Sambuc template<> int thrice(int par) {
99*0a6a1f1dSLionel Sambuc     return (par << 1) + par;
100*0a6a1f1dSLionel Sambuc }
container3(int par)101*0a6a1f1dSLionel Sambuc int 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 Sambuc int 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 Sambuc int 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 Sambuc int 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 Sambuc int 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