165 lines · cpp
1// RUN: %clang_cc1 -I %S/Inputs -x c++ -std=c++11 -triple x86_64-unknown-linux -emit-llvm -O2 < %s | FileCheck -allow-deprecated-dag-overlap %s2// RUN: %clang_cc1 -I %S/Inputs -x c++ -std=c++11 -triple x86_64-unknown-linux -emit-llvm -Os < %s | FileCheck -allow-deprecated-dag-overlap %s3// RUN: %clang_cc1 -I %S/Inputs -x c++ -std=c++11 -triple x86_64-unknown-linux -emit-llvm -Oz < %s | FileCheck -allow-deprecated-dag-overlap %s4 5#pragma clang optimize off6 7// This is a macro definition and therefore its text is not present after8// preprocessing. The pragma has no effect here.9#define CREATE_FUNC(name) \10int name (int param) { \11 return param; \12} \13 14// This is a declaration and therefore it is not decorated with `optnone`.15extern 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`.19int 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 invocation27// is also decorated with the `optnone` attribute because it is within a28// region of code affected by the functionality (not because of the position29// of the macro definition).30CREATE_FUNC (created)31// CHECK-DAG: @_Z7createdi{{.*}} [[ATTRCREATED:#[0-9]+]]32 33class 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`.40int 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`.46template <typename T> T twice (T param);47 48// The template definition will be decorated with the attribute `optnone`.49template <typename T> T thrice (T param) {50 return 3 * param;51}52 53// This function definition will not be decorated with `optnone` because the54// attribute would conflict with `always_inline`.55int __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 the61// attribute would conflict with `minsize`.62int __attribute__((minsize)) bax(int z) {63 return foo(z, 2);64}65// CHECK-DAG: @_Z3baxi{{.*}} [[ATTRBAX:#[0-9]+]]66 67#pragma clang optimize on68 69// The function "int wombat(int param)" created by the macro is not70// decorated with `optnone`, because the pragma applies its effects only71// after preprocessing. The position of the macro definition is not72// relevant.73CREATE_FUNC (wombat)74// CHECK-DAG: @_Z6wombati{{.*}} [[ATTRWOMBAT:#[0-9]+]]75 76// This instantiation of the "twice" template function with a "float" type77// will not have an `optnone` attribute because the template declaration was78// not affected by the pragma.79float 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" type86// will have an `optnone` attribute because the template definition was87// affected by the pragma.88float 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 be96// decorated with an `optnone` attribute because it is now outside of the97// affected region.98template<> int thrice(int par) {99 return (par << 1) + par;100}101int 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 off112 113int another_optnone(int x) {114 return x << 1;115}116// CHECK-DAG: @_Z15another_optnonei{{.*}} [[ATTRANOTHEROPTNONE:#[0-9]+]]117 118#pragma clang optimize on119 120int 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 the127// 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 132int yet_another_optnone(int x) {133 return x << 3;134}135// CHECK-DAG: @_Z19yet_another_optnonei{{.*}} [[ATTRYETANOTHEROPTNONE:#[0-9]+]]136 137#pragma clang optimize on138 139int 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