[llvm] [Verifier] Only accept noundef metadata on loads and update metadata tests (PR #204922)

Nikolas Klauser via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 20 05:49:35 PDT 2026


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/204922

>From f87044ebadb17aac8dd4f3c2adcbade4f5e6cca2 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sat, 20 Jun 2026 13:42:42 +0200
Subject: [PATCH 1/3] [Verifier] Reject noundef metadata on invalid
 instructions and update metadata tests

---
 llvm/lib/IR/Verifier.cpp                 |   5 +
 llvm/test/Verifier/nofpclass-metadata.ll | 104 ++++-----------
 llvm/test/Verifier/nonnull-metadata.ll   |  16 +++
 llvm/test/Verifier/nonnull_metadata.ll   |  21 ---
 llvm/test/Verifier/noundef-metadata.ll   |  12 ++
 llvm/test/Verifier/range-1.ll            | 163 -----------------------
 llvm/test/Verifier/range-metadata.ll     |  66 +++++++++
 7 files changed, 128 insertions(+), 259 deletions(-)
 create mode 100644 llvm/test/Verifier/nonnull-metadata.ll
 delete mode 100644 llvm/test/Verifier/nonnull_metadata.ll
 create mode 100644 llvm/test/Verifier/noundef-metadata.ll
 delete mode 100644 llvm/test/Verifier/range-1.ll
 create mode 100644 llvm/test/Verifier/range-metadata.ll

diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 14b1f7d799ea9..bb07ebac84cd7 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -6026,6 +6026,11 @@ void Verifier::visitInstruction(Instruction &I) {
     Check(MD->getNumOperands() == 0, "nonnull metadata must be empty", &I);
   }
 
+  if (MDNode *MD = I.getMetadata(LLVMContext::MD_noundef)) {
+    Check(isa<LoadInst>(I), "noundef applies only to load instructions", &I);
+    Check(MD->getNumOperands() == 0, "noundef metadata must be empty", &I);
+  }
+
   if (MDNode *MD = I.getMetadata(LLVMContext::MD_dereferenceable))
     visitDereferenceableMetadata(I, MD);
 
diff --git a/llvm/test/Verifier/nofpclass-metadata.ll b/llvm/test/Verifier/nofpclass-metadata.ll
index 09b30ea9c7908..b301e9f90617e 100644
--- a/llvm/test/Verifier/nofpclass-metadata.ll
+++ b/llvm/test/Verifier/nofpclass-metadata.ll
@@ -1,91 +1,45 @@
 ; RUN: not llvm-as -disable-output %s 2>&1 | FileCheck %s
 
-; CHECK: nofpclass must have exactly one entry
-; CHECK-NEXT: !0 = !{}
-define float @md_missing_value(ptr %ptr) {
-  %load = load float, ptr %ptr, align 4, !nofpclass !{}
-  ret float %load
-}
+declare float @func()
 
-; CHECK: nofpclass must have exactly one entry
-; CHECK-NEXT: !1 = !{i32 1, i32 2}
-define float @md_too_many_entries(ptr %ptr) {
-  %load = load float, ptr %ptr, align 4, !nofpclass !{i32 1, i32 2}
-  ret float %load
-}
+%struct = type { i32, float }
 
-; CHECK: nofpclass entry must be a constant i32
-; CHECK: !2 = !{i64 1}
-define float @md_is_i64(ptr %ptr) {
-  %load = load float, ptr %ptr, align 4, !nofpclass !{i64 1}
-  ret float %load
-}
+define void @md_missing_value(ptr %ptr) {
+  ; CHECK: nofpclass is only for loads
+  call float @func(), !nofpclass !{i32 3}
 
-; CHECK: nofpclass entry must be a constant i32
-; CHECK-NEXT: !3 = !{float 1.000000e+00}
-define float @md_is_float(ptr %ptr) {
-  %load = load float, ptr %ptr, align 4, !nofpclass !{float 1.0}
-  ret float %load
-}
+  ; CHECK: nofpclass only applies to floating-point typed loads
+  load i32, ptr %ptr, align 4, !nofpclass !{i32 3}
 
-; CHECK: nofpclass entry must be a constant i32
-; CHECK-NEXT: !4 = !{!"foo"}
-define float @md_is_string(ptr %ptr) {
-  %load = load float, ptr %ptr, align 4, !nofpclass !{!"foo"}
-  ret float %load
-}
+  ; CHECK: nofpclass only applies to floating-point typed loads
+  load <2 x i32>, ptr %ptr, align 8, !nofpclass !{i32 3}
 
-; CHECK: nofpclass entry must be a constant i32
-; CHECK-NEXT: !5 = !{ptr @md_is_ptr}
-define float @md_is_ptr(ptr %ptr) {
-  %load = load float, ptr %ptr, align 4, !nofpclass !{ptr @md_is_ptr}
-  ret float %load
-}
+  ; CHECK: nofpclass only applies to floating-point typed loads
+  load %struct, ptr %ptr, align 4, !nofpclass !{i32 3}
 
-; CHECK: 'nofpclass' must have at least one test bit set
-; CHECK-NEXT: !6 = !{i32 0}
-; CHECK-NEXT: %load = load float, ptr %ptr, align 4, !nofpclass !6
-  define float @md_is_zero_val(ptr %ptr) {
-  %load = load float, ptr %ptr, align 4, !nofpclass !{i32 0}
-  ret float %load
-}
+  ; CHECK: nofpclass must have exactly one entry
+  %load = load float, ptr %ptr, align 4, !nofpclass !{}
 
-; CHECK: Invalid value for 'nofpclass' test mask
-; CHECK-NEXT: !7 = !{i32 1024}
-; CHECK-NEXT: %load = load float, ptr %ptr, align 4, !nofpclass !7
-define float @md_is_out_of_bounds(ptr %ptr) {
-  %load = load float, ptr %ptr, align 4, !nofpclass !{i32 1024}
-  ret float %load
-}
+  ; CHECK: nofpclass must have exactly one entry
+  load float, ptr %ptr, align 4, !nofpclass !{i32 1, i32 2}
 
-declare float @func()
+  ; CHECK: nofpclass entry must be a constant i32
+  load float, ptr %ptr, align 4, !nofpclass !{i64 1}
 
-; CHECK: nofpclass is only for loads
-; CHECK-NEXT: %result = call float @func(), !nofpclass !8
-define float @not_load(ptr %ptr) {
-  %result = call float @func(), !nofpclass !{i32 3}
-  ret float %result
-}
+  ; CHECK: nofpclass entry must be a constant i32
+  load float, ptr %ptr, align 4, !nofpclass !{float 1.0}
 
-; CHECK: nofpclass only applies to floating-point typed loads
-; CHECK-NEXT: %load = load i32, ptr %ptr, align 4, !nofpclass !8
-define i32 @load_int(ptr %ptr) {
-  %load = load i32, ptr %ptr, align 4, !nofpclass !{i32 3}
-  ret i32 %load
-}
+  ; CHECK: nofpclass entry must be a constant i32
+  load float, ptr %ptr, align 4, !nofpclass !{!"foo"}
 
-; CHECK: nofpclass only applies to floating-point typed loads
-; CHECK-NEXT: %load = load <2 x i32>, ptr %ptr, align 8, !nofpclass !8
-define <2 x i32> @load_int_vec(ptr %ptr) {
-  %load = load <2 x i32>, ptr %ptr, align 8, !nofpclass !{i32 3}
-  ret <2 x i32> %load
-}
+  ; CHECK: nofpclass entry must be a constant i32
+  load float, ptr %ptr, align 4, !nofpclass !{ptr @md_is_ptr}
 
-%struct = type { i32, float }
+  ; CHECK: 'nofpclass' must have at least one test bit set
+  load float, ptr %ptr, align 4, !nofpclass !{i32 0}
+
+  ; CHECK: Invalid value for 'nofpclass' test mask
+  load float, ptr %ptr, align 4, !nofpclass !{i32 1024}
 
-; CHECK: nofpclass only applies to floating-point typed loads
-; CHECK-NEXT: %load = load %struct, ptr %ptr, align 4, !nofpclass !8
-define %struct @load_hetero_struct(ptr %ptr) {
-  %load = load %struct, ptr %ptr, align 4, !nofpclass !{i32 3}
-  ret %struct %load
+  ret void
 }
diff --git a/llvm/test/Verifier/nonnull-metadata.ll b/llvm/test/Verifier/nonnull-metadata.ll
new file mode 100644
index 0000000000000..0572dcee4d012
--- /dev/null
+++ b/llvm/test/Verifier/nonnull-metadata.ll
@@ -0,0 +1,16 @@
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+
+declare ptr @dummy()
+
+define void @test(ptr %p) {
+  ; CHECK: nonnull applies only to pointer types
+  load i32, ptr %p, !nonnull !{}
+
+  ; CHECK: nonnull applies only to load instructions, use attributes for calls or invokes
+  call ptr @dummy(), !nonnull !{}
+
+  ; CHECK: nonnull metadata must be empty
+  load ptr, ptr %p, !nonnull !{i32 0}
+
+  ret void
+}
diff --git a/llvm/test/Verifier/nonnull_metadata.ll b/llvm/test/Verifier/nonnull_metadata.ll
deleted file mode 100644
index 9ef67dc163c59..0000000000000
--- a/llvm/test/Verifier/nonnull_metadata.ll
+++ /dev/null
@@ -1,21 +0,0 @@
-; RUN: not llvm-as < %s 2>&1 | FileCheck %s
-
-declare ptr @dummy()
-
-; CHECK: nonnull applies only to pointer types
-define void @test_not_pointer(ptr %p) {
-  load i32, ptr %p, !nonnull !{}
-  ret void
-}
-
-; CHECK: nonnull applies only to load instructions, use attributes for calls or invokes
-define void @test_not_load() {
-  call ptr @dummy(), !nonnull !{}
-  ret void
-}
-
-; CHECK: nonnull metadata must be empty
-define void @test_invalid_arg(ptr %p) {
-  load ptr, ptr %p, !nonnull !{i32 0}
-  ret void
-}
diff --git a/llvm/test/Verifier/noundef-metadata.ll b/llvm/test/Verifier/noundef-metadata.ll
new file mode 100644
index 0000000000000..9d5e959e9fc32
--- /dev/null
+++ b/llvm/test/Verifier/noundef-metadata.ll
@@ -0,0 +1,12 @@
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+
+define void @test(ptr %ptr) {
+entry:
+  ; This one is valid
+  load i32, ptr %ptr, !noundef !{}
+  ; CHECK: noundef metadata must be empty
+  load i32, ptr %ptr, !noundef !{i32 0}
+  ; CHECK: noundef applies only to load instructions
+  store i32 0, ptr %ptr, !noundef !{}
+  ret void
+}
diff --git a/llvm/test/Verifier/range-1.ll b/llvm/test/Verifier/range-1.ll
deleted file mode 100644
index d81f3a430749a..0000000000000
--- a/llvm/test/Verifier/range-1.ll
+++ /dev/null
@@ -1,163 +0,0 @@
-; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
-
-define void @f1(ptr %x) {
-entry:
-  store i8 0, ptr %x, align 1, !range !0
-  ret void
-}
-!0 = !{i8 0, i8 1}
-; CHECK: Ranges are only for loads, calls and invokes!
-; CHECK-NEXT: store i8 0, ptr %x, align 1, !range !0
-
-define i8 @f2(ptr %x) {
-entry:
-  %y = load i8, ptr %x, align 1, !range !1
-  ret i8 %y
-}
-!1 = !{}
-; CHECK: It should have at least one range!
-
-define i8 @f3(ptr %x) {
-entry:
-  %y = load i8, ptr %x, align 1, !range !2
-  ret i8 %y
-}
-!2 = !{i8 0}
-; CHECK: Unfinished range!
-
-define i8 @f4(ptr %x) {
-entry:
-  %y = load i8, ptr %x, align 1, !range !3
-  ret i8 %y
-}
-!3 = !{double 0.0, i8 0}
-; CHECK: The lower limit must be an integer!
-
-define i8 @f5(ptr %x) {
-entry:
-  %y = load i8, ptr %x, align 1, !range !4
-  ret i8 %y
-}
-!4 = !{i8 0, double 0.0}
-; CHECK: The upper limit must be an integer!
-
-define i8 @f6(ptr %x) {
-entry:
-  %y = load i8, ptr %x, align 1, !range !5
-  ret i8 %y
-}
-!5 = !{i32 0, i8 0}
-; CHECK: Range pair types must match!
-; CHECK:  %y = load
-
-define i8 @f7(ptr %x) {
-entry:
-  %y = load i8, ptr %x, align 1, !range !6
-  ret i8 %y
-}
-!6 = !{i8 0, i32 0}
-; CHECK: Range pair types must match!
-; CHECK:  %y = load
-
-define i8 @f8(ptr %x) {
-entry:
-  %y = load i8, ptr %x, align 1, !range !7
-  ret i8 %y
-}
-!7 = !{i32 0, i32 0}
-; CHECK: Range types must match instruction type!
-; CHECK:  %y = load
-
-define i8 @f9(ptr %x) {
-entry:
-  %y = load i8, ptr %x, align 1, !range !8
-  ret i8 %y
-}
-!8 = !{i8 0, i8 0}
-; CHECK: Range must not be empty!
-
-define i8 @f10(ptr %x) {
-entry:
-  %y = load i8, ptr %x, align 1, !range !9
-  ret i8 %y
-}
-!9 = !{i8 0, i8 2, i8 1, i8 3}
-; CHECK: Intervals are overlapping
-
-define i8 @f11(ptr %x) {
-entry:
-  %y = load i8, ptr %x, align 1, !range !10
-  ret i8 %y
-}
-!10 = !{i8 0, i8 2, i8 2, i8 3}
-; CHECK: Intervals are contiguous
-
-define i8 @f12(ptr %x) {
-entry:
-  %y = load i8, ptr %x, align 1, !range !11
-  ret i8 %y
-}
-!11 = !{i8 1, i8 2, i8 -1, i8 0}
-; CHECK: Intervals are not in order
-
-define i8 @f13(ptr %x) {
-entry:
-  %y = load i8, ptr %x, align 1, !range !12
-  ret i8 %y
-}
-!12 = !{i8 1, i8 3, i8 5, i8 1}
-; CHECK: Intervals are contiguous
-
-define i8 @f14(ptr %x) {
-entry:
-  %y = load i8, ptr %x, align 1, !range !13
-  ret i8 %y
-}
-!13 = !{i8 1, i8 3, i8 5, i8 2}
-; CHECK: Intervals are overlapping
-
-define i8 @f15(ptr %x) {
-entry:
-  %y = load i8, ptr %x, align 1, !range !14
-  ret i8 %y
-}
-!14 = !{i8 10, i8 1, i8 12, i8 13}
-; CHECK: Intervals are overlapping
-
-define i8 @f16(ptr %x) {
-entry:
-  %y = load i8, ptr %x, align 1, !range !16
-  ret i8 %y
-}
-!16 = !{i8 1, i8 3, i8 4, i8 5, i8 6, i8 2}
-; CHECK: Intervals are overlapping
-
-define i8 @f17(ptr %x) {
-entry:
-  %y = load i8, ptr %x, align 1, !range !17
-  ret i8 %y
-}
-!17 = !{i8 1, i8 3, i8 4, i8 5, i8 6, i8 1}
-; CHECK: Intervals are contiguous
-
-define i8 @f18() {
-entry:
-  %y = call i8 undef(), !range !18
-  ret i8 %y
-}
-!18 = !{}
-; CHECK: It should have at least one range!
-
-define <2 x i8> @vector_range_wrong_type(ptr %x) {
-  %y = load <2 x i8>, ptr %x, !range !19
-  ret <2 x i8> %y
-}
-!19 = !{i16 0, i16 10}
-; CHECK: Range types must match instruction type!
-
-define i32 @range_assert(ptr %x) {
-  %y = load i32, ptr %x, !range !20
-  ret i32 %y
-}
-; CHECK: The upper and lower limits cannot be the same value{{$}}
-!20 = !{i32 123, i32 123}
diff --git a/llvm/test/Verifier/range-metadata.ll b/llvm/test/Verifier/range-metadata.ll
new file mode 100644
index 0000000000000..367b21283ff98
--- /dev/null
+++ b/llvm/test/Verifier/range-metadata.ll
@@ -0,0 +1,66 @@
+; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
+
+define void @f1(ptr %x) {
+entry:
+  ; CHECK: Ranges are only for loads, calls and invokes!
+  store i8 0, ptr %x, align 1, !range !{i8 0, i8 1}
+
+  ; CHECK: It should have at least one range!
+  load i8, ptr %x, align 1, !range !{}
+
+  ; CHECK: Unfinished range!
+  load i8, ptr %x, align 1, !range !{i8 0}
+
+  ; CHECK: The lower limit must be an integer!
+  load i8, ptr %x, align 1, !range !{double 0.0, i8 0}
+
+  ; CHECK: The upper limit must be an integer!
+  load i8, ptr %x, align 1, !range !{i8 0, double 0.0}
+
+  ; CHECK: Range pair types must match!
+  load i8, ptr %x, align 1, !range !5
+
+  ; CHECK: Range pair types must match!
+  load i8, ptr %x, align 1, !range !{i8 0, i32 0}
+
+  ; CHECK: Range types must match instruction type!
+  load i8, ptr %x, align 1, !range !{i32 0, i32 0}
+
+  ; CHECK: Range must not be empty!
+  load i8, ptr %x, align 1, !range !{i8 0, i8 0}
+
+  ; CHECK: Intervals are overlapping
+  load i8, ptr %x, align 1, !range !{i8 0, i8 2, i8 1, i8 3}
+
+  ; CHECK: Intervals are overlapping
+  load i8, ptr %x, align 1, !range !{i8 1, i8 3, i8 5, i8 2}
+
+  ; CHECK: Intervals are overlapping
+  load i8, ptr %x, align 1, !range !{i8 10, i8 1, i8 12, i8 13}
+
+  ; CHECK: Intervals are overlapping
+  load i8, ptr %x, align 1, !range !{i8 1, i8 3, i8 4, i8 5, i8 6, i8 2}
+
+  ; CHECK: Intervals are contiguous
+  load i8, ptr %x, align 1, !range !{i8 0, i8 2, i8 2, i8 3}
+
+  ; CHECK: Intervals are contiguous
+  load i8, ptr %x, align 1, !range !{i8 1, i8 3, i8 5, i8 1}
+
+  ; CHECK: Intervals are contiguous
+  load i8, ptr %x, align 1, !range !{i8 1, i8 3, i8 4, i8 5, i8 6, i8 1}
+
+  ; CHECK: Intervals are not in order
+  load i8, ptr %x, align 1, !range !{i8 1, i8 2, i8 -1, i8 0}
+
+  ; CHECK: It should have at least one range!
+  call i8 undef(), !range !{}
+
+  ; CHECK: Range types must match instruction type!
+  load <2 x i8>, ptr %x, !range !{i16 0, i16 10}
+
+  ; CHECK: The upper and lower limits cannot be the same value{{$}}
+  load i32, ptr %x, !range !{i32 123, i32 123}
+
+  ret void
+}

>From cd55e925c012a79dd0c94a370caa8ffa454dd43c Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sat, 20 Jun 2026 14:47:44 +0200
Subject: [PATCH 2/3] CI fixes

---
 .../AArch64/lower-range-metadata-func-call.ll    |  6 +++---
 llvm/test/CodeGen/X86/legalize-vec-assertzext.ll |  4 ++--
 .../AtomicExpand/AMDGPU/expand-atomic-i16.ll     |  8 ++++----
 .../InstCombine/simplify-demanded-fpclass-fma.ll | 10 +++++-----
 .../simplify-demanded-fpclass-maximum.ll         |  2 +-
 .../simplify-demanded-fpclass-maximumnum.ll      |  2 +-
 .../simplify-demanded-fpclass-maxnum.ll          |  2 +-
 .../simplify-demanded-fpclass-minimum.ll         |  2 +-
 .../simplify-demanded-fpclass-minimumnum.ll      |  2 +-
 .../simplify-demanded-fpclass-minnum.ll          |  2 +-
 llvm/test/Verifier/nofpclass-metadata.ll         |  4 ++--
 llvm/test/Verifier/range-metadata.ll             |  8 +++++---
 llvm/test/tools/llubi/metadata.ll                | 16 ++++++++--------
 13 files changed, 35 insertions(+), 33 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll b/llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll
index eb190c486dc15..04cdc2f151218 100644
--- a/llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll
+++ b/llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll
@@ -10,7 +10,7 @@ define i32 @test_call_known_max_range() #0 {
 ; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
 ; CHECK-NEXT:    ret
 entry:
-  %id = tail call i32 @foo(), !range !0, !noundef !{}
+  %id = tail call i32 @foo(), !range !0 !{}
   %and = and i32 %id, 1023
   ret i32 %and
 }
@@ -24,7 +24,7 @@ define i32 @test_call_known_trunc_1_bit_range() #0 {
 ; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
 ; CHECK-NEXT:    ret
 entry:
-  %id = tail call i32 @foo(), !range !0, !noundef !{}
+  %id = tail call i32 @foo(), !range !0 !{}
   %and = and i32 %id, 511
   ret i32 %and
 }
