[clang] 4516dc1 - Don't add optnone or noinline if the function is already marked as

Akira Hatanaka via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 15 15:46:37 PST 2019


Author: Akira Hatanaka
Date: 2019-11-15T15:44:04-08:00
New Revision: 4516dc1c20d1e77f20a72e90be876506805b3978

URL: https://github.com/llvm/llvm-project/commit/4516dc1c20d1e77f20a72e90be876506805b3978
DIFF: https://github.com/llvm/llvm-project/commit/4516dc1c20d1e77f20a72e90be876506805b3978.diff

LOG: Don't add optnone or noinline if the function is already marked as
always_inline.

The assertion in SetLLVMFunctionAttributesForDefinition used to fail
when there was attribute OptimizeNone on the AST function and attribute
always_inline on the IR function. This happens because base destructors
are annotated with always_inline when the code is compiled with
-fapple-kext (see r124757).

rdar://problem/57169694

Added: 
    

Modified: 
    clang/lib/CodeGen/CodeGenModule.cpp
    clang/test/CodeGenCXX/apple-kext.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index b7db1f49c0e9..e253bbc19915 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1515,16 +1515,15 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
       !CodeGenOpts.DisableO0ImplyOptNone && CodeGenOpts.OptimizationLevel == 0;
   // We can't add optnone in the following cases, it won't pass the verifier.
   ShouldAddOptNone &= !D->hasAttr<MinSizeAttr>();
-  ShouldAddOptNone &= !F->hasFnAttribute(llvm::Attribute::AlwaysInline);
   ShouldAddOptNone &= !D->hasAttr<AlwaysInlineAttr>();
 
-  if (ShouldAddOptNone || D->hasAttr<OptimizeNoneAttr>()) {
+  // Add optnone, but do so only if the function isn't always_inline.
+  if ((ShouldAddOptNone || D->hasAttr<OptimizeNoneAttr>()) &&
+      !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) {
     B.addAttribute(llvm::Attribute::OptimizeNone);
 
     // OptimizeNone implies noinline; we should not be inlining such functions.
     B.addAttribute(llvm::Attribute::NoInline);
-    assert(!F->hasFnAttribute(llvm::Attribute::AlwaysInline) &&
-           "OptimizeNone and AlwaysInline on same function!");
 
     // We still need to handle naked functions even though optnone subsumes
     // much of their semantics.
@@ -1540,7 +1539,8 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
     B.addAttribute(llvm::Attribute::NoInline);
   } else if (D->hasAttr<NoDuplicateAttr>()) {
     B.addAttribute(llvm::Attribute::NoDuplicate);
-  } else if (D->hasAttr<NoInlineAttr>()) {
+  } else if (D->hasAttr<NoInlineAttr>() && !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) {
+    // Add noinline if the function isn't always_inline.
     B.addAttribute(llvm::Attribute::NoInline);
   } else if (D->hasAttr<AlwaysInlineAttr>() &&
              !F->hasFnAttribute(llvm::Attribute::NoInline)) {

diff  --git a/clang/test/CodeGenCXX/apple-kext.cpp b/clang/test/CodeGenCXX/apple-kext.cpp
index 0d7ccfb3be1a..990bc146c57c 100644
--- a/clang/test/CodeGenCXX/apple-kext.cpp
+++ b/clang/test/CodeGenCXX/apple-kext.cpp
@@ -4,6 +4,25 @@
 // CHECK: @llvm.global_ctors = appending global {{.*}} { i32 65535, void ()* [[CTOR0:@.*]], i8* null }
 // CHECK: @llvm.global_dtors = appending global {{.*}} { i32 65535, void ()* [[DTOR0:@.*]], i8* null }
 
+// Check that the base destructor is marked as always_inline when generating
+// code for kext.
+
+namespace testBaseDestructor {
+#pragma clang optimize off
+struct D {
+  virtual ~D();
+};
+
+D::~D() {}
+#pragma clang optimize on
+}
+
+// CHECK: define void @_ZN18testBaseDestructor1DD2Ev({{.*}}) unnamed_addr #[[ATTR0:.*]] align 2 {
+
+// CHECK: define void @_ZN18testBaseDestructor1DD1Ev({{.*}}) unnamed_addr #[[ATTR1:.*]] align 2 {
+
+// CHECK: define void @_ZN18testBaseDestructor1DD0Ev({{.*}}) unnamed_addr #[[ATTR1]] align 2 {
+
 // rdar://11241230
 namespace test0 {
   struct A { A(); ~A(); };
@@ -20,3 +39,6 @@ namespace test0 {
 // CHECK:    define internal void [[DTOR0]]()
 // CHECK:      call void @_ZN5test01AD1Ev([[A]]* @_ZN5test01aE)
 // CHECK-NEXT: ret void
+
+// CHECK: attributes #[[ATTR0]] = { alwaysinline nounwind {{.*}} }
+// CHECK: attributes #[[ATTR1]] = { noinline nounwind {{.*}} }


        


More information about the cfe-commits mailing list