Skip to content

[BOLT][merge-fdata] Initialize YAML profile header #109613

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 25, 2024

Conversation

maksfb
Copy link
Contributor

@maksfb maksfb commented Sep 23, 2024

While merging profiles, some fields in the input header, e.g. HashFunction, could be uninitialized leading to a UMR. Initialize merged header with the first input header.

Fixes #109592

Summary:
While merging profiles, some fields in the input header, e.g.
HashFunction, could be uninitialized leading to a UMR. Initialize
merged header with the first input header.
@llvmbot
Copy link
Member

llvmbot commented Sep 23, 2024

@llvm/pr-subscribers-bolt

Author: Maksim Panchenko (maksfb)

Changes

Summary:
While merging profiles, some fields in the input header, e.g. HashFunction, could be uninitialized leading to a UMR. Initialize merged header with the first input header.


Full diff: https://github.com/llvm/llvm-project/pull/109613.diff

2 Files Affected:

  • (added) bolt/test/merge-fdata-uninitialized-header.test (+45)
  • (modified) bolt/tools/merge-fdata/merge-fdata.cpp (+11-1)
diff --git a/bolt/test/merge-fdata-uninitialized-header.test b/bolt/test/merge-fdata-uninitialized-header.test
new file mode 100644
index 00000000000000..53369612784117
--- /dev/null
+++ b/bolt/test/merge-fdata-uninitialized-header.test
@@ -0,0 +1,45 @@
+## Test that merge-fdata correctly handles YAML header with an uninitialized
+## fields. a.yaml does not have hash-func set and it used to crash merge-fdata.
+
+# REQUIRES: system-linux
+
+# RUN: split-file %s %t
+# RUN: not merge-fdata %t/a.yaml %t/b.yaml 2>&1 | FileCheck %s
+
+# CHECK: cannot merge profiles with different hash functions
+
+#--- a.yaml
+---
+header:
+  profile-version: 1
+  binary-name:     'a.out'
+  binary-build-id: '<unknown>'
+  profile-flags:   [ lbr ]
+  profile-origin:  branch profile reader
+  profile-events:  ''
+  dfs-order:       false
+functions:
+  - name:            'main'
+    fid:             1
+    hash:            0x50BBA3441D436491
+    exec:            1
+    nblocks:         0
+...
+#--- b.yaml
+---
+header:
+  profile-version: 1
+  binary-name:     'a.out'
+  binary-build-id: '<unknown>'
+  profile-flags:   [ lbr ]
+  profile-origin:  branch profile reader
+  profile-events:  ''
+  dfs-order:       false
+  hash-func: xxh3
+functions:
+  - name:            'main'
+    fid:             1
+    hash:            0x50BBA3441D436491
+    exec:            1
+    nblocks:         0
+...
diff --git a/bolt/tools/merge-fdata/merge-fdata.cpp b/bolt/tools/merge-fdata/merge-fdata.cpp
index b640aae808f56e..89ca46c1c0a8fa 100644
--- a/bolt/tools/merge-fdata/merge-fdata.cpp
+++ b/bolt/tools/merge-fdata/merge-fdata.cpp
@@ -145,6 +145,10 @@ void mergeProfileHeaders(BinaryProfileHeader &MergedHeader,
     errs() << "WARNING: merging profiles with different sampling events\n";
     MergedHeader.EventNames += "," + Header.EventNames;
   }
+
+  if (MergedHeader.HashFunction != Header.HashFunction)
+    report_error("merge conflict",
+                 "cannot merge profiles with different hash functions");
 }
 
 void mergeBasicBlockProfile(BinaryBasicBlockProfile &MergedBB,
@@ -386,6 +390,7 @@ int main(int argc, char **argv) {
   // Merged information for all functions.
   StringMap<BinaryFunctionProfile> MergedBFs;
 
+  bool FirstHeader = true;
   for (std::string &InputDataFilename : Inputs) {
     ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
         MemoryBuffer::getFileOrSTDIN(InputDataFilename);
@@ -409,7 +414,12 @@ int main(int argc, char **argv) {
     }
 
     // Merge the header.
-    mergeProfileHeaders(MergedHeader, BP.Header);
+    if (FirstHeader) {
+      MergedHeader = BP.Header;
+      FirstHeader = false;
+    } else {
+      mergeProfileHeaders(MergedHeader, BP.Header);
+    }
 
     // Do the function merge.
     for (BinaryFunctionProfile &BF : BP.Functions) {

Copy link
Collaborator

@kongy kongy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified that it fixed the assertion failure I am seeing.

@kongy
Copy link
Collaborator

kongy commented Sep 25, 2024

Is this change ready to be merged?

@maksfb maksfb merged commit 6fb39ac into llvm:main Sep 25, 2024
9 checks passed
Sterling-Augustine pushed a commit to Sterling-Augustine/llvm-project that referenced this pull request Sep 27, 2024
While merging profiles, some fields in the input header, e.g.
HashFunction, could be uninitialized leading to a UMR. Initialize merged
header with the first input header.

Fixes llvm#109592
@maksfb maksfb deleted the gh-fix-merge-fdata branch March 6, 2025 02:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BOLT merge-fdata crashes on assertion build
3 participants