@@ -38,7 +38,7 @@ define i32 @test_call_known_max_range_m1() #0 {
 ; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
 ; CHECK-NEXT:    ret
 entry:
-  %id = tail call i32 @foo(), !range !1, !noundef !{}
+  %id = tail call i32 @foo(), !range !1 !{}
   %and = and i32 %id, 255
   ret i32 %and
 }
diff --git a/llvm/test/CodeGen/X86/legalize-vec-assertzext.ll b/llvm/test/CodeGen/X86/legalize-vec-assertzext.ll
index 1799dd3832aad..b1d8243f26a0f 100644
--- a/llvm/test/CodeGen/X86/legalize-vec-assertzext.ll
+++ b/llvm/test/CodeGen/X86/legalize-vec-assertzext.ll
@@ -11,7 +11,7 @@ define i64 @split_assertzext(ptr %x) nounwind {
 ; CHECK-NEXT:    popq %rcx
 ; CHECK-NEXT:    vzeroupper
 ; CHECK-NEXT:    retq
-  %e = call <16 x i64> @test(), !range !0, !noundef !{}
+  %e = call <16 x i64> @test(), !range !0
   %d = extractelement <16 x i64> %e, i32 15
   ret i64 %d
 }
@@ -29,7 +29,7 @@ define i64 @widen_assertzext(ptr %x) nounwind {
 ; CHECK-NEXT:    popq %rcx
 ; CHECK-NEXT:    vzeroupper
 ; CHECK-NEXT:    retq
-  %e = call <7 x i64> @test2(), !range !0, !noundef !{}
+  %e = call <7 x i64> @test2(), !range !0
   %d = extractelement <7 x i64> %e, i32 6
   ret i64 %d
 }
