[llvm] [mlir] [IR][PGO] Verify invalid `MD_prof` metadata on instructions (PR #145576)

Mircea Trofin via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 25 08:08:14 PDT 2025


https://github.com/mtrofin updated https://github.com/llvm/llvm-project/pull/145576

>From ebb80f3f669ae523696691b5139619b52e8cccfa Mon Sep 17 00:00:00 2001
From: Mircea Trofin <mtrofin at google.com>
Date: Tue, 24 Jun 2025 11:15:33 -0700
Subject: [PATCH 1/2] [IR][PGO] Verify invalid `MD_prof` metadata on
 instructions


>From 3c77cbcf16de136011747d6660aad1164614ed27 Mon Sep 17 00:00:00 2001
From: Mircea Trofin <mtrofin at google.com>
Date: Tue, 24 Jun 2025 11:21:14 -0700
Subject: [PATCH 2/2] change

---
 llvm/lib/IR/Verifier.cpp                      |  3 ++
 .../SimplifyCFG/preserve-branchweights.ll     | 44 +++----------------
 llvm/test/Verifier/branch-weight.ll           | 39 ++++++++++++++++
 .../Target/LLVMIR/Import/import-failure.ll    | 16 -------
 4 files changed, 47 insertions(+), 55 deletions(-)
 create mode 100644 llvm/test/Verifier/branch-weight.ll

diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 71261343b3482..ae95e3e2bff8d 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -5008,6 +5008,9 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) {
       Check(mdconst::dyn_extract<ConstantInt>(MDO),
             "!prof brunch_weights operand is not a const int");
     }
+  } else {
+    Check(ProfName == "VP", "expected either branch_weights or VP profile name",
+          MD);
   }
 }
 
diff --git a/llvm/test/Transforms/SimplifyCFG/preserve-branchweights.ll b/llvm/test/Transforms/SimplifyCFG/preserve-branchweights.ll
index fb607c72a0e35..0f78e236b4248 100644
--- a/llvm/test/Transforms/SimplifyCFG/preserve-branchweights.ll
+++ b/llvm/test/Transforms/SimplifyCFG/preserve-branchweights.ll
@@ -38,45 +38,12 @@ Z:
   ret void
 }
 
-; Make sure the metadata name string is "branch_weights" before propagating it.
-
-define void @fake_weights(i1 %a, i1 %b) {
-; CHECK-LABEL: @fake_weights(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A_NOT:%.*]] = xor i1 [[A:%.*]], true
-; CHECK-NEXT:    [[C:%.*]] = or i1 [[B:%.*]], false
-; CHECK-NEXT:    [[OR_COND:%.*]] = select i1 [[A_NOT]], i1 [[C]], i1 false
-; CHECK-NEXT:    br i1 [[OR_COND]], label [[Z:%.*]], label [[Y:%.*]], !prof [[PROF1:![0-9]+]]
-; CHECK:       common.ret:
-; CHECK-NEXT:    ret void
-; CHECK:       Y:
-; CHECK-NEXT:    call void @helper(i32 0)
-; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
-; CHECK:       Z:
-; CHECK-NEXT:    call void @helper(i32 1)
-; CHECK-NEXT:    br label [[COMMON_RET]]
-;
-entry:
-  br i1 %a, label %Y, label %X, !prof !12
-X:
-  %c = or i1 %b, false
-  br i1 %c, label %Z, label %Y, !prof !1
-
-Y:
-  call void @helper(i32 0)
-  ret void
-
-Z:
-  call void @helper(i32 1)
-  ret void
-}
-
 define void @test2(i1 %a, i1 %b) {
 ; CHECK-LABEL: @test2(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[C:%.*]] = or i1 [[B:%.*]], false
 ; CHECK-NEXT:    [[OR_COND:%.*]] = select i1 [[A:%.*]], i1 [[C]], i1 false
-; CHECK-NEXT:    br i1 [[OR_COND]], label [[Z:%.*]], label [[Y:%.*]], !prof [[PROF2:![0-9]+]]
+; CHECK-NEXT:    br i1 [[OR_COND]], label [[Z:%.*]], label [[Y:%.*]], !prof [[PROF1:![0-9]+]]
 ; CHECK:       common.ret:
 ; CHECK-NEXT:    ret void
 ; CHECK:       Y:
@@ -107,7 +74,7 @@ define void @test3(i1 %a, i1 %b) {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[C:%.*]] = or i1 [[B:%.*]], false
 ; CHECK-NEXT:    [[OR_COND:%.*]] = select i1 [[A:%.*]], i1 [[C]], i1 false
-; CHECK-NEXT:    br i1 [[OR_COND]], label [[Z:%.*]], label [[Y:%.*]], !prof [[PROF1]]
+; CHECK-NEXT:    br i1 [[OR_COND]], label [[Z:%.*]], label [[Y:%.*]], !prof [[PROF2:![0-9]+]]
 ; CHECK:       common.ret:
 ; CHECK-NEXT:    ret void
 ; CHECK:       Y:
@@ -138,7 +105,7 @@ define void @test4(i1 %a, i1 %b) {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[C:%.*]] = or i1 [[B:%.*]], false
 ; CHECK-NEXT:    [[OR_COND:%.*]] = select i1 [[A:%.*]], i1 [[C]], i1 false
-; CHECK-NEXT:    br i1 [[OR_COND]], label [[Z:%.*]], label [[Y:%.*]], !prof [[PROF1]]
+; CHECK-NEXT:    br i1 [[OR_COND]], label [[Z:%.*]], label [[Y:%.*]], !prof [[PROF2]]
 ; CHECK:       common.ret:
 ; CHECK-NEXT:    ret void
 ; CHECK:       Y:
@@ -1120,7 +1087,6 @@ exit:
 !9 = !{!"branch_weights", i32 7, i32 6}
 !10 = !{!"branch_weights", i32 672646, i32 21604207}
 !11 = !{!"branch_weights", i32 6960, i32 21597248}
-!12 = !{!"these_are_not_the_branch_weights_you_are_looking_for", i32 3, i32 5}
 !13 = !{!"branch_weights", i32 2, i32 3}
 !14 = !{!"branch_weights", i32 4, i32 7}
 !15 = !{!"branch_weights", i32 99, i32 1}
@@ -1136,8 +1102,8 @@ exit:
 ; CHECK: attributes #[[ATTR2:[0-9]+]] = { noredzone nounwind ssp memory(none) }
 ;.
 ; CHECK: [[PROF0]] = !{!"branch_weights", i32 5, i32 11}
-; CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 3}
-; CHECK: [[PROF2]] = !{!"branch_weights", i32 1, i32 5}
+; CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 5}
+; CHECK: [[PROF2]] = !{!"branch_weights", i32 1, i32 3}
 ; CHECK: [[PROF3]] = !{!"branch_weights", i32 7, i32 1, i32 2}
 ; CHECK: [[PROF4]] = !{!"branch_weights", i32 49, i32 12, i32 24, i32 35}
 ; CHECK: [[PROF5]] = !{!"branch_weights", i32 11, i32 5}
