Author: Wei Wang
Date: 2026-01-08T13:55:24-08:00
New Revision: 86b95b0c402ac8fae0fd4d2f62ad412918ad4254

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

LOG: [SampleProf] Handle coro wrapper function name canonicalization (#174881)

Fix an issue where `FunctionSamples::getCanonicalFnName` incorrectly
canonicalizes coro await suspense wrapper functions to collide with the
coro function itself. This causes the sample annotation to skip coro
function. Canonicalization strips everything comes after the first dot
(.), unless the function attribute
"sample-profile-suffix-elision-policy" is set to "selected", in which
case it strips after the known suffixes. The wrapper function name has
the suffix of ".__await_suspend_wrapper__" + await_kind. Add the
attribute to wrapper function so that the suffix is not stripped.

Added: 
    llvm/test/Transforms/SampleProfile/Inputs/coro-annotate.prof
    llvm/test/Transforms/SampleProfile/coro-annotate.ll

Modified: 
    clang/lib/CodeGen/CGCoroutine.cpp
    clang/test/CodeGenCoroutines/coro-attributes.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGCoroutine.cpp 
b/clang/lib/CodeGen/CGCoroutine.cpp
index c80bb0e004367..7282c42420657 100644
--- a/clang/lib/CodeGen/CGCoroutine.cpp
+++ b/clang/lib/CodeGen/CGCoroutine.cpp
@@ -447,6 +447,7 @@ CodeGenFunction::generateAwaitSuspendWrapper(Twine const 
&CoroName,
 
   Fn->setMustProgress();
   Fn->addFnAttr(llvm::Attribute::AttrKind::AlwaysInline);
+  Fn->addFnAttr("sample-profile-suffix-elision-policy", "selected");
 
   StartFunction(GlobalDecl(), ReturnTy, Fn, FI, args);
 

diff  --git a/clang/test/CodeGenCoroutines/coro-attributes.cpp 
b/clang/test/CodeGenCoroutines/coro-attributes.cpp
index 8f171771a8cbc..2dfb6cc052ce9 100644
--- a/clang/test/CodeGenCoroutines/coro-attributes.cpp
+++ b/clang/test/CodeGenCoroutines/coro-attributes.cpp
@@ -15,8 +15,12 @@ struct coro {
 
 // CHECK: void @_Z3foov() #[[FOO_ATTR_NUM:[0-9]+]]
 // CHECK: declare token @llvm.coro.save(ptr) #[[SAVE_ATTR_NUM:[0-9]+]]
+// CHECK: void @_Z3foov.__await_suspend_wrapper__init({{.*}}) 
#[[WRAPPER_ATTR_NUM:[0-9]+]]
+// CHECK: void @_Z3foov.__await_suspend_wrapper__await({{.*}}) 
#[[WRAPPER_ATTR_NUM:[0-9]+]]
+// CHECK: void @_Z3foov.__await_suspend_wrapper__final({{.*}}) 
#[[WRAPPER_ATTR_NUM:[0-9]+]]
 // CHECK: attributes #[[FOO_ATTR_NUM]] = { {{.*}} presplitcoroutine
 // CHECK: attributes #[[SAVE_ATTR_NUM]] = { {{.*}}nomerge
+// CHECK: attributes #[[WRAPPER_ATTR_NUM]] = { 
{{.*}}"sample-profile-suffix-elision-policy"="selected"
 coro foo() {
   co_await suspend_always{};
 }

diff  --git a/llvm/test/Transforms/SampleProfile/Inputs/coro-annotate.prof 
b/llvm/test/Transforms/SampleProfile/Inputs/coro-annotate.prof
new file mode 100644
index 0000000000000..6b9ccb2653918
--- /dev/null
+++ b/llvm/test/Transforms/SampleProfile/Inputs/coro-annotate.prof
@@ -0,0 +1,2 @@
+bar:100:13293
+ 0: 100

diff  --git a/llvm/test/Transforms/SampleProfile/coro-annotate.ll 
b/llvm/test/Transforms/SampleProfile/coro-annotate.ll
new file mode 100644
index 0000000000000..9aa85353cca28
--- /dev/null
+++ b/llvm/test/Transforms/SampleProfile/coro-annotate.ll
@@ -0,0 +1,31 @@
+; RUN: opt < %s -sample-profile-file=%S/Inputs/coro-annotate.prof 
-passes=sample-profile -S | FileCheck %s
+
+; This test checks if a coro function can correctly get sample annotation with 
the present of its await suspend wrappers.
+; Please ignore the incomplete coro function body and missing coro intrinsics 
since only the function names matter here.
+; Note: Do not change the function names. They are intentionally made to 
create a specific order in the module's ValSymTab iterator.
+
+; CHECK: define void @bar() {{.*}} !prof ![[PROF:[0-9]+]]
+; CHECK: ![[PROF]] = !{!"function_entry_count", i64 13294}
+define void @bar() #0 !dbg !4 {
+entry:
+  ret void, !dbg !9
+}
+
+define internal void @bar.__await_suspend_wrapper__init(ptr noundef nonnull 
%0, ptr noundef %1) #1 {
+entry:
+  ret void
+}
+
+attributes #0 = { presplitcoroutine "use-sample-profile" }
+attributes #1 = { "sample-profile-suffix-elision-policy"="selected" }
+
+!llvm.module.flags = !{!7, !8}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1)
+!1 = !DIFile(filename: "test.c", directory: "")
+!2 = !{}
+!4 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 1, type: 
!5, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: 
!0, retainedNodes: !2)
+!5 = !DISubroutineType(types: !2)
+!7 = !{i32 2, !"Dwarf Version", i32 4}
+!8 = !{i32 2, !"Debug Info Version", i32 3}
+!9 = !DILocation(line: 1, column: 15, scope: !4)


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to