diff --git a/llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomic-i16.ll b/llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomic-i16.ll
index c340e6e75766e..c6a54027c481e 100644
--- a/llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomic-i16.ll
+++ b/llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomic-i16.ll
@@ -253,7 +253,7 @@ define i16 @test_atomicrmw_and_i16_global_agent_drop_md(ptr addrspace(1) %ptr, i
 ; R600-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]]
 ; R600-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
 ; R600-NEXT:    ret i16 [[EXTRACTED]]
-  %res = atomicrmw and ptr addrspace(1) %ptr, i16 %value syncscope("agent") seq_cst, !noundef !0, !some.unknown.md !0
+  %res = atomicrmw and ptr addrspace(1) %ptr, i16 %value syncscope("agent") seq_cst, !some.unknown.md !0
   ret i16 %res
 }
 
@@ -281,7 +281,7 @@ define i16 @test_atomicrmw_and_i16_global_agent_align4_drop_md(ptr addrspace(1)
 ; R600-NEXT:    [[TMP2:%.*]] = atomicrmw and ptr addrspace(1) [[PTR:%.*]], i32 [[ANDOPERAND]] syncscope("agent") seq_cst, align 4
 ; R600-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[TMP2]] to i16
 ; R600-NEXT:    ret i16 [[EXTRACTED]]
