[clang] e53bbd9 - [IR] move nomerge attribute from function declaration/definition to callsites

Zequan Wu via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 12 12:10:57 PST 2021


Author: Zequan Wu
Date: 2021-01-12T12:10:46-08:00
New Revision: e53bbd99516fc7b612df1ae08d48288d0b8784ea

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

LOG: [IR] move nomerge attribute from function declaration/definition to callsites

Move nomerge attribute from function declaration/definition to callsites to
allow virtual function calls attach the attribute.

Differential Revision: https://reviews.llvm.org/D94537

Added: 
    

Modified: 
    clang/lib/CodeGen/CGCall.cpp
    clang/lib/CodeGen/CodeGenModule.cpp
    clang/test/CodeGen/attr-nomerge.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 2cc7203d1194..42801372189b 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1985,7 +1985,9 @@ void CodeGenModule::ConstructAttributeList(
           FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
         NBA = Fn->getAttr<NoBuiltinAttr>();
       }
-      if (!AttrOnCallSite && TargetDecl->hasAttr<NoMergeAttr>())
+      // Only place nomerge attribute on call sites, never functions. This
+      // allows it to work on indirect virtual function calls.
+      if (AttrOnCallSite && TargetDecl->hasAttr<NoMergeAttr>())
         FuncAttrs.addAttribute(llvm::Attribute::NoMerge);
     }
 
@@ -5018,13 +5020,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
         Attrs.addAttribute(getLLVMContext(), llvm::AttributeList::FunctionIndex,
                            llvm::Attribute::StrictFP);
 
-  // Add nomerge attribute to the call-site if the callee function doesn't have
-  // the attribute.
-  if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
-    if (!FD->hasAttr<NoMergeAttr>() && InNoMergeAttributedStmt)
-      Attrs = Attrs.addAttribute(getLLVMContext(),
-                                 llvm::AttributeList::FunctionIndex,
-                                 llvm::Attribute::NoMerge);
+  // Add call-site nomerge attribute if exists.
+  if (InNoMergeAttributedStmt)
+    Attrs =
+        Attrs.addAttribute(getLLVMContext(), llvm::AttributeList::FunctionIndex,
+                           llvm::Attribute::NoMerge);
 
   // Apply some call-site-specific attributes.
   // TODO: work this into building the attribute set.

diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index da5b03b138bf..bee51715bdc6 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1772,9 +1772,6 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
       B.addAttribute(llvm::Attribute::MinSize);
   }
 
-  if (D->hasAttr<NoMergeAttr>())
-    B.addAttribute(llvm::Attribute::NoMerge);
-
   F->addAttributes(llvm::AttributeList::FunctionIndex, B);
 
   unsigned alignment = D->getMaxAlignment() / Context.getCharWidth();

