[clang] [llvm] [clang] report inlining decisions with -Wattribute-{warning|error} (PR #73552)

Nick Desaulniers via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 27 11:10:27 PST 2023


https://github.com/nickdesaulniers updated https://github.com/llvm/llvm-project/pull/73552

>From cea177222b421c67dabbe9e267f8b9a4ead4d51e Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Tue, 10 Jan 2023 17:42:18 -0800
Subject: [PATCH 01/12] [clang] report inlining decisions with
 -Wattribute-{warning|error}

Due to inlining, descovering which specific call site to a function with
the attribute "warning" or "error" is painful.

In the IR record inlining decisions in metadata when inlining a callee
that itself contains a call to a dontcall-error or dontcall-warn fn.

Print this info so that it's clearer which call site is problematic.

There's still some limitations with this approach; macro expansion is
not recorded.

Fixes: https://github.com/ClangBuiltLinux/linux/issues/1571

Differential Revision: https://reviews.llvm.org/D141451
---
 .../clang/Basic/DiagnosticFrontendKinds.td    |  2 +
 clang/lib/CodeGen/CodeGenAction.cpp           | 10 +++
 ...backend-attribute-error-warning-optimize.c | 21 +++++
 .../backend-attribute-error-warning.c         |  6 ++
 .../backend-attribute-error-warning.cpp       | 12 +++
 llvm/docs/LangRef.rst                         |  8 +-
 llvm/include/llvm/IR/DiagnosticInfo.h         | 14 +++-
 llvm/lib/IR/DiagnosticInfo.cpp                | 23 ++++-
 llvm/lib/Transforms/Utils/InlineFunction.cpp  | 13 +++
 .../Transforms/Inline/dontcall-attributes.ll  | 84 +++++++++++++++++++
 10 files changed, 185 insertions(+), 8 deletions(-)
 create mode 100644 llvm/test/Transforms/Inline/dontcall-attributes.ll

diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 715e0c0dc8fa84e..0909b1f59175be9 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -93,6 +93,8 @@ def err_fe_backend_error_attr :
 def warn_fe_backend_warning_attr :
   Warning<"call to '%0' declared with 'warning' attribute: %1">, BackendInfo,
   InGroup<BackendWarningAttributes>;
+def note_fe_backend_in : Note<"called by function '%0'">;
+def note_fe_backend_inlined : Note<"inlined by function '%0'">;
 
 def err_fe_invalid_code_complete_file : Error<
     "cannot locate code-completion file %0">, DefaultFatal;
diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp
index a31a271ed77d1ca..66e040741e2718d 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -52,6 +52,8 @@
 #include "llvm/Transforms/Utils/Cloning.h"
 
 #include <optional>
+#include <string>
+
 using namespace clang;
 using namespace llvm;
 
@@ -794,6 +796,14 @@ void BackendConsumer::DontCallDiagHandler(const DiagnosticInfoDontCall &D) {
                               ? diag::err_fe_backend_error_attr
                               : diag::warn_fe_backend_warning_attr)
       << llvm::demangle(D.getFunctionName()) << D.getNote();
+
+  SmallVector<std::string, 4> InliningDecisions;
+  D.getInliningDecisions(InliningDecisions);
+  InliningDecisions.push_back(D.getCaller().str());
+  for (auto Dec : llvm::enumerate(InliningDecisions))
+    Diags.Report(Dec.index() ? diag::note_fe_backend_inlined
+                             : diag::note_fe_backend_in)
+        << llvm::demangle(Dec.value());
 }
 
 void BackendConsumer::MisExpectDiagHandler(
diff --git a/clang/test/Frontend/backend-attribute-error-warning-optimize.c b/clang/test/Frontend/backend-attribute-error-warning-optimize.c
index d3951e3b6b1f57d..0bfc50ff8985c39 100644
--- a/clang/test/Frontend/backend-attribute-error-warning-optimize.c
+++ b/clang/test/Frontend/backend-attribute-error-warning-optimize.c
@@ -9,6 +9,7 @@ int x(void) {
 }
 void baz(void) {
   foo(); // expected-error {{call to 'foo' declared with 'error' attribute: oh no foo}}
+         // expected-note@* {{called by function 'baz'}}
   if (x())
     bar();
 }
@@ -20,3 +21,23 @@ void indirect(void) {
   quux = foo;
   quux();
 }
+
+static inline void a(int x) {
+    if (x == 10)
+        foo(); // expected-error {{call to 'foo' declared with 'error' attribute: oh no foo}}
+               // expected-note@* {{called by function 'a'}}
+               // expected-note@* {{inlined by function 'b'}}
+               // expected-note@* {{inlined by function 'd'}}
+}
+
+static inline void b() {
+    a(10);
+}
+
+void c() {
+    a(9);
+}
+
+void d() {
+  b();
+}
diff --git a/clang/test/Frontend/backend-attribute-error-warning.c b/clang/test/Frontend/backend-attribute-error-warning.c
index c3c7803479aac96..c87a47053e5c0f8 100644
--- a/clang/test/Frontend/backend-attribute-error-warning.c
+++ b/clang/test/Frontend/backend-attribute-error-warning.c
@@ -23,11 +23,17 @@ duplicate_warnings(void);
 
 void baz(void) {
   foo(); // expected-error {{call to 'foo' declared with 'error' attribute: oh no foo}}
+         // expected-note@* {{called by function 'baz'}}
   if (x())
     bar(); // expected-error {{call to 'bar' declared with 'error' attribute: oh no bar}}
+           // expected-note@* {{called by function 'baz'}}
 
   quux();                     // enabled-warning {{call to 'quux' declared with 'warning' attribute: oh no quux}}
+                              // enabled-note@* {{called by function 'baz'}}
   __compiletime_assert_455(); // expected-error {{call to '__compiletime_assert_455' declared with 'error' attribute: demangle me}}
+                              // expected-note@* {{called by function 'baz'}}
   duplicate_errors();         // expected-error {{call to 'duplicate_errors' declared with 'error' attribute: two}}
+                              // expected-note@* {{called by function 'baz'}}
   duplicate_warnings();       // enabled-warning {{call to 'duplicate_warnings' declared with 'warning' attribute: two}}
+                              // enabled-note@* {{called by function 'baz'}}
 }
diff --git a/clang/test/Frontend/backend-attribute-error-warning.cpp b/clang/test/Frontend/backend-attribute-error-warning.cpp
index 1ed549c271241ab..537e798649f7508 100644
--- a/clang/test/Frontend/backend-attribute-error-warning.cpp
+++ b/clang/test/Frontend/backend-attribute-error-warning.cpp
@@ -24,13 +24,19 @@ duplicate_warnings(void);
 
 void baz(void) {
   foo(); // expected-error {{call to 'foo()' declared with 'error' attribute: oh no foo}}
+         // expected-note@* {{called by function 'baz()'}}
   if (x())
     bar(); // expected-error {{call to 'bar()' declared with 'error' attribute: oh no bar}}
+           // expected-note@* {{called by function 'baz()'}}
 
   quux();                     // enabled-warning {{call to 'quux()' declared with 'warning' attribute: oh no quux}}
+                              // enabled-note@* {{called by function 'baz()'}}
   __compiletime_assert_455(); // expected-error {{call to '__compiletime_assert_455()' declared with 'error' attribute: demangle me}}
+                              // expected-note@* {{called by function 'baz()'}}
   duplicate_errors();         // expected-error {{call to 'duplicate_errors()' declared with 'error' attribute: two}}
+                              // expected-note@* {{called by function 'baz()'}}
   duplicate_warnings();       // enabled-warning {{call to 'duplicate_warnings()' declared with 'warning' attribute: two}}
+                              // enabled-note@* {{called by function 'baz()'}}
 }
 
 #ifdef __cplusplus
@@ -46,15 +52,21 @@ struct Widget {
 
 void baz_cpp(void) {
   foo(); // expected-error {{call to 'foo()' declared with 'error' attribute: oh no foo}}
+         // expected-note@* {{called by function 'baz_cpp()'}}
   if (x())
     bar(); // expected-error {{call to 'bar()' declared with 'error' attribute: oh no bar}}
+           // expected-note@* {{called by function 'baz_cpp()'}}
   quux();  // enabled-warning {{call to 'quux()' declared with 'warning' attribute: oh no quux}}
+           // enabled-note@* {{called by function 'baz_cpp()'}}
 
   // Test that we demangle correctly in the diagnostic for C++.
   __compiletime_assert_455(); // expected-error {{call to '__compiletime_assert_455()' declared with 'error' attribute: demangle me}}
+                              // expected-note@* {{called by function 'baz_cpp()'}}
   nocall<int>(42);            // expected-error {{call to 'int nocall<int>(int)' declared with 'error' attribute: demangle me, too}}
+                              // expected-note@* {{called by function 'baz_cpp()'}}
 
   Widget W;
   int w = W; // enabled-warning {{call to 'Widget::operator int()' declared with 'warning' attribute: don't call me!}}
+             // enabled-note@* {{called by function 'baz_cpp()'}}
 }
 #endif
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index e448c5ed5c5d947..c3127dcaf1ef80a 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -1803,13 +1803,17 @@ example:
     call of a function with this attribute is not eliminated via optimization.
     Front ends can provide optional ``srcloc`` metadata nodes on call sites of
     such callees to attach information about where in the source language such a
-    call came from. A string value can be provided as a note.
+    call came from. A string value can be provided as a note. The optimizer may
+    add the optional ``inlined.from`` metadata to call sites which front ends
+    might consume to display more precise diagnostics.
 ``"dontcall-warn"``
     This attribute denotes that a warning diagnostic should be emitted when a
     call of a function with this attribute is not eliminated via optimization.
     Front ends can provide optional ``srcloc`` metadata nodes on call sites of
     such callees to attach information about where in the source language such a
-    call came from. A string value can be provided as a note.
+    call came from. A string value can be provided as a note. The optimizer may
+    add the optional ``inlined.from`` metadata to call sites which front ends
+    might consume to display more precise diagnostics.
 ``fn_ret_thunk_extern``
     This attribute tells the code generator that returns from functions should
     be replaced with jumps to externally-defined architecture-specific symbols.
diff --git a/llvm/include/llvm/IR/DiagnosticInfo.h b/llvm/include/llvm/IR/DiagnosticInfo.h
index 628445fe9fb2cca..3f64c0acd293ed5 100644
--- a/llvm/include/llvm/IR/DiagnosticInfo.h
+++ b/llvm/include/llvm/IR/DiagnosticInfo.h
@@ -1099,15 +1099,19 @@ class DiagnosticInfoSrcMgr : public DiagnosticInfo {
 void diagnoseDontCall(const CallInst &CI);
 
 class DiagnosticInfoDontCall : public DiagnosticInfo {
+  StringRef CallerName;
   StringRef CalleeName;
   StringRef Note;
   unsigned LocCookie;
+  MDNode *MDN;
 
 public:
-  DiagnosticInfoDontCall(StringRef CalleeName, StringRef Note,
-                         DiagnosticSeverity DS, unsigned LocCookie)
-      : DiagnosticInfo(DK_DontCall, DS), CalleeName(CalleeName), Note(Note),
-        LocCookie(LocCookie) {}
+  DiagnosticInfoDontCall(StringRef CallerName, StringRef CalleeName,
+                         StringRef Note, DiagnosticSeverity DS,
+                         unsigned LocCookie, MDNode *MDN)
+      : DiagnosticInfo(DK_DontCall, DS), CallerName(CallerName),
+        CalleeName(CalleeName), Note(Note), LocCookie(LocCookie), MDN(MDN) {}
+  StringRef getCaller() const { return CallerName; }
   StringRef getFunctionName() const { return CalleeName; }
   StringRef getNote() const { return Note; }
   unsigned getLocCookie() const { return LocCookie; }
@@ -1115,6 +1119,8 @@ class DiagnosticInfoDontCall : public DiagnosticInfo {
   static bool classof(const DiagnosticInfo *DI) {
     return DI->getKind() == DK_DontCall;
   }
+  void
+  getInliningDecisions(SmallVectorImpl<std::string> &InliningDecisions) const;
 };
 
 } // end namespace llvm
diff --git a/llvm/lib/IR/DiagnosticInfo.cpp b/llvm/lib/IR/DiagnosticInfo.cpp
index 342c4cbbc39d65f..bacb4c01a1342ca 100644
--- a/llvm/lib/IR/DiagnosticInfo.cpp
+++ b/llvm/lib/IR/DiagnosticInfo.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/ADT/iterator_range.h"
@@ -433,8 +434,9 @@ void llvm::diagnoseDontCall(const CallInst &CI) {
       if (MDNode *MD = CI.getMetadata("srcloc"))
         LocCookie =
             mdconst::extract<ConstantInt>(MD->getOperand(0))->getZExtValue();
-      DiagnosticInfoDontCall D(F->getName(), A.getValueAsString(), Sev,
-                               LocCookie);
+      DiagnosticInfoDontCall D(CI.getParent()->getParent()->getName(),
+                               F->getName(), A.getValueAsString(), Sev,
+                               LocCookie, CI.getMetadata("inlined.from"));
       F->getContext().diagnose(D);
     }
   }
@@ -449,3 +451,20 @@ void DiagnosticInfoDontCall::print(DiagnosticPrinter &DP) const {
   if (!getNote().empty())
     DP << ": " << getNote();
 }
+
+void DiagnosticInfoDontCall::getInliningDecisions(
+    SmallVectorImpl<std::string> &InliningDecisions) const {
+  if (!MDN)
+    return;
+
+  const MDOperand &MO = MDN->getOperand(0);
+  if (auto *MDT = dyn_cast<MDTuple>(MO)) {
+    for (const MDOperand &MO : MDT->operands()) {
+      if (auto *S = dyn_cast<MDString>(MO)) {
+        InliningDecisions.push_back(S->getString().str());
+      }
+    }
+  } else if (auto *S = dyn_cast<MDString>(MO)) {
+    InliningDecisions.push_back(S->getString().str());
+  }
+}
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 39d5f6e53c1de48..81ffc416ffd5c0a 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -2520,6 +2520,19 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
         // inlining, commonly when the callee is an intrinsic.
         if (MarkNoUnwind && !CI->doesNotThrow())
           CI->setDoesNotThrow();
+
+        const Function *Callee = CI->getCalledFunction();
+        if (Callee && (Callee->hasFnAttribute("dontcall-error") ||
+                       Callee->hasFnAttribute("dontcall-warn"))) {
+          Metadata *MD = MDString::get(CI->getContext(), CalledFunc->getName());
+          if (MDNode *N = CI->getMetadata("inlined.from")) {
+            TempMDTuple Temp = cast<MDTuple>(N)->clone();
+            Temp->push_back(MD);
+            MD = MDNode::replaceWithUniqued(std::move(Temp));
+          }
+          MDTuple *MDT = MDNode::get(CI->getContext(), {MD});
+          CI->setMetadata("inlined.from", MDT);
+        }
       }
     }
   }