-  %res = atomicrmw and ptr addrspace(1) %ptr, i16 %value syncscope("agent") seq_cst, align 4, !noundef !0, !some.unknown.md !0
+  %res = atomicrmw and ptr addrspace(1) %ptr, i16 %value syncscope("agent") seq_cst, align 4, !some.unknown.md !0
   ret i16 %res
 }
 
@@ -327,7 +327,7 @@ define i16 @test_atomicrmw_and_i16_global_agent_preserve_mmra(ptr addrspace(1) %
 ; R600-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]]
 ; R600-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
 ; R600-NEXT:    ret i16 [[EXTRACTED]]
-  %res = atomicrmw and ptr addrspace(1) %ptr, i16 %value syncscope("agent") seq_cst, !noundef !0, !mmra !1
+  %res = atomicrmw and ptr addrspace(1) %ptr, i16 %value syncscope("agent") seq_cst, !mmra !1
   ret i16 %res
 }
 
@@ -355,7 +355,7 @@ define i16 @test_atomicrmw_and_i16_global_agent_align4_preserve_mmra(ptr addrspa
 ; R600-NEXT:    [[TMP2:%.*]] = atomicrmw and ptr addrspace(1) [[PTR:%.*]], i32 [[ANDOPERAND]] syncscope("agent") seq_cst, align 4, !mmra [[META0]]
 ; R600-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[TMP2]] to i16
 ; R600-NEXT:    ret i16 [[EXTRACTED]]
