r256762 - Add some overlooked optnone tests, and tighten up an existing test.

Paul Robinson via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 4 09:03:58 PST 2016


Author: probinson
Date: Mon Jan  4 11:03:58 2016
New Revision: 256762

URL: http://llvm.org/viewvc/llvm-project?rev=256762&view=rev
Log:
Add some overlooked optnone tests, and tighten up an existing test.

Differential Revision: http://reviews.llvm.org/D15704

Added:
    cfe/trunk/test/CodeGenCXX/optnone-and-attributes.cpp
    cfe/trunk/test/CodeGenCXX/optnone-class-members.cpp
    cfe/trunk/test/CodeGenCXX/optnone-templates.cpp
Modified:
    cfe/trunk/test/CodeGenCXX/optnone-def-decl.cpp

Added: cfe/trunk/test/CodeGenCXX/optnone-and-attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/optnone-and-attributes.cpp?rev=256762&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/optnone-and-attributes.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/optnone-and-attributes.cpp Mon Jan  4 11:03:58 2016
@@ -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

Added: cfe/trunk/test/CodeGenCXX/optnone-class-members.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/optnone-class-members.cpp?rev=256762&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/optnone-class-members.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/optnone-class-members.cpp Mon Jan  4 11:03:58 2016
@@ -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

Modified: cfe/trunk/test/CodeGenCXX/optnone-def-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/optnone-def-decl.cpp?rev=256762&r1=256761&r2=256762&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/optnone-def-decl.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/optnone-def-decl.cpp Mon Jan  4 11:03:58 2016
@@ -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

Added: cfe/trunk/test/CodeGenCXX/optnone-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/optnone-templates.cpp?rev=256762&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/optnone-templates.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/optnone-templates.cpp Mon Jan  4 11:03:58 2016
@@ -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




More information about the cfe-commits mailing list