diff --git a/llvm/test/Verifier/branch-weight.ll b/llvm/test/Verifier/branch-weight.ll
new file mode 100644
index 0000000000000..e3b0f340e31bc
--- /dev/null
+++ b/llvm/test/Verifier/branch-weight.ll
@@ -0,0 +1,39 @@
+; Test MD_prof validation
+
+; RUN: split-file %s %t
+; RUN: opt -passes=verify %t/valid.ll --disable-output
+; RUN: not opt -passes=verify %t/invalid1.ll --disable-output 2>&1 | FileCheck %s
+; RUN: not opt -passes=verify %t/invalid2.ll --disable-output 2>&1 | FileCheck %s
+
+;--- valid.ll
+define void @test(i1 %0) {
+  br i1 %0, label %2, label %3, !prof !0
+2:
+  ret void
+3:
+  ret void
+}
+!0 = !{!"branch_weights", i32 1, i32 2}
+
+;--- invalid1.ll
+define void @test(i1 %0) {
+  br i1 %0, label %2, label %3, !prof !0
+2:
+  ret void
+3:
+  ret void
+}
+!0 = !{!"invalid", i32 1, i32 2}
+
+;--- invalid2.ll
+define void @test(i1 %0) {
+  br i1 %0, label %2, label %3, !prof !0
+2:
+  ret void
+3:
+  ret void
+}
+
+!0 = !{!"function_entry_count", i32 1}
+
+; CHECK: expected either branch_weights or VP profile name
diff --git a/mlir/test/Target/LLVMIR/Import/import-failure.ll b/mlir/test/Target/LLVMIR/Import/import-failure.ll
index a05a2b4bd4507..d48be66f2063e 100644
--- a/mlir/test/Target/LLVMIR/Import/import-failure.ll
+++ b/mlir/test/Target/LLVMIR/Import/import-failure.ll
@@ -258,22 +258,6 @@ end:
 
 ; // -----
 
-; CHECK:      <unknown>
-; CHECK-SAME: warning: expected function_entry_count to be attached to a function
-; CHECK:      warning: unhandled metadata: !0 = !{!"function_entry_count", i64 42}
-define void @cond_br(i1 %arg) {
-entry:
-  br i1 %arg, label %bb1, label %bb2, !prof !0
-bb1:
-  ret void
-bb2:
-  ret void
-}
-
-!0 = !{!"function_entry_count", i64 42}
-
-; // -----
-
 ; CHECK:      <unknown>
 ; CHECK-SAME: warning: dropped instruction: call void @llvm.experimental.noalias.scope.decl(metadata !0)
 define void @unused_scope() {



More information about the llvm-commits mailing list