-  %res = atomicrmw and ptr addrspace(1) %ptr, i16 %value syncscope("agent") seq_cst, align 4, !noundef !0, !mmra !1
+  %res = atomicrmw and ptr addrspace(1) %ptr, i16 %value syncscope("agent") seq_cst, align 4, !mmra !1
   ret i16 %res
 }
 
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fma.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fma.ll
index 86984e797f575..bedced6a7e944 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fma.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fma.ll
@@ -249,7 +249,7 @@ define nofpclass(nan) half @ret_nonan__fmuladd__no_nan_all_src__drop_ub_attrs_md
 ; CHECK-NEXT:    [[RESULT:%.*]] = call nnan half @llvm.fmuladd.f16(half [[NOT_NAN0]], half [[NOT_NAN1]], half [[NOT_NAN2]])
 ; CHECK-NEXT:    ret half [[RESULT]]
 ;
-  %result = call noundef half @llvm.fmuladd.f16(half %not.nan0, half %not.nan1, half noundef %not.nan2), !unknown.md !0, !noundef !0
+  %result = call noundef half @llvm.fmuladd.f16(half %not.nan0, half %not.nan1, half noundef %not.nan2), !unknown.md !0
   ret half %result
 }
 
@@ -259,7 +259,7 @@ define nofpclass(nan inf) half @ret_noinf_nonan__fmuladd__no_inf_all_src__drop_u
 ; CHECK-NEXT:    [[RESULT:%.*]] = call nnan ninf half @llvm.fmuladd.f16(half [[NOT_NAN_OR_INF0]], half [[NOT_NAN_OR_INF1]], half [[NOT_NAN_OR_INF2]])
 ; CHECK-NEXT:    ret half [[RESULT]]
 ;