diff  --git a/clang/test/CodeGen/attr-nomerge.cpp b/clang/test/CodeGen/attr-nomerge.cpp
index d93f4a7c96d6..fc26af379fdb 100644
--- a/clang/test/CodeGen/attr-nomerge.cpp
+++ b/clang/test/CodeGen/attr-nomerge.cpp
@@ -3,7 +3,7 @@
 class A {
 public:
   [[clang::nomerge]] A();
-  [[clang::nomerge]] ~A();
+  [[clang::nomerge]] virtual ~A();
   [[clang::nomerge]] void f();
   [[clang::nomerge]] virtual void g();
   [[clang::nomerge]] static void f1();
@@ -14,14 +14,14 @@ class B : public A {
   void g() override;
 };
 
-[[clang::nomerge]] bool bar();
+bool bar();
 [[clang::nomerge]] void f(bool, bool);
 
 void foo(int i, A *ap, B *bp) {
   [[clang::nomerge]] bar();
   [[clang::nomerge]] (i = 4, bar());
   [[clang::nomerge]] (void)(bar());
-  [[clang::nomerge]] f(bar(), bar());
+  f(bar(), bar());
   [[clang::nomerge]] [] { bar(); bar(); }(); // nomerge only applies to the anonymous function call
   [[clang::nomerge]] for (bar(); bar(); bar()) {}
   [[clang::nomerge]] { asm("nop"); }
@@ -37,6 +37,9 @@ void foo(int i, A *ap, B *bp) {
 
   B b;
   b.g();
+
+  A *newA = new B();
+  delete newA;
 }
 
 int g(int i);
@@ -57,37 +60,34 @@ void something_else_again() {
   g(1);
 }
 
+// CHECK: call zeroext i1 @_Z3barv() #[[ATTR0:[0-9]+]]
+// CHECK: call zeroext i1 @_Z3barv() #[[ATTR0]]
+// CHECK: call zeroext i1 @_Z3barv() #[[ATTR0]]
 // CHECK: call zeroext i1 @_Z3barv(){{$}}
 // CHECK: call zeroext i1 @_Z3barv(){{$}}
-// CHECK: call zeroext i1 @_Z3barv(){{$}}
-// CHECK: call zeroext i1 @_Z3barv(){{$}}
-// CHECK: call zeroext i1 @_Z3barv(){{$}}
-// CHECK: call void @_Z1fbb({{.*}}){{$}}
-// CHECK: call void @"_ZZ3fooiP1AP1BENK3$_0clEv"{{.*}} #[[ATTR0:[0-9]+]]
-// CHECK: call zeroext i1 @_Z3barv(){{$}}
-// CHECK: call zeroext i1 @_Z3barv(){{$}}
-// CHECK: call zeroext i1 @_Z3barv(){{$}}
+// CHECK: call void @_Z1fbb({{.*}}) #[[ATTR0]]
+// CHECK: call void @"_ZZ3fooiP1AP1BENK3$_0clEv"{{.*}} #[[ATTR0]]
+// CHECK: call zeroext i1 @_Z3barv() #[[ATTR0]]
+// CHECK-LABEL: for.cond:
+// CHECK: call zeroext i1 @_Z3barv() #[[ATTR0]]
+// CHECK-LABEL: for.inc:
+// CHECK: call zeroext i1 @_Z3barv() #[[ATTR0]]
 // CHECK: call void asm sideeffect "nop"{{.*}} #[[ATTR1:[0-9]+]]
 // CHECK: call zeroext i1 @_Z3barv(){{$}}
 // CHECK: %[[AG:.*]] = load void (%class.A*)*, void (%class.A*)**
-// CHECK-NEXT: call void %[[AG]](%class.A* nonnull dereferenceable
+// CHECK-NEXT: call void %[[AG]](%class.A* {{.*}}) #[[ATTR0]]
 // CHECK: %[[BG:.*]] = load void (%class.B*)*, void (%class.B*)**
 // CHECK-NEXT: call void %[[BG]](%class.B* nonnull dereferenceable
-
-
-// CHECK-DAG: declare zeroext i1 @_Z3barv() #[[ATTR2:[0-9]+]]
-// CHECK-DAG: declare void @_Z1fbb(i1 zeroext, i1 zeroext) #[[ATTR2]]
-// CHECK-DAG: declare void @_ZN1AC1Ev{{.*}} #[[ATTR2]]
-// CHECK-DAG: declare void @_ZN1A1fEv{{.*}} #[[ATTR2]]
-// CHECK-DAG: declare void @_ZN1A1gEv{{.*}} #[[ATTR2]]
-// CHECK-DAG: declare void @_ZN1A2f1Ev{{.*}} #[[ATTR2]]
-// CHECK-DAG: declare void @_ZN1AC2Ev{{.*}} #[[ATTR2]]
-// CHECK-DAG: declare void @_ZN1AD1Ev{{.*}} #[[ATTR3:[0-9]+]]
-// CHECK-DAG: declare void @_ZN1AD2Ev{{.*}} #[[ATTR3]]
-// CHECK-DAG: define{{.*}} i32 @_Z1gi(i32 %i) #[[ATTR4:[0-9]+]] {
+// CHECK: call void @_ZN1AC1Ev({{.*}}) #[[ATTR0]]
+// CHECK: call void @_ZN1A1fEv({{.*}}) #[[ATTR0]]
+// CHECK: call void @_ZN1A1gEv({{.*}}) #[[ATTR0]]
+// CHECK: call void @_ZN1A2f1Ev() #[[ATTR0]]
+// CHECK: call void @_ZN1BC1Ev({{.*}}){{$}}
+// CHECK: call void @_ZN1B1gEv({{.*}}){{$}}
+// CHECK: call void @_ZN1BC1Ev({{.*}}){{$}}
+// CHECK: %[[AG:.*]] = load void (%class.A*)*, void (%class.A*)**
+// CHECK-NEXT: call void %[[AG]](%class.A* {{.*}}) #[[ATTR1]]
+// CHECK: call void  @_ZN1AD1Ev(%class.A* {{.*}}) #[[ATTR1]]
 
 // CHECK-DAG: attributes #[[ATTR0]] = {{{.*}}nomerge{{.*}}}
 // CHECK-DAG: attributes #[[ATTR1]] = {{{.*}}nomerge{{.*}}}
-// CHECK-DAG: attributes #[[ATTR2]] = {{{.*}}nomerge{{.*}}}
-// CHECK-DAG: attributes #[[ATTR3]] = {{{.*}}nomerge{{.*}}}
-// CHECK-DAG: attributes #[[ATTR4]] = {{{.*}}nomerge{{.*}}}


        


More information about the cfe-commits mailing list