diff --git a/llvm/test/Transforms/Inline/dontcall-attributes.ll b/llvm/test/Transforms/Inline/dontcall-attributes.ll
new file mode 100644
index 000000000000000..acf8c6a62aad619
--- /dev/null
+++ b/llvm/test/Transforms/Inline/dontcall-attributes.ll
@@ -0,0 +1,84 @@
+; RUN: opt -S -o - -passes=inline %s \
+; RUN:  | FileCheck %s --check-prefixes=CHECK-BOTH,CHECK
+; RUN: opt -S -o - -passes=always-inline %s \
+; RUN:  | FileCheck %s --check-prefixes=CHECK-BOTH,CHECK-ALWAYS
+
+declare void @foo() "dontcall-warn"="oh no"
+declare void @fof() "dontcall-error"="oh no"
+
+define void @bar(i32 %x) {
+  %cmp = icmp eq i32 %x, 10
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  call void @foo()
+  br label %if.end
+
+if.end:
+  ret void
+}
+
+define void @quux() {
+  call void @bar(i32 9)
+  ret void
+}
+
+; Test that @baz's call to @foo has metadata with inlining info.
+define void @baz() {
+; CHECK-LABEL: @baz(
+; CHECK-NEXT:    call void @foo(), !inlined.from !0
+;
+  call void @bar(i32 10)
+  ret void
+}
+
+; Test that @zing's call to @foo has unique metadata from @baz's call to @foo.
+define void @zing() {
+; CHECK-LABEL: @zing(
+; CHECK-NEXT:    call void @foo(), !inlined.from !1
+;
+  call void @baz()
+  ret void
+}
+
+; Same test but @fof has fn attr "dontcall-error"="..." rather than
+; "dontcall-warn"="...".
+define void @a() {
+  call void @fof()
+  ret void
+}
+define void @b() {
+; CHECK-LABEL: @b(
+; CHECK-NEXT: call void @fof(), !inlined.from !3
+  call void @a()
+  ret void
+}
+
+; Add some tests for alwaysinline.
+define void @always_callee() alwaysinline {
+  call void @fof()
+  ret void
+}
+define void @always_caller() alwaysinline {
+; CHECK-BOTH-LABEL: @always_caller(
+; CHECK-NEXT: call void @fof(), !inlined.from !4
+; CHECK-ALWAYS-NEXT: call void @fof(), !inlined.from !0
+  call void @always_callee()
+  ret void
+}
+define void @always_caller2() alwaysinline {
+; CHECK-BOTH-LABEL: @always_caller2(
+; CHECK-NEXT: call void @fof(), !inlined.from !5
+; CHECK-ALWAYS-NEXT: call void @fof(), !inlined.from !1
+  call void @always_caller()
+  ret void
+}
+
+; CHECK: !0 = !{!"bar"}
+; CHECK-NEXT: !1 = !{!2}
+; CHECK-NEXT: !2 = !{!"bar", !"baz"}
+; CHECK-NEXT: !3 = !{!"a"}
+; CHECK-NEXT: !4 = !{!"always_callee"}
+; CHECK-ALWAYS: !0 = !{!"always_callee"}
+; CHECK-ALWAYS-NEXT: !1 = !{!2}
+; CHECK-ALWAYS-NEXT: !2 = !{!"always_callee", !"always_caller"}

>From c03a2cd371acd37a0021515ff43bef42f35366e2 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Mon, 27 Nov 2023 10:09:06 -0800
Subject: [PATCH 02/12] use structured bindings

addresses https://reviews.llvm.org/D141451#inline-1445382
---
 clang/lib/CodeGen/CodeGenAction.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp
index 66e040741e2718d..e7681c339df8f91 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -800,10 +800,10 @@ void BackendConsumer::DontCallDiagHandler(const DiagnosticInfoDontCall &D) {
   SmallVector<std::string, 4> InliningDecisions;
   D.getInliningDecisions(InliningDecisions);
   InliningDecisions.push_back(D.getCaller().str());
-  for (auto Dec : llvm::enumerate(InliningDecisions))
-    Diags.Report(Dec.index() ? diag::note_fe_backend_inlined
-                             : diag::note_fe_backend_in)
-        << llvm::demangle(Dec.value());
+  for (auto [index, value] : llvm::enumerate(InliningDecisions))
+    Diags.Report(index ? diag::note_fe_backend_inlined
+                       : diag::note_fe_backend_in)
+        << llvm::demangle(value);
 }
 
 void BackendConsumer::MisExpectDiagHandler(

>From 239ab3ede24f030c40eb1e6cafc3dac6955835b6 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Mon, 27 Nov 2023 10:11:00 -0800
Subject: [PATCH 03/12] use LocCookie

addresses https://reviews.llvm.org/D141451#inline-1445409
---
 clang/lib/CodeGen/CodeGenAction.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp
index e7681c339df8f91..c734d09f65324ec 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -801,8 +801,8 @@ void BackendConsumer::DontCallDiagHandler(const DiagnosticInfoDontCall &D) {
   D.getInliningDecisions(InliningDecisions);
   InliningDecisions.push_back(D.getCaller().str());
   for (auto [index, value] : llvm::enumerate(InliningDecisions))
-    Diags.Report(index ? diag::note_fe_backend_inlined
-                       : diag::note_fe_backend_in)
+    Diags.Report(LocCookie, index ? diag::note_fe_backend_inlined
+                                  : diag::note_fe_backend_in)
         << llvm::demangle(value);
 }
 

>From 6c55bf2837bdff1ed16b67ce1c2cf806df2d1e1a Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Mon, 27 Nov 2023 10:12:22 -0800
Subject: [PATCH 04/12] fix indentation of test

addresses https://reviews.llvm.org/D141451#inline-1445383
---
 .../backend-attribute-error-warning-optimize.c     | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/clang/test/Frontend/backend-attribute-error-warning-optimize.c b/clang/test/Frontend/backend-attribute-error-warning-optimize.c
index 0bfc50ff8985c39..0e7df74b60b6e2d 100644
--- a/clang/test/Frontend/backend-attribute-error-warning-optimize.c
+++ b/clang/test/Frontend/backend-attribute-error-warning-optimize.c
@@ -23,19 +23,19 @@ void indirect(void) {
 }
 
 static inline void a(int x) {
-    if (x == 10)
-        foo(); // expected-error {{call to 'foo' declared with 'error' attribute: oh no foo}}
-               // expected-note@* {{called by function 'a'}}
-               // expected-note@* {{inlined by function 'b'}}
-               // expected-note@* {{inlined by function 'd'}}
+  if (x == 10)
+    foo(); // expected-error {{call to 'foo' declared with 'error' attribute: oh no foo}}
+           // expected-note@* {{called by function 'a'}}
+           // expected-note@* {{inlined by function 'b'}}
+           // expected-note@* {{inlined by function 'd'}}
 }
 
 static inline void b() {
-    a(10);
+  a(10);
 }
 
 void c() {
-    a(9);
+  a(9);
 }
 
 void d() {

>From 4ea1488c1ee05be81b9501781f3a53b068e82f23 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Mon, 27 Nov 2023 10:14:36 -0800
Subject: [PATCH 05/12] use < rather than -o -

Addresses https://reviews.llvm.org/D141451#inline-1445410
---
 llvm/test/Transforms/Inline/dontcall-attributes.ll | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/llvm/test/Transforms/Inline/dontcall-attributes.ll b/llvm/test/Transforms/Inline/dontcall-attributes.ll
index acf8c6a62aad619..3965f33212b20fe 100644
--- a/llvm/test/Transforms/Inline/dontcall-attributes.ll
+++ b/llvm/test/Transforms/Inline/dontcall-attributes.ll
@@ -1,7 +1,5 @@
-; RUN: opt -S -o - -passes=inline %s \
-; RUN:  | FileCheck %s --check-prefixes=CHECK-BOTH,CHECK
-; RUN: opt -S -o - -passes=always-inline %s \
-; RUN:  | FileCheck %s --check-prefixes=CHECK-BOTH,CHECK-ALWAYS
+; RUN: opt -S -passes=inline < %s | FileCheck %s --check-prefixes=CHECK-BOTH,CHECK
+; RUN: opt -S -passes=always-inline < %s | FileCheck %s --check-prefixes=CHECK-BOTH,CHECK-ALWAYS
 
 declare void @foo() "dontcall-warn"="oh no"
 declare void @fof() "dontcall-error"="oh no"

>From c4bc1cb443d0fe3a6e23776208f9544e6b991ed5 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Mon, 27 Nov 2023 10:16:24 -0800
Subject: [PATCH 06/12] fix label checks

addresses https://reviews.llvm.org/D141451#inline-1445385
---
 llvm/test/Transforms/Inline/dontcall-attributes.ll | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/test/Transforms/Inline/dontcall-attributes.ll b/llvm/test/Transforms/Inline/dontcall-attributes.ll
index 3965f33212b20fe..bc6e37702983cab 100644
--- a/llvm/test/Transforms/Inline/dontcall-attributes.ll
+++ b/llvm/test/Transforms/Inline/dontcall-attributes.ll
@@ -23,7 +23,7 @@ define void @quux() {
 
 ; Test that @baz's call to @foo has metadata with inlining info.
 define void @baz() {
-; CHECK-LABEL: @baz(
+; CHECK-LABEL: define {{[^@]+}}@baz(
 ; CHECK-NEXT:    call void @foo(), !inlined.from !0
 ;
   call void @bar(i32 10)
@@ -32,7 +32,7 @@ define void @baz() {
 
 ; Test that @zing's call to @foo has unique metadata from @baz's call to @foo.
 define void @zing() {
-; CHECK-LABEL: @zing(
+; CHECK-LABEL: define {{[^@]+}}@zing(
 ; CHECK-NEXT:    call void @foo(), !inlined.from !1
 ;
   call void @baz()
@@ -58,14 +58,14 @@ define void @always_callee() alwaysinline {
   ret void
 }
 define void @always_caller() alwaysinline {
-; CHECK-BOTH-LABEL: @always_caller(
+; CHECK-BOTH-LABEL: define {{[^@]+}}@always_caller(
 ; CHECK-NEXT: call void @fof(), !inlined.from !4
 ; CHECK-ALWAYS-NEXT: call void @fof(), !inlined.from !0
   call void @always_callee()
   ret void
 }
 define void @always_caller2() alwaysinline {
-; CHECK-BOTH-LABEL: @always_caller2(
+; CHECK-BOTH-LABEL: define {{[^@]+}}@always_caller2(
 ; CHECK-NEXT: call void @fof(), !inlined.from !5
 ; CHECK-ALWAYS-NEXT: call void @fof(), !inlined.from !1
   call void @always_caller()

>From 3dab97106cdc84b63e8d7a234ca02d37c55a421c Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Mon, 27 Nov 2023 10:17:09 -0800
Subject: [PATCH 07/12] remove dead lines from test

addresses https://reviews.llvm.org/D141451#inline-1445386
---
 llvm/test/Transforms/Inline/dontcall-attributes.ll | 2 --
 1 file changed, 2 deletions(-)

diff --git a/llvm/test/Transforms/Inline/dontcall-attributes.ll b/llvm/test/Transforms/Inline/dontcall-attributes.ll
index bc6e37702983cab..ef2ceeffa72ae43 100644
--- a/llvm/test/Transforms/Inline/dontcall-attributes.ll
+++ b/llvm/test/Transforms/Inline/dontcall-attributes.ll
@@ -25,7 +25,6 @@ define void @quux() {
 define void @baz() {
 ; CHECK-LABEL: define {{[^@]+}}@baz(
 ; CHECK-NEXT:    call void @foo(), !inlined.from !0
-;
   call void @bar(i32 10)
   ret void
 }
@@ -34,7 +33,6 @@ define void @baz() {
 define void @zing() {
 ; CHECK-LABEL: define {{[^@]+}}@zing(
 ; CHECK-NEXT:    call void @foo(), !inlined.from !1
-;
   call void @baz()
   ret void
 }

>From ba7c5070c55cd9f92fe72950a6ef32d7f5bbff7d Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Mon, 27 Nov 2023 10:27:57 -0800
Subject: [PATCH 08/12] return SmallVector

hopefully NRVO kicks in *shrug*

addresses https://reviews.llvm.org/D141451#inline-1446132
---
 clang/lib/CodeGen/CodeGenAction.cpp   |  3 +--
 llvm/include/llvm/IR/DiagnosticInfo.h |  3 +--
 llvm/lib/IR/DiagnosticInfo.cpp        | 26 ++++++++++++++------------
 3 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp
index c734d09f65324ec..6a274d32cfc0c0f 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -797,8 +797,7 @@ void BackendConsumer::DontCallDiagHandler(const DiagnosticInfoDontCall &D) {
                               : diag::warn_fe_backend_warning_attr)
       << llvm::demangle(D.getFunctionName()) << D.getNote();
 
-  SmallVector<std::string, 4> InliningDecisions;
-  D.getInliningDecisions(InliningDecisions);
+  SmallVector<std::string> InliningDecisions = D.getInliningDecisions();
   InliningDecisions.push_back(D.getCaller().str());
   for (auto [index, value] : llvm::enumerate(InliningDecisions))
     Diags.Report(LocCookie, index ? diag::note_fe_backend_inlined
diff --git a/llvm/include/llvm/IR/DiagnosticInfo.h b/llvm/include/llvm/IR/DiagnosticInfo.h
index 3f64c0acd293ed5..1d4dd3d05e268bf 100644
--- a/llvm/include/llvm/IR/DiagnosticInfo.h
+++ b/llvm/include/llvm/IR/DiagnosticInfo.h
@@ -1119,8 +1119,7 @@ class DiagnosticInfoDontCall : public DiagnosticInfo {
   static bool classof(const DiagnosticInfo *DI) {
     return DI->getKind() == DK_DontCall;
   }
-  void
-  getInliningDecisions(SmallVectorImpl<std::string> &InliningDecisions) const;
+  SmallVector<std::string> getInliningDecisions() const;
 };
 
 } // end namespace llvm
diff --git a/llvm/lib/IR/DiagnosticInfo.cpp b/llvm/lib/IR/DiagnosticInfo.cpp
index bacb4c01a1342ca..cbf5ff0a3d4d722 100644
--- a/llvm/lib/IR/DiagnosticInfo.cpp
+++ b/llvm/lib/IR/DiagnosticInfo.cpp
@@ -452,19 +452,21 @@ void DiagnosticInfoDontCall::print(DiagnosticPrinter &DP) const {
     DP << ": " << getNote();
 }
 
-void DiagnosticInfoDontCall::getInliningDecisions(
-    SmallVectorImpl<std::string> &InliningDecisions) const {
-  if (!MDN)
-    return;
-
-  const MDOperand &MO = MDN->getOperand(0);
-  if (auto *MDT = dyn_cast<MDTuple>(MO)) {
-    for (const MDOperand &MO : MDT->operands()) {
-      if (auto *S = dyn_cast<MDString>(MO)) {
-        InliningDecisions.push_back(S->getString().str());
+SmallVector<std::string> DiagnosticInfoDontCall::getInliningDecisions() const {
+  SmallVector<std::string> InliningDecisions;
+
+  if (MDN) {
+    const MDOperand &MO = MDN->getOperand(0);
+    if (auto *MDT = dyn_cast<MDTuple>(MO)) {
+      for (const MDOperand &MO : MDT->operands()) {
+        if (auto *S = dyn_cast<MDString>(MO)) {
+          InliningDecisions.push_back(S->getString().str());
+        }
       }
+    } else if (auto *S = dyn_cast<MDString>(MO)) {
+      InliningDecisions.push_back(S->getString().str());
     }
-  } else if (auto *S = dyn_cast<MDString>(MO)) {
-    InliningDecisions.push_back(S->getString().str());
   }
+
+  return InliningDecisions;
 }

>From a1496ded6a6aa43bc8d0329982156ef2f62321d2 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Mon, 27 Nov 2023 10:51:37 -0800
Subject: [PATCH 09/12] no need to support lone MDStrings; they're always
 enclosed in an MDTuple

addresses https://reviews.llvm.org/D141451#inline-1446137
---
 llvm/lib/IR/DiagnosticInfo.cpp | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/IR/DiagnosticInfo.cpp b/llvm/lib/IR/DiagnosticInfo.cpp
index cbf5ff0a3d4d722..8649d9f66aad6c7 100644
--- a/llvm/lib/IR/DiagnosticInfo.cpp
+++ b/llvm/lib/IR/DiagnosticInfo.cpp
@@ -455,18 +455,11 @@ void DiagnosticInfoDontCall::print(DiagnosticPrinter &DP) const {
 SmallVector<std::string> DiagnosticInfoDontCall::getInliningDecisions() const {
   SmallVector<std::string> InliningDecisions;
 
-  if (MDN) {
-    const MDOperand &MO = MDN->getOperand(0);
-    if (auto *MDT = dyn_cast<MDTuple>(MO)) {
-      for (const MDOperand &MO : MDT->operands()) {
-        if (auto *S = dyn_cast<MDString>(MO)) {
+  if (MDN)
+    if (auto *MDT = dyn_cast<MDTuple>(MDN->getOperand(0)))
+      for (const MDOperand &MO : MDT->operands())
+        if (auto *S = dyn_cast<MDString>(MO))
           InliningDecisions.push_back(S->getString().str());
-        }
-      }
-    } else if (auto *S = dyn_cast<MDString>(MO)) {
-      InliningDecisions.push_back(S->getString().str());
-    }
-  }
 
   return InliningDecisions;
 }

>From 066908496bdca6517215641b3da7345896e06d02 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Mon, 27 Nov 2023 10:54:43 -0800
Subject: [PATCH 10/12] use an Intanium mangled identifier in test

addresses https://reviews.llvm.org/D141451#inline-1445411
---
 llvm/test/Transforms/Inline/dontcall-attributes.ll | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/llvm/test/Transforms/Inline/dontcall-attributes.ll b/llvm/test/Transforms/Inline/dontcall-attributes.ll
index ef2ceeffa72ae43..96a4d9c95e2f770 100644
--- a/llvm/test/Transforms/Inline/dontcall-attributes.ll
+++ b/llvm/test/Transforms/Inline/dontcall-attributes.ll
@@ -39,14 +39,14 @@ define void @zing() {
 
 ; Same test but @fof has fn attr "dontcall-error"="..." rather than
 ; "dontcall-warn"="...".
-define void @a() {
+define void @_Z1av() {
   call void @fof()
   ret void
 }
-define void @b() {
-; CHECK-LABEL: @b(
+define void @_Z1bv() {
+; CHECK-LABEL: define {{[^@]+}}@_Z1bv(
 ; CHECK-NEXT: call void @fof(), !inlined.from !3
-  call void @a()
+  call void @_Z1av()
   ret void
 }
 
@@ -73,7 +73,7 @@ define void @always_caller2() alwaysinline {
 ; CHECK: !0 = !{!"bar"}
 ; CHECK-NEXT: !1 = !{!2}
 ; CHECK-NEXT: !2 = !{!"bar", !"baz"}
-; CHECK-NEXT: !3 = !{!"a"}
+; CHECK-NEXT: !3 = !{!"_Z1av"}
 ; CHECK-NEXT: !4 = !{!"always_callee"}
 ; CHECK-ALWAYS: !0 = !{!"always_callee"}
 ; CHECK-ALWAYS-NEXT: !1 = !{!2}

>From d3a221a9aea4f60244adc7d726b398abeb2775b3 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Mon, 27 Nov 2023 11:05:22 -0800
Subject: [PATCH 11/12] use const ref structured binding

addresses https://github.com/llvm/llvm-project/pull/73552/files#r1406619873
---
 clang/lib/CodeGen/CodeGenAction.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp
index 6a274d32cfc0c0f..66816e4cede5046 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -799,7 +799,7 @@ void BackendConsumer::DontCallDiagHandler(const DiagnosticInfoDontCall &D) {
 
   SmallVector<std::string> InliningDecisions = D.getInliningDecisions();
   InliningDecisions.push_back(D.getCaller().str());
-  for (auto [index, value] : llvm::enumerate(InliningDecisions))
+  for (const auto &[index, value] : llvm::enumerate(InliningDecisions))
     Diags.Report(LocCookie, index ? diag::note_fe_backend_inlined
                                   : diag::note_fe_backend_in)
         << llvm::demangle(value);

>From e7ed56d009a83f78ffe22eaae8256a766b0c6b4b Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Mon, 27 Nov 2023 11:08:49 -0800
Subject: [PATCH 12/12] s/std::string/StringRef/ for inlining decisions

addresses https://github.com/llvm/llvm-project/pull/73552/files#r1406619278
---
 clang/lib/CodeGen/CodeGenAction.cpp   | 4 ++--
 llvm/include/llvm/IR/DiagnosticInfo.h | 3 +--
 llvm/lib/IR/DiagnosticInfo.cpp        | 6 +++---
 3 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp
index 66816e4cede5046..3ff265ec5cf7123 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -797,8 +797,8 @@ void BackendConsumer::DontCallDiagHandler(const DiagnosticInfoDontCall &D) {
                               : diag::warn_fe_backend_warning_attr)
       << llvm::demangle(D.getFunctionName()) << D.getNote();
 
-  SmallVector<std::string> InliningDecisions = D.getInliningDecisions();
-  InliningDecisions.push_back(D.getCaller().str());
+  SmallVector<StringRef> InliningDecisions = D.getInliningDecisions();
+  InliningDecisions.push_back(D.getCaller());
   for (const auto &[index, value] : llvm::enumerate(InliningDecisions))
     Diags.Report(LocCookie, index ? diag::note_fe_backend_inlined
                                   : diag::note_fe_backend_in)
diff --git a/llvm/include/llvm/IR/DiagnosticInfo.h b/llvm/include/llvm/IR/DiagnosticInfo.h
index 1d4dd3d05e268bf..8f3008dab0a4dc5 100644
--- a/llvm/include/llvm/IR/DiagnosticInfo.h
+++ b/llvm/include/llvm/IR/DiagnosticInfo.h
@@ -29,7 +29,6 @@
 #include <functional>
 #include <iterator>
 #include <optional>
-#include <string>
 
 namespace llvm {
 
@@ -1119,7 +1118,7 @@ class DiagnosticInfoDontCall : public DiagnosticInfo {
   static bool classof(const DiagnosticInfo *DI) {
     return DI->getKind() == DK_DontCall;
   }
-  SmallVector<std::string> getInliningDecisions() const;
+  SmallVector<StringRef> getInliningDecisions() const;
 };
 
 } // end namespace llvm
diff --git a/llvm/lib/IR/DiagnosticInfo.cpp b/llvm/lib/IR/DiagnosticInfo.cpp
index 8649d9f66aad6c7..004028a5d430eba 100644
--- a/llvm/lib/IR/DiagnosticInfo.cpp
+++ b/llvm/lib/IR/DiagnosticInfo.cpp
@@ -452,14 +452,14 @@ void DiagnosticInfoDontCall::print(DiagnosticPrinter &DP) const {
     DP << ": " << getNote();
 }
 
-SmallVector<std::string> DiagnosticInfoDontCall::getInliningDecisions() const {
-  SmallVector<std::string> InliningDecisions;
+SmallVector<StringRef> DiagnosticInfoDontCall::getInliningDecisions() const {
+  SmallVector<StringRef> InliningDecisions;
 
   if (MDN)
     if (auto *MDT = dyn_cast<MDTuple>(MDN->getOperand(0)))
       for (const MDOperand &MO : MDT->operands())
         if (auto *S = dyn_cast<MDString>(MO))
-          InliningDecisions.push_back(S->getString().str());
+          InliningDecisions.push_back(S->getString());
 
   return InliningDecisions;
 }



More information about the cfe-commits mailing list