-  %result = call noundef half @llvm.fmuladd.f16(half %not.nan.or.inf0, half %not.nan.or.inf1, half %not.nan.or.inf2), !unknown.md !0, !noundef !0
+  %result = call noundef half @llvm.fmuladd.f16(half %not.nan.or.inf0, half %not.nan.or.inf1, half %not.nan.or.inf2), !unknown.md !0
   ret half %result
 }
 
@@ -269,7 +269,7 @@ define nofpclass(nan) half @ret_nonan__fma_square__no_nan_all_src(half nofpclass
 ; CHECK-NEXT:    [[RESULT:%.*]] = call nnan half @llvm.fma.f16(half [[NOT_NAN0]], half [[NOT_NAN0]], half [[NOT_NAN1]])
 ; CHECK-NEXT:    ret half [[RESULT]]
 ;
-  %result = call noundef half @llvm.fma.f16(half %not.nan0, half %not.nan0, half %not.nan1), !unknown.md !0, !noundef !0
+  %result = call noundef half @llvm.fma.f16(half %not.nan0, half %not.nan0, half %not.nan1), !unknown.md !0
   ret half %result
 }
 
@@ -279,7 +279,7 @@ define nofpclass(inf) half @ret_noinf__fma_square__no_inf_all_src(half nofpclass
 ; CHECK-NEXT:    [[RESULT:%.*]] = call ninf half @llvm.fma.f16(half [[NOT_NAN0]], half [[NOT_NAN0]], half [[NOT_NAN1]])
 ; CHECK-NEXT:    ret half [[RESULT]]
 ;
-  %result = call noundef half @llvm.fma.f16(half %not.nan0, half %not.nan0, half %not.nan1), !unknown.md !0, !noundef !0
+  %result = call noundef half @llvm.fma.f16(half %not.nan0, half %not.nan0, half %not.nan1), !unknown.md !0
   ret half %result
 }
 
@@ -289,7 +289,7 @@ define nofpclass(nan inf) half @ret_nonan_noinf__fma_square__no_nan_no_inf_all_s
 ; CHECK-NEXT:    [[RESULT:%.*]] = call nnan ninf nsz half @llvm.fma.f16(half [[NOT_NAN0]], half [[NOT_NAN0]], half [[NOT_NAN1]])
 ; CHECK-NEXT:    ret half [[RESULT]]
 ;
-  %result = call nsz noundef half @llvm.fma.f16(half %not.nan0, half %not.nan0, half %not.nan1), !unknown.md !0, !noundef !0
+  %result = call nsz noundef half @llvm.fma.f16(half %not.nan0, half %not.nan0, half %not.nan1), !unknown.md !0
   ret half %result
 }
 
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll
index 2386a5e8af85e..47558396f8b6e 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll
@@ -1717,7 +1717,7 @@ define nofpclass(snan) float @not_nan__maximum_noundef_md__not_nan(float nofpcla
 ; CHECK-NEXT:    [[RESULT:%.*]] = call nnan float @llvm.maximum.f32(float [[NOT_NAN0]], float [[NOT_NAN1]])
 ; CHECK-NEXT:    ret float [[RESULT]]
 ;
-  %result = call float @llvm.maximum.f32(float %not.nan0, float %not.nan1), !noundef !0, !unknown.md !0
+  %result = call float @llvm.maximum.f32(float %not.nan0, float %not.nan1), !unknown.md !0
   ret float %result
 }
 
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximumnum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximumnum.ll
index 8a27076d75ed3..160aa6b6c029a 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximumnum.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximumnum.ll
@@ -1725,7 +1725,7 @@ define nofpclass(snan) float @not_nan__maximumnum_noundef_md__not_nan(float nofp
 ; CHECK-NEXT:    [[RESULT:%.*]] = call nnan float @llvm.maximumnum.f32(float [[NOT_NAN0]], float [[NOT_NAN1]])
 ; CHECK-NEXT:    ret float [[RESULT]]
 ;
-  %result = call float @llvm.maximumnum.f32(float %not.nan0, float %not.nan1), !noundef !0, !unknown.md !0
+  %result = call float @llvm.maximumnum.f32(float %not.nan0, float %not.nan1), !unknown.md !0
   ret float %result
 }
 
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maxnum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maxnum.ll
index ae4aed7031d6a..488a32f428c2f 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maxnum.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maxnum.ll
@@ -1726,7 +1726,7 @@ define nofpclass(snan) float @not_nan__maxnum_noundef_md__not_nan(float nofpclas
 ; CHECK-NEXT:    [[RESULT:%.*]] = call nnan float @llvm.maxnum.f32(float [[NOT_NAN0]], float [[NOT_NAN1]])
 ; CHECK-NEXT:    ret float [[RESULT]]
 ;
-  %result = call float @llvm.maxnum.f32(float %not.nan0, float %not.nan1), !noundef !0, !unknown.md !0
+  %result = call float @llvm.maxnum.f32(float %not.nan0, float %not.nan1), !unknown.md !0
   ret float %result
 }
 
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimum.ll
index e27d1f2052762..9e277ee2001ca 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimum.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimum.ll
@@ -1719,7 +1719,7 @@ define nofpclass(snan) float @not_nan__minimum_noundef_md__not_nan(float nofpcla
 ; CHECK-NEXT:    [[RESULT:%.*]] = call nnan float @llvm.minimum.f32(float [[NOT_NAN0]], float [[NOT_NAN1]])
 ; CHECK-NEXT:    ret float [[RESULT]]
 ;
-  %result = call float @llvm.minimum.f32(float %not.nan0, float %not.nan1), !noundef !0, !unknown.md !0
+  %result = call float @llvm.minimum.f32(float %not.nan0, float %not.nan1), !unknown.md !0
   ret float %result
 }
 
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimumnum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimumnum.ll
index 4f7fe0fd453d0..78100cea9705f 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimumnum.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimumnum.ll
@@ -1722,7 +1722,7 @@ define nofpclass(snan) float @not_nan__minimumnum_noundef_md__not_nan(float nofp
 ; CHECK-NEXT:    [[RESULT:%.*]] = call nnan float @llvm.minimumnum.f32(float [[NOT_NAN0]], float [[NOT_NAN1]])
 ; CHECK-NEXT:    ret float [[RESULT]]
 ;
-  %result = call float @llvm.minimumnum.f32(float %not.nan0, float %not.nan1), !noundef !0, !unknown.md !0
+  %result = call float @llvm.minimumnum.f32(float %not.nan0, float %not.nan1), !unknown.md !0
   ret float %result
 }
 
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minnum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minnum.ll
index dca645741b8b0..36223458500ea 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minnum.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minnum.ll
@@ -1722,7 +1722,7 @@ define nofpclass(snan) float @not_nan__minnum_noundef_md__not_nan(float nofpclas
 ; CHECK-NEXT:    [[RESULT:%.*]] = call nnan float @llvm.minnum.f32(float [[NOT_NAN0]], float [[NOT_NAN1]])
 ; CHECK-NEXT:    ret float [[RESULT]]
 ;
-  %result = call float @llvm.minnum.f32(float %not.nan0, float %not.nan1), !noundef !0, !unknown.md !0
+  %result = call float @llvm.minnum.f32(float %not.nan0, float %not.nan1), !unknown.md !0
   ret float %result
 }
 
