1 // RUN: %clang_cc1 -I %S/Inputs -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 // Test that we can re-open and re-close an "off" region after the first one,
100 // and that this works as expected.
101 
102 #pragma clang optimize off
103 
104 int another_optnone(int x) {
105     return x << 1;
106 }
107 // CHECK-DAG: @_Z15another_optnonei{{.*}} [[ATTRANOTHEROPTNONE:#[0-9]+]]
108 
109 #pragma clang optimize on
110 
111 int another_normal(int x) {
112     return x << 2;
113 }
114 // CHECK-DAG: @_Z14another_normali{{.*}} [[ATTRANOTHERNORMAL:#[0-9]+]]
115 
116 
117 // Test that we can re-open an "off" region by including a header with the
118 // pragma and that this works as expected (i.e. the off region "falls through"
119 // the end of the header into this file).
120 
121 #include <header-with-pragma-optimize-off.h>
122 
123 int yet_another_optnone(int x) {
124     return x << 3;
125 }
126 // CHECK-DAG: @_Z19yet_another_optnonei{{.*}} [[ATTRYETANOTHEROPTNONE:#[0-9]+]]
127 
128 #pragma clang optimize on
129 
130 int yet_another_normal(int x) {
131     return x << 4;
132 }
133 // CHECK-DAG: @_Z18yet_another_normali{{.*}} [[ATTRYETANOTHERNORMAL:#[0-9]+]]
134 
135 
136 // Check for both noinline and optnone on each function that should have them.
137 // CHECK-DAG: attributes [[ATTRBAR]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
138 // CHECK-DAG: attributes [[ATTRCREATED]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
139 // CHECK-DAG: attributes [[ATTRMETHOD]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
140 // CHECK-DAG: attributes [[ATTRTHRICEFLOAT]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
141 // CHECK-DAG: attributes [[ATTRANOTHEROPTNONE]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
142 // CHECK-DAG: attributes [[ATTRYETANOTHEROPTNONE]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
143 
144 // Check that the other functions do NOT have optnone.
145 // CHECK-DAG-NOT: attributes [[ATTRFOO]] = { {{.*}}optnone{{.*}} }
146 // CHECK-DAG-NOT: attributes [[ATTRBAZ]] = { {{.*}}optnone{{.*}} }
147 // CHECK-DAG-NOT: attributes [[ATTRWOMBAT]] = { {{.*}}optnone{{.*}} }
148 // CHECK-DAG-NOT: attributes [[ATTRCONTAINER]] = { {{.*}}optnone{{.*}} }
149 // CHECK-DAG-NOT: attributes [[ATTRTWICE]] = { {{.*}}optnone{{.*}} }
150 // CHECK-DAG-NOT: attributes [[ATTRCONTAINER2]] = { {{.*}}optnone{{.*}} }
151 // CHECK-DAG-NOT: attributes [[ATTRCONTAINER3]] = { {{.*}}optnone{{.*}} }
152 // CHECK-DAG-NOT: attributes [[ATTRTHRICEINT]] = { {{.*}}optnone{{.*}} }
153 // CHECK-DAG-NOT: attributes [[ATTRANOTHERNORMAL]] = { {{.*}}optnone{{.*}} }
154 // CHECK-DAG-NOT: attributes [[ATTRYETANOTHERNORMAL]] = { {{.*}}optnone{{.*}} }
155