[llvm] 79c62ef - [Metadata][profcheck] Handle identical MDNodes in getMergedProfMetadata (#175701)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 14 12:15:16 PST 2026


Author: Snehasish Kumar
Date: 2026-01-14T12:15:12-08:00
New Revision: 79c62efef6f421679038b2b545582180dd2b775a

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

LOG: [Metadata][profcheck] Handle identical MDNodes in getMergedProfMetadata (#175701)

This fixes a bug where !prof metadata was dropped from SelectInsts when GVN simplified/merged them. Guarded by -profcheck-disable-metadata-fixes. Exposed by the tests in Transforms/SampleProfile.

Added: 
    

Modified: 
    llvm/lib/IR/Metadata.cpp
    llvm/unittests/IR/MetadataTest.cpp
    llvm/utils/profcheck-xfail.txt

Removed: 
    


################################################################################
diff  --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 1add0c7930bc9..326abd87ddae9 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -46,6 +46,8 @@
 #include "llvm/IR/Type.h"
 #include "llvm/IR/Value.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/CommandLine.h"
+
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/ModRef.h"
@@ -58,6 +60,10 @@
 
 using namespace llvm;
 
+namespace llvm {
+extern cl::opt<bool> ProfcheckDisableMetadataFixes;
+}
+
 MetadataAsValue::MetadataAsValue(Type *Ty, Metadata *MD)
     : Value(Ty, MetadataAsValueVal), MD(MD) {
   track();
@@ -1255,6 +1261,9 @@ MDNode *MDNode::getMergedProfMetadata(MDNode *A, MDNode *B,
       BCall->getCalledFunction())
     return mergeDirectCallProfMetadata(A, B, AInstr, BInstr);
 
+  if (A == B && !ProfcheckDisableMetadataFixes)
+    return A;
+
   // The rest of the cases are not implemented but could be added
   // when there are use cases.
   return nullptr;

diff  --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index 85c79d13ae7ce..5b4935f8ba88f 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -5463,6 +5463,59 @@ TEST_F(MDTupleAllocationTest, Tracking2) {
   EXPECT_EQ(A->getOperand(2), Value2);
 }
 
+TEST_F(MDNodeTest, MergedProfMetadata) {
+  // Check that identical profile metadata is merged correctly.
+  Metadata *Ops[] = {
+      ConstantAsMetadata::get(ConstantInt::get(Context, APInt(32, 1))),
+      ConstantAsMetadata::get(ConstantInt::get(Context, APInt(32, 10))),
+      ConstantAsMetadata::get(ConstantInt::get(Context, APInt(32, 20)))};
+  MDNode *Prof = MDNode::get(Context, Ops);
+
+  // Create instructions to pass to getMergedProfMetadata.
+  // It requires the instructions to be of a supported type (e.g., SelectInst).
+  Value *C = ConstantInt::get(Context, APInt(1, 1));
+  Value *V1 = ConstantInt::get(Context, APInt(32, 1));
+  Value *V2 = ConstantInt::get(Context, APInt(32, 2));
+  std::unique_ptr<SelectInst> SI1(SelectInst::Create(C, V1, V2));
+  std::unique_ptr<SelectInst> SI2(SelectInst::Create(C, V1, V2));
+
+  SI1->setMetadata(LLVMContext::MD_prof, Prof);
+  SI2->setMetadata(LLVMContext::MD_prof, Prof);
+
+  MDNode *Merged =
+      MDNode::getMergedProfMetadata(Prof, Prof, SI1.get(), SI2.get());
+  EXPECT_EQ(Merged, Prof);
+}
+
+TEST_F(MDNodeTest, MergedProfMetadata_CallInst) {
+  // Check that identical profile metadata on CallInsts is SUMMED, not
+  // preserved.
+  Metadata *Ops[] = {
+      MDString::get(Context, "branch_weights"),
+      ConstantAsMetadata::get(ConstantInt::get(Context, APInt(32, 10)))};
+  MDNode *Prof = MDNode::get(Context, Ops);
+
+  // Create two CallInsts.
+  FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), false);
+  std::unique_ptr<CallInst> CI1(
+      CallInst::Create(FTy, getFunction("f"), ArrayRef<Value *>()));
+  std::unique_ptr<CallInst> CI2(
+      CallInst::Create(FTy, getFunction("f"), ArrayRef<Value *>()));
+
+  CI1->setMetadata(LLVMContext::MD_prof, Prof);
+  CI2->setMetadata(LLVMContext::MD_prof, Prof);
+
+  MDNode *Merged =
+      MDNode::getMergedProfMetadata(Prof, Prof, CI1.get(), CI2.get());
+
+  // Expect merged node to be 
diff erent (summed weights).
+  EXPECT_NE(Merged, Prof);
+  // Verify value is 20.
+  ASSERT_EQ(Merged->getNumOperands(), 2u);
+  ConstantInt *W = mdconst::extract<ConstantInt>(Merged->getOperand(1));
+  EXPECT_EQ(W->getZExtValue(), 20u);
+}
+
 #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) && !defined(GTEST_HAS_SEH)
 typedef MetadataTest MDTupleAllocationDeathTest;
 TEST_F(MDTupleAllocationDeathTest, ResizeRejected) {

diff  --git a/llvm/utils/profcheck-xfail.txt b/llvm/utils/profcheck-xfail.txt
index 564fbf3d00a48..3a1a26dfd8840 100644
--- a/llvm/utils/profcheck-xfail.txt
+++ b/llvm/utils/profcheck-xfail.txt
@@ -505,8 +505,6 @@ Transforms/PreISelIntrinsicLowering/AArch64/expand-exp.ll
 Transforms/PreISelIntrinsicLowering/AArch64/expand-log.ll
 Transforms/PreISelIntrinsicLowering/PowerPC/memset-pattern.ll
 Transforms/PreISelIntrinsicLowering/RISCV/memset-pattern.ll
-Transforms/SampleProfile/pseudo-probe-profile-mismatch-thinlto.ll
-Transforms/SampleProfile/remarks-hotness.ll
 Transforms/ScalarizeMaskedMemIntrin/AArch64/expand-masked-load.ll
 Transforms/ScalarizeMaskedMemIntrin/AArch64/expand-masked-store.ll
 Transforms/ScalarizeMaskedMemIntrin/AArch64/streaming-compatible-expand-masked-gather-scatter.ll


        


More information about the llvm-commits mailing list