diff --git a/llvm/test/Verifier/nofpclass-metadata.ll b/llvm/test/Verifier/nofpclass-metadata.ll
index b301e9f90617e..0acd6e240cecc 100644
--- a/llvm/test/Verifier/nofpclass-metadata.ll
+++ b/llvm/test/Verifier/nofpclass-metadata.ll
@@ -4,7 +4,7 @@ declare float @func()
 
 %struct = type { i32, float }
 
-define void @md_missing_value(ptr %ptr) {
+define void @test(ptr %ptr) {
   ; CHECK: nofpclass is only for loads
   call float @func(), !nofpclass !{i32 3}
 
@@ -33,7 +33,7 @@ define void @md_missing_value(ptr %ptr) {
   load float, ptr %ptr, align 4, !nofpclass !{!"foo"}
 
   ; CHECK: nofpclass entry must be a constant i32
-  load float, ptr %ptr, align 4, !nofpclass !{ptr @md_is_ptr}
+  load float, ptr %ptr, align 4, !nofpclass !{ptr @test}
 
   ; CHECK: 'nofpclass' must have at least one test bit set
   load float, ptr %ptr, align 4, !nofpclass !{i32 0}
diff --git a/llvm/test/Verifier/range-metadata.ll b/llvm/test/Verifier/range-metadata.ll
index 367b21283ff98..00cc604769116 100644
--- a/llvm/test/Verifier/range-metadata.ll
+++ b/llvm/test/Verifier/range-metadata.ll
@@ -1,6 +1,8 @@
 ; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
 
-define void @f1(ptr %x) {
+declare i8 @func()
+
+define void @test(ptr %x) {
 entry:
   ; CHECK: Ranges are only for loads, calls and invokes!
   store i8 0, ptr %x, align 1, !range !{i8 0, i8 1}
@@ -18,7 +20,7 @@ entry:
   load i8, ptr %x, align 1, !range !{i8 0, double 0.0}
 
   ; CHECK: Range pair types must match!
-  load i8, ptr %x, align 1, !range !5
+  load i8, ptr %x, align 1, !range !{i32 0, i8 0}
 
   ; CHECK: Range pair types must match!
   load i8, ptr %x, align 1, !range !{i8 0, i32 0}
@@ -54,7 +56,7 @@ entry:
   load i8, ptr %x, align 1, !range !{i8 1, i8 2, i8 -1, i8 0}
 
   ; CHECK: It should have at least one range!
-  call i8 undef(), !range !{}
+  call i8 @func(), !range !{}
 
   ; CHECK: Range types must match instruction type!
   load <2 x i8>, ptr %x, !range !{i16 0, i16 10}
diff --git a/llvm/test/tools/llubi/metadata.ll b/llvm/test/tools/llubi/metadata.ll
index bf971c8ad7ef8..4789dae5e4cc0 100644
--- a/llvm/test/tools/llubi/metadata.ll
+++ b/llvm/test/tools/llubi/metadata.ll
@@ -32,12 +32,12 @@ define void @main() {
   %align_load_valid = load ptr, ptr %alloc_ptr, !align !{i32 8}, !noundef !{}, !dereferenceable_or_null !{i32 8}
   %nonnull_load_invalid = load ptr, ptr %alloc_ptr, !nonnull !{}
 
-  %range_call_valid = call i32 @callee(), !noundef !{}, !range !{i32 0, i32 11}
+  %range_call_valid = call i32 @callee(), !range !{i32 0, i32 11}
   %range_call_invalid = call i32 @callee(), !range !{i32 0, i32 10}
-  %nofpclass_call_valid = call float @callee_fp(), !noundef !{}, !nofpclass !{i32 3}
+  %nofpclass_call_valid = call float @callee_fp(), !nofpclass !{i32 3}
   %nofpclass_call_invalid = call float @callee_fp(), !nofpclass !{i32 99}
-  %nonnull_align_call_valid = call ptr @callee_ptr(ptr %alloc_ptr), !nonnull !{}, !align !{i32 8}, !noundef !{}
-  %align_call_invalid = call ptr @callee_ptr(ptr null), !align !{i32 8}, !noundef !{}
+  %nonnull_align_call_valid = call ptr @callee_ptr(ptr %alloc_ptr), !nonnull !{}, !align !{i32 8}
+  %align_call_invalid = call ptr @callee_ptr(ptr null), !align !{i32 8}
   %nonnull_call_invalid = call ptr @callee_ptr(ptr null), !nonnull !{}
 
   %dereferenceable_call_valid = call ptr @callee_ptr(ptr %alloc_ptr), !dereferenceable !{i32 8}
@@ -65,7 +65,7 @@ define void @main() {
 ; CHECK-NEXT: Entering function: callee
 ; CHECK-NEXT:   ret i32 10
 ; CHECK-NEXT: Exiting function: callee
-; CHECK-NEXT:   %range_call_valid = call i32 @callee(), !range !7, !noundef !1 => i32 10
+; CHECK-NEXT:   %range_call_valid = call i32 @callee(), !range !7 => i32 10
 ; CHECK-NEXT: Entering function: callee
 ; CHECK-NEXT:   ret i32 10
 ; CHECK-NEXT: Exiting function: callee
@@ -73,7 +73,7 @@ define void @main() {
 ; CHECK-NEXT: Entering function: callee_fp
 ; CHECK-NEXT:   ret float 0.000000e+00
 ; CHECK-NEXT: Exiting function: callee_fp
-; CHECK-NEXT:   %nofpclass_call_valid = call float @callee_fp(), !noundef !1, !nofpclass !4 => float 0.000000e+00
+; CHECK-NEXT:   %nofpclass_call_valid = call float @callee_fp(), !nofpclass !4 => float 0.000000e+00
 ; CHECK-NEXT: Entering function: callee_fp
 ; CHECK-NEXT:   ret float 0.000000e+00
 ; CHECK-NEXT: Exiting function: callee_fp
@@ -82,12 +82,12 @@ define void @main() {
 ; CHECK-NEXT:   ptr %x = ptr 0x48 [alloc_ptr]
 ; CHECK-NEXT:   ret ptr %x
 ; CHECK-NEXT: Exiting function: callee_ptr
-; CHECK-NEXT:   %nonnull_align_call_valid = call ptr @callee_ptr(ptr %alloc_ptr), !nonnull !1, !align !6, !noundef !1 => ptr 0x48 [alloc_ptr]
+; CHECK-NEXT:   %nonnull_align_call_valid = call ptr @callee_ptr(ptr %alloc_ptr), !nonnull !1, !align !6 => ptr 0x48 [alloc_ptr]
 ; CHECK-NEXT: Entering function: callee_ptr
 ; CHECK-NEXT:   ptr %x = ptr 0x0 [nullary]
 ; CHECK-NEXT:   ret ptr %x
 ; CHECK-NEXT: Exiting function: callee_ptr
-; CHECK-NEXT:   %align_call_invalid = call ptr @callee_ptr(ptr null), !align !6, !noundef !1 => ptr 0x0 [nullary]
+; CHECK-NEXT:   %align_call_invalid = call ptr @callee_ptr(ptr null), !align !6 => ptr 0x0 [nullary]
 ; CHECK-NEXT: Entering function: callee_ptr
 ; CHECK-NEXT:   ptr %x = ptr 0x0 [nullary]
 ; CHECK-NEXT:   ret ptr %x

>From 1a3b719c77bcf608b52bd925654128edbddfbc74 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sat, 20 Jun 2026 14:49:23 +0200
Subject: [PATCH 3/3] More fixes

---
 llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll b/llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll
index 04cdc2f151218..747af105bf4c8 100644
--- a/llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll
+++ b/llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll
@@ -10,7 +10,7 @@ define i32 @test_call_known_max_range() #0 {
 ; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
 ; CHECK-NEXT:    ret
 entry:
-  %id = tail call i32 @foo(), !range !0 !{}
+  %id = tail call i32 @foo(), !range !0
   %and = and i32 %id, 1023
   ret i32 %and
 }
@@ -24,7 +24,7 @@ define i32 @test_call_known_trunc_1_bit_range() #0 {
 ; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
 ; CHECK-NEXT:    ret
 entry:
-  %id = tail call i32 @foo(), !range !0 !{}
+  %id = tail call i32 @foo(), !range !0
   %and = and i32 %id, 511
   ret i32 %and
 }
@@ -38,7 +38,7 @@ define i32 @test_call_known_max_range_m1() #0 {
 ; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
 ; CHECK-NEXT:    ret
 entry:
-  %id = tail call i32 @foo(), !range !1 !{}
+  %id = tail call i32 @foo(), !range !1
   %and = and i32 %id, 255
   ret i32 %and
 }



More information about the llvm-commits mailing list