diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp index a466ce5bf0d4c..b3fa9e2bb0368 100644 --- a/llvm/lib/Linker/IRMover.cpp +++ b/llvm/lib/Linker/IRMover.cpp @@ -1133,8 +1133,11 @@ void IRLinker::linkNamedMDNodes() { NamedMDNode *DestNMD = DstM.getOrInsertNamedMetadata(NMD.getName()); // Add Src elements into Dest node. - for (const MDNode *Op : NMD.operands()) - DestNMD->addOperand(Mapper.mapMDNode(*Op)); + for (const MDNode *Op : NMD.operands()) { + auto *MD = Mapper.mapMDNode(*Op); + if (llvm::find(DestNMD->operands(), MD) == DestNMD->op_end()) + DestNMD->addOperand(MD); + } } } diff --git a/llvm/test/Linker/Inputs/ident.b.ll b/llvm/test/Linker/Inputs/ident.b.ll index d9daf8558a704..bfcff3de577e3 100644 --- a/llvm/test/Linker/Inputs/ident.b.ll +++ b/llvm/test/Linker/Inputs/ident.b.ll @@ -1,2 +1,3 @@ -!llvm.ident = !{!0} -!0 = !{!"Compiler V3"} +!llvm.ident = !{!0, !1} +!0 = !{!"Compiler V2"} +!1 = !{!"Compiler V3"} diff --git a/llvm/test/Linker/Inputs/opencl.md.a.ll b/llvm/test/Linker/Inputs/opencl.md.a.ll new file mode 100644 index 0000000000000..e1bfe80ede7f9 --- /dev/null +++ b/llvm/test/Linker/Inputs/opencl.md.a.ll @@ -0,0 +1,13 @@ +!llvm.module.flags = !{!0} +!opencl.ocl.version = !{!1} +!opencl.spir.version = !{!1} +!opencl.used.extensions = !{!3, !4} +!opencl.used.optional.core.features = !{!5} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 3, i32 0} +!2 = !{!"LLVM.org clang version 20.1.0"} +!3 = !{!"cl_images", !"cl_khr_fp16"} +!4 = !{!"cl_images", !"cl_doubles"} +!5 = !{!"cl_images"} diff --git a/llvm/test/Linker/Inputs/opencl.md.b.ll b/llvm/test/Linker/Inputs/opencl.md.b.ll new file mode 100644 index 0000000000000..e062010718858 --- /dev/null +++ b/llvm/test/Linker/Inputs/opencl.md.b.ll @@ -0,0 +1,13 @@ +!llvm.module.flags = !{!0} +!opencl.ocl.version = !{!1} +!opencl.spir.version = !{!1} +!opencl.used.extensions = !{!3, !4} +!opencl.used.optional.core.features = !{!5} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 3, i32 0} +!2 = !{!"LLVM.org clang version 20.1.0"} +!3 = !{!"cl_images", !"cl_khr_fp16"} +!4 = !{!"cl_khr_fp16", !"cl_doubles"} +!5 = !{!"cl_images"} diff --git a/llvm/test/Linker/Inputs/opencl.md.c.ll b/llvm/test/Linker/Inputs/opencl.md.c.ll new file mode 100644 index 0000000000000..03ad621dde7b8 --- /dev/null +++ b/llvm/test/Linker/Inputs/opencl.md.c.ll @@ -0,0 +1,6 @@ +!opencl.ocl.version = !{!0} +!opencl.spir.version = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 2, i32 0} +!1 = !{!"LLVM.org clang version 20.1.0"} diff --git a/llvm/test/Linker/dicompositetype-unique.ll b/llvm/test/Linker/dicompositetype-unique.ll index ab1fdaa3616c9..28b2f33001b9e 100644 --- a/llvm/test/Linker/dicompositetype-unique.ll +++ b/llvm/test/Linker/dicompositetype-unique.ll @@ -17,8 +17,8 @@ ; Check that the type map will unique two DICompositeTypes. -; CHECK: !named = !{!0, !1, !2, !3, !0, !1, !2, !3} -; NOMAP: !named = !{!0, !1, !2, !3, !0, !4, !5, !6} +; CHECK: !named = !{!0, !1, !2, !3} +; NOMAP: !named = !{!0, !1, !2, !3, !4, !5, !6} !named = !{!0, !1, !2, !3} ; Check both directions. diff --git a/llvm/test/Linker/distinct.ll b/llvm/test/Linker/distinct.ll index f21c51ce8b54f..0863446f9a33e 100644 --- a/llvm/test/Linker/distinct.ll +++ b/llvm/test/Linker/distinct.ll @@ -9,7 +9,7 @@ ; Add an external reference to @global so that it gets linked in. @alias = alias i32, ptr @global -; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !0, !1, !2, !9, !10, !11, !12, !13, !14} +; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14} !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8} ; CHECK: !0 = !{} diff --git a/llvm/test/Linker/ident.ll b/llvm/test/Linker/ident.ll index 93bf8c7b2ca72..532a8427346ce 100644 --- a/llvm/test/Linker/ident.ll +++ b/llvm/test/Linker/ident.ll @@ -1,6 +1,7 @@ ; RUN: llvm-link %S/Inputs/ident.a.ll %S/Inputs/ident.b.ll -S | FileCheck %s -; Verify that multiple input llvm.ident metadata are linked together. +; Verify that multiple input llvm.ident metadata are linked together, and +; duplicate "Compiler V2" metadata from the two inputs are unified. ; CHECK-DAG: !llvm.ident = !{!0, !1, !2} ; CHECK-DAG: "Compiler V1" diff --git a/llvm/test/Linker/named-metadata-opencl-version.ll b/llvm/test/Linker/named-metadata-opencl-version.ll new file mode 100644 index 0000000000000..158091a77ad91 --- /dev/null +++ b/llvm/test/Linker/named-metadata-opencl-version.ll @@ -0,0 +1,20 @@ +; RUN: llvm-link %S/Inputs/opencl.md.a.ll %S/Inputs/opencl.md.c.ll -S | FileCheck %s + +; OpenCL/SPIR version is different in input modules. +; Verify that different OpenCL/SPIR version metadata nodes are kept in the +; destination module. + +; CHECK: !opencl.ocl.version = !{![[#MD0:]], ![[#MD1:]]} +; CHECK: !opencl.spir.version = !{![[#MD0]], ![[#MD1]]} +; CHECK: !opencl.used.extensions = !{![[#MD2:]], ![[#MD3:]]} +; CHECK: !opencl.used.optional.core.features = !{![[#MD4:]]} +; CHECK: !llvm.ident = !{![[#MD5:]]} +; CHECK: !llvm.module.flags = !{![[#MD6:]]} + +; CHECK: ![[#MD0]] = !{i32 3, i32 0} +; CHECK: ![[#MD1]] = !{i32 2, i32 0} +; CHECK: ![[#MD2]] = !{!"cl_images", !"cl_khr_fp16"} +; CHECK: ![[#MD3]] = !{!"cl_images", !"cl_doubles"} +; CHECK: ![[#MD4]] = !{!"cl_images"} +; CHECK: ![[#MD5]] = !{!"LLVM.org clang version 20.1.0"} +; CHECK: ![[#MD6]] = !{i32 1, !"wchar_size", i32 4} diff --git a/llvm/test/Linker/named-metadata-opencl.ll b/llvm/test/Linker/named-metadata-opencl.ll new file mode 100644 index 0000000000000..109280ad08c1e --- /dev/null +++ b/llvm/test/Linker/named-metadata-opencl.ll @@ -0,0 +1,18 @@ +; RUN: llvm-link %S/Inputs/opencl.md.a.ll %S/Inputs/opencl.md.b.ll -S | FileCheck %s + +; Verify that duplicate named metadata node isn't added to the result module. + +; CHECK: !opencl.ocl.version = !{![[#MD0:]]} +; CHECK: !opencl.spir.version = !{![[#MD0]]} +; CHECK: !opencl.used.extensions = !{![[#MD1:]], ![[#MD2:]], ![[#MD3:]]} +; CHECK: !opencl.used.optional.core.features = !{![[#MD4:]]} +; CHECK: !llvm.ident = !{![[#MD5:]]} +; CHECK: !llvm.module.flags = !{![[#MD6:]]} + +; CHECK: ![[#MD0]] = !{i32 3, i32 0} +; CHECK: ![[#MD1]] = !{!"cl_images", !"cl_khr_fp16"} +; CHECK: ![[#MD2]] = !{!"cl_images", !"cl_doubles"} +; CHECK: ![[#MD3]] = !{!"cl_khr_fp16", !"cl_doubles"} +; CHECK: ![[#MD4]] = !{!"cl_images"} +; CHECK: ![[#MD5]] = !{!"LLVM.org clang version 20.1.0"} +; CHECK: ![[#MD6]] = !{i32 1, !"wchar_size", i32 4} diff --git a/llvm/test/Linker/unique-fwd-decl-order.ll b/llvm/test/Linker/unique-fwd-decl-order.ll index e1d8c2e5cf92f..2f83714305b53 100644 --- a/llvm/test/Linker/unique-fwd-decl-order.ll +++ b/llvm/test/Linker/unique-fwd-decl-order.ll @@ -8,7 +8,7 @@ ; Note that these two assembly files number the nodes identically, even though ; the nodes are in a different order. This is for the reader's convenience. -; CHECK: !named = !{!0, !0} +; CHECK: !named = !{!0} !named = !{!0} ; CHECK: !0 = !{!1} diff --git a/llvm/test/ThinLTO/X86/import-metadata.ll b/llvm/test/ThinLTO/X86/import-metadata.ll index f938fdd5c93c9..7175fb6bb2715 100644 --- a/llvm/test/ThinLTO/X86/import-metadata.ll +++ b/llvm/test/ThinLTO/X86/import-metadata.ll @@ -12,11 +12,12 @@ ; CHECK: !llvm.dbg.cu = !{![[#CU1:]], ![[#CU2:]]} ;; Note that MD1 comes from the current module. MD2 is from the imported module. -;; We are checking if the imported MD2 doesn't end up having a null operand. -; CHECK: !llvm.md = !{![[#MD1:]], ![[#MD2:]]} +;; We are checking that MD2 is unified with MD1 and the imported MD2 doesn't +;; end up having a null operand. +; CHECK: !llvm.md = !{![[#MD1:]]} ; CHECK: ![[#MD3:]] = !{} ; CHECK: ![[#CU2]] = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: ![[#FILE2:]], isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug) -; CHECK: ![[#MD2]] = !{![[#MD3]]} +; CHECK: ![[#MD1]] = !{![[#MD3]]} target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-scei-ps4"