forked from OSchip/llvm-project
Add some overlooked optnone tests, and tighten up an existing test.
Differential Revision: http://reviews.llvm.org/D15704 llvm-svn: 256762
This commit is contained in:
parent
947ca8ac52
commit
9d6940ba09
|
@ -0,0 +1,82 @@
|
|||
// RUN: %clang_cc1 < %s -triple i386-mingw32 -fms-extensions -emit-llvm -x c++ | FileCheck %s
|
||||
|
||||
// optnone wins over inlinehint.
|
||||
// Test that both func1 and func2 are marked optnone and noinline.
|
||||
|
||||
// Definition with both optnone and inlinehint.
|
||||
__attribute__((optnone))
|
||||
inline int func1(int a) {
|
||||
return a + a + a + a;
|
||||
}
|
||||
// CHECK: @_Z5func1i({{.*}}) [[OPTNONE:#[0-9]+]]
|
||||
|
||||
// optnone declaration, inlinehint definition.
|
||||
__attribute__((optnone))
|
||||
int func2(int a);
|
||||
|
||||
inline int func2(int a) {
|
||||
return a + a + a + a;
|
||||
}
|
||||
// CHECK: @_Z5func2i({{.*}}) [[OPTNONE]]
|
||||
|
||||
// Keep alive the definitions of func1 and func2.
|
||||
int foo() {
|
||||
int val = func1(1);
|
||||
return val + func2(2);
|
||||
}
|
||||
|
||||
// optnone wins over minsize.
|
||||
__attribute__((optnone))
|
||||
int func3(int a);
|
||||
|
||||
__attribute__((minsize))
|
||||
int func3(int a) {
|
||||
return a + a + a + a;
|
||||
}
|
||||
// Same attribute set as everything else, therefore no 'minsize'.
|
||||
// CHECK: @_Z5func3i({{.*}}) [[OPTNONE]]
|
||||
|
||||
|
||||
// Verify that noreturn is compatible with optnone.
|
||||
__attribute__((noreturn))
|
||||
extern void exit_from_function();
|
||||
|
||||
__attribute__((noreturn)) __attribute((optnone))
|
||||
extern void noreturn_function(int a) { exit_from_function(); }
|
||||
// CHECK: @_Z17noreturn_functioni({{.*}}) [[NORETURN:#[0-9]+]]
|
||||
|
||||
|
||||
// Verify that __declspec(noinline) is compatible with optnone.
|
||||
__declspec(noinline) __attribute__((optnone))
|
||||
void func4() { return; }
|
||||
// CHECK: @_Z5func4v() [[OPTNONE]]
|
||||
|
||||
__declspec(noinline)
|
||||
extern void func5();
|
||||
|
||||
__attribute__((optnone))
|
||||
void func5() { return; }
|
||||
// CHECK: @_Z5func5v() [[OPTNONE]]
|
||||
|
||||
|
||||
// Verify also that optnone can be used on dllexport functions.
|
||||
// Adding attribute optnone on a dllimport function has no effect.
|
||||
|
||||
__attribute__((dllimport))
|
||||
__attribute__((optnone))
|
||||
int imported_optnone_func(int a);
|
||||
|
||||
__attribute__((dllexport))
|
||||
__attribute__((optnone))
|
||||
int exported_optnone_func(int a) {
|
||||
return imported_optnone_func(a); // use of imported func
|
||||
}
|
||||
// CHECK: @_Z21exported_optnone_funci({{.*}}) [[OPTNONE]]
|
||||
// CHECK: declare dllimport {{.*}} @_Z21imported_optnone_funci({{.*}}) [[DLLIMPORT:#[0-9]+]]
|
||||
|
||||
|
||||
// CHECK: attributes [[OPTNONE]] = { noinline {{.*}} optnone
|
||||
// CHECK: attributes [[NORETURN]] = { noinline noreturn {{.*}} optnone
|
||||
|
||||
// CHECK: attributes [[DLLIMPORT]] =
|
||||
// CHECK-SAME-NOT: optnone
|
|
@ -0,0 +1,164 @@
|
|||
// RUN: %clang_cc1 < %s -triple %itanium_abi_triple -fms-extensions -emit-llvm -x c++ | FileCheck %s
|
||||
|
||||
// Test attribute 'optnone' on methods:
|
||||
// -- member functions;
|
||||
// -- static member functions.
|
||||
|
||||
// Verify that all methods of struct A are associated to the same attribute set.
|
||||
// The attribute set shall contain attributes 'noinline' and 'optnone'.
|
||||
|
||||
struct A {
|
||||
// Definition of an optnone static method.
|
||||
__attribute__((optnone))
|
||||
static int static_optnone_method(int a) {
|
||||
return a + a;
|
||||
}
|
||||
// CHECK: @_ZN1A21static_optnone_methodEi({{.*}}) [[OPTNONE:#[0-9]+]]
|
||||
|
||||
// Definition of an optnone normal method.
|
||||
__attribute__((optnone))
|
||||
int optnone_method(int a) {
|
||||
return a + a + a + a;
|
||||
}
|
||||
// CHECK: @_ZN1A14optnone_methodEi({{.*}}) [[OPTNONE]]
|
||||
|
||||
// Declaration of an optnone method with out-of-line definition
|
||||
// that doesn't say optnone.
|
||||
__attribute__((optnone))
|
||||
int optnone_decl_method(int a);
|
||||
|
||||
// Methods declared without attribute optnone; the definitions will
|
||||
// have attribute optnone, and we verify optnone wins.
|
||||
__forceinline static int static_forceinline_method(int a);
|
||||
__attribute__((always_inline)) int alwaysinline_method(int a);
|
||||
__attribute__((noinline)) int noinline_method(int a);
|
||||
__attribute__((minsize)) int minsize_method(int a);
|
||||
};
|
||||
|
||||
void foo() {
|
||||
A a;
|
||||
A::static_optnone_method(4);
|
||||
a.optnone_method(14);
|
||||
a.optnone_decl_method(12);
|
||||
A::static_forceinline_method(5);
|
||||
a.alwaysinline_method(5);
|
||||
a.noinline_method(6);
|
||||
a.minsize_method(7);
|
||||
}
|
||||
|
||||
// No attribute here, should still be on the definition.
|
||||
int A::optnone_decl_method(int a) {
|
||||
return a;
|
||||
}
|
||||
// CHECK: @_ZN1A19optnone_decl_methodEi({{.*}}) [[OPTNONE]]
|
||||
|
||||
// optnone implies noinline; therefore attribute noinline is added to
|
||||
// the set of function attributes.
|
||||
// forceinline is instead translated as 'always_inline'.
|
||||
// However 'noinline' wins over 'always_inline' and therefore
|
||||
// the resulting attributes for this method are: noinline + optnone
|
||||
__attribute__((optnone))
|
||||
int A::static_forceinline_method(int a) {
|
||||
return a + a + a + a;
|
||||
}
|
||||
// CHECK: @_ZN1A25static_forceinline_methodEi({{.*}}) [[OPTNONE]]
|
||||
|
||||
__attribute__((optnone))
|
||||
int A::alwaysinline_method(int a) {
|
||||
return a + a + a + a;
|
||||
}
|
||||
// CHECK: @_ZN1A19alwaysinline_methodEi({{.*}}) [[OPTNONE]]
|
||||
|
||||
// 'noinline' + 'noinline and optnone' = 'noinline and optnone'
|
||||
__attribute__((optnone))
|
||||
int A::noinline_method(int a) {
|
||||
return a + a + a + a;
|
||||
}
|
||||
// CHECK: @_ZN1A15noinline_methodEi({{.*}}) [[OPTNONE]]
|
||||
|
||||
// 'optnone' wins over 'minsize'
|
||||
__attribute__((optnone))
|
||||
int A::minsize_method(int a) {
|
||||
return a + a + a + a;
|
||||
}
|
||||
// CHECK: @_ZN1A14minsize_methodEi({{.*}}) [[OPTNONE]]
|
||||
|
||||
|
||||
// Test attribute 'optnone' on methods:
|
||||
// -- pure virtual functions
|
||||
// -- base virtual and derived virtual
|
||||
// -- base virtual but not derived virtual
|
||||
// -- optnone methods redefined in override
|
||||
|
||||
// A method defined in override doesn't inherit the function attributes of the
|
||||
// superclass method.
|
||||
|
||||
struct B {
|
||||
virtual int pure_virtual(int a) = 0;
|
||||
__attribute__((optnone))
|
||||
virtual int pure_virtual_with_optnone(int a) = 0;
|
||||
|
||||
virtual int base(int a) {
|
||||
return a + a + a + a;
|
||||
}
|
||||
|
||||
__attribute__((optnone))
|
||||
virtual int optnone_base(int a) {
|
||||
return a + a + a + a;
|
||||
}
|
||||
|
||||
__attribute__((optnone))
|
||||
virtual int only_base_virtual(int a) {
|
||||
return a + a;
|
||||
}
|
||||
};
|
||||
|
||||
struct C : public B {
|
||||
__attribute__((optnone))
|
||||
virtual int pure_virtual(int a) {
|
||||
return a + a + a + a;
|
||||
}
|
||||
|
||||
virtual int pure_virtual_with_optnone(int a) {
|
||||
return a + a + a + a;
|
||||
}
|
||||
|
||||
__attribute__((optnone))
|
||||
virtual int base(int a) {
|
||||
return a + a;
|
||||
}
|
||||
|
||||
virtual int optnone_base(int a) {
|
||||
return a + a;
|
||||
}
|
||||
|
||||
int only_base_virtual(int a) {
|
||||
return a + a + a + a;
|
||||
}
|
||||
};
|
||||
|
||||
int bar() {
|
||||
C c;
|
||||
int result;
|
||||
result = c.pure_virtual(3);
|
||||
result += c.pure_virtual_with_optnone(2);
|
||||
result += c.base(5);
|
||||
result += c.optnone_base(7);
|
||||
result += c.only_base_virtual(9);
|
||||
return result;
|
||||
}
|
||||
|
||||
// CHECK: @_ZN1C12pure_virtualEi({{.*}}) {{.*}} [[OPTNONE]]
|
||||
// CHECK: @_ZN1C25pure_virtual_with_optnoneEi({{.*}}) {{.*}} [[NORMAL:#[0-9]+]]
|
||||
// CHECK: @_ZN1C4baseEi({{.*}}) {{.*}} [[OPTNONE]]
|
||||
// CHECK: @_ZN1C12optnone_baseEi({{.*}}) {{.*}} [[NORMAL]]
|
||||
// CHECK: @_ZN1C17only_base_virtualEi({{.*}}) {{.*}} [[NORMAL]]
|
||||
// CHECK: @_ZN1B4baseEi({{.*}}) {{.*}} [[NORMAL]]
|
||||
// CHECK: @_ZN1B12optnone_baseEi({{.*}}) {{.*}} [[OPTNONE]]
|
||||
// CHECK: @_ZN1B17only_base_virtualEi({{.*}}) {{.*}} [[OPTNONE]]
|
||||
|
||||
|
||||
// CHECK: attributes [[NORMAL]] =
|
||||
// CHECK-SAME-NOT: noinline
|
||||
// CHECK-SAME-NOT: optnone
|
||||
// CHECK: attributes [[OPTNONE]] = {{.*}} noinline {{.*}} optnone
|
|
@ -90,5 +90,6 @@ int user_of_forceinline_optnone_function() {
|
|||
// CHECK: @_Z28forceinline_optnone_functionii({{.*}}) [[OPTNONE]]
|
||||
|
||||
// CHECK: attributes [[OPTNONE]] = { noinline nounwind optnone {{.*}} }
|
||||
// CHECK: attributes [[NORMAL]] = { nounwind {{.*}} }
|
||||
|
||||
// CHECK: attributes [[NORMAL]] =
|
||||
// CHECK-SAME-NOT: noinline
|
||||
// CHECK-SAME-NOT: optnone
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
// RUN: %clang_cc1 %s -triple %itanium_abi_triple -std=c++11 -emit-llvm -o - | FileCheck %s
|
||||
|
||||
// Test optnone on template instantiations.
|
||||
|
||||
//-- Effect of optnone on generic add template function.
|
||||
|
||||
template <typename T> T template_normal(T a)
|
||||
{
|
||||
return a + a;
|
||||
}
|
||||
|
||||
template <typename T> __attribute__((optnone)) T template_optnone(T a)
|
||||
{
|
||||
return a + a + a;
|
||||
}
|
||||
|
||||
// This function should cause instantiations of each template, one marked
|
||||
// with the 'optnone' attribute.
|
||||
int container(int i)
|
||||
{
|
||||
return template_normal<int>(i) + template_optnone<int>(i);
|
||||
}
|
||||
|
||||
// CHECK: @_Z15template_normalIiET_S0_({{.*}}) [[NORMAL:#[0-9]+]]
|
||||
// CHECK: @_Z16template_optnoneIiET_S0_({{.*}}) [[OPTNONE:#[0-9]+]]
|
||||
|
||||
|
||||
//-- Effect of optnone on a partial specialization.
|
||||
// FIRST TEST: a method becomes marked with optnone in the specialization.
|
||||
|
||||
template <typename T, typename U> class template_normal_base {
|
||||
public:
|
||||
T method(T t, U u)
|
||||
{
|
||||
return t + static_cast<T>(u);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U> class template_normal_base<int, U>
|
||||
{
|
||||
public:
|
||||
__attribute__((optnone)) int method (int t, U u)
|
||||
{
|
||||
return t - static_cast<int>(u);
|
||||
}
|
||||
};
|
||||
|
||||
// This function should cause an instantiation of the full template (whose
|
||||
// method is not marked optnone) and an instantiation of the partially
|
||||
// specialized template (whose method is marked optnone).
|
||||
void container2()
|
||||
{
|
||||
int y = 2;
|
||||
float z = 3.0;
|
||||
template_normal_base<float, int> class_normal;
|
||||
template_normal_base<int, float> class_optnone;
|
||||
float r1 = class_normal.method(z, y);
|
||||
float r2 = class_optnone.method(y, z);
|
||||
}
|
||||
|
||||
// CHECK: @_ZN20template_normal_baseIfiE6methodEfi({{.*}}) [[NORMAL]]
|
||||
// CHECK: @_ZN20template_normal_baseIifE6methodEif({{.*}}) [[OPTNONE]]
|
||||
|
||||
|
||||
//-- Effect of optnone on a partial specialization.
|
||||
// SECOND TEST: a method loses optnone in the specialization.
|
||||
|
||||
template <typename T, typename U> class template_optnone_base {
|
||||
public:
|
||||
__attribute__((optnone)) T method(T t, U u)
|
||||
{
|
||||
return t + static_cast<T>(u);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U> class template_optnone_base<int, U>
|
||||
{
|
||||
public:
|
||||
int method (int t, U u)
|
||||
{
|
||||
return t - static_cast<int>(u);
|
||||
}
|
||||
};
|
||||
|
||||
// This function should cause an instantiation of the full template (whose
|
||||
// method is marked optnone) and an instantiation of the partially
|
||||
// specialized template (whose method is not marked optnone).
|
||||
void container3()
|
||||
{
|
||||
int y = 2;
|
||||
float z = 3.0;
|
||||
template_optnone_base<float, int> class_optnone;
|
||||
template_optnone_base<int, float> class_normal;
|
||||
float r1 = class_optnone.method(z, y);
|
||||
float r2 = class_normal.method(y, z);
|
||||
}
|
||||
|
||||
// CHECK: @_ZN21template_optnone_baseIfiE6methodEfi({{.*}}) [[OPTNONE]]
|
||||
// CHECK: @_ZN21template_optnone_baseIifE6methodEif({{.*}}) [[NORMAL]]
|
||||
|
||||
|
||||
// CHECK: attributes [[NORMAL]] =
|
||||
// CHECK-SAME-NOT: optnone
|
||||
// CHECK: attributes [[OPTNONE]] = {{.*}} optnone
|
Loading…
Reference in New Issue