[llvm] [LLVM][C API] Support Value extraction from a MetadataAsValue. (PR #105501)

Tim Besard via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 21 05:11:07 PDT 2024


https://github.com/maleadt updated https://github.com/llvm/llvm-project/pull/105501

>From 6388ec1e71e2e4de2981a055c2aeedcafb90e425 Mon Sep 17 00:00:00 2001
From: Tim Besard <tim.besard at gmail.com>
Date: Wed, 21 Aug 2024 13:15:17 +0200
Subject: [PATCH 1/2] [LLVM][C API] Support Value extraction from a
 MetadataAsValue.

It is already possible to extract the underlying Metadata
from a ValueAsMetadata.
---
 llvm/lib/IR/Core.cpp                         |  8 ++++++--
 llvm/test/Bindings/llvm-c/vam_mav_extract.ll |  2 ++
 llvm/tools/llvm-c-test/llvm-c-test.h         |  1 +
 llvm/tools/llvm-c-test/main.c                |  5 +++++
 llvm/tools/llvm-c-test/metadata.c            | 20 +++++++++++++++++++-
 5 files changed, 33 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/Bindings/llvm-c/vam_mav_extract.ll

diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index 7665385025bd91..f4708bc18b3f8b 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -1328,8 +1328,12 @@ LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count) {
   return LLVMMDNodeInContext(LLVMGetGlobalContext(), Vals, Count);
 }
 
-LLVMValueRef LLVMMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
-  return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
+LLVMValueRef LLVMMetadataAsValue(LLVMContextRef C, LLVMMetadataRef Metadata) {
+  auto *MD = unwrap(Metadata);
+  if (auto *VAM = dyn_cast<ValueAsMetadata>(MD))
+    return wrap(VAM->getValue());
+  else
+    return wrap(MetadataAsValue::get(*unwrap(C), MD));
 }
 
 LLVMMetadataRef LLVMValueAsMetadata(LLVMValueRef Val) {
diff --git a/llvm/test/Bindings/llvm-c/vam_mav_extract.ll b/llvm/test/Bindings/llvm-c/vam_mav_extract.ll
new file mode 100644
index 00000000000000..31640c460ceab7
--- /dev/null
+++ b/llvm/test/Bindings/llvm-c/vam_mav_extract.ll
@@ -0,0 +1,2 @@
+; RUN: llvm-c-test --vam-mav-extract < /dev/null
+; This used to trigger an assertion
diff --git a/llvm/tools/llvm-c-test/llvm-c-test.h b/llvm/tools/llvm-c-test/llvm-c-test.h
index 1da6596cd5a8f2..44790e6a3bc8b5 100644
--- a/llvm/tools/llvm-c-test/llvm-c-test.h
+++ b/llvm/tools/llvm-c-test/llvm-c-test.h
@@ -45,6 +45,7 @@ int llvm_add_named_metadata_operand(void);
 int llvm_set_metadata(void);
 int llvm_replace_md_operand(void);
 int llvm_is_a_value_as_metadata(void);
+int llvm_vam_mav_extract(void);
 
 // object.c
 int llvm_object_list_sections(void);
diff --git a/llvm/tools/llvm-c-test/main.c b/llvm/tools/llvm-c-test/main.c
index 8be9ea06fc68da..0ec9928fd942ea 100644
--- a/llvm/tools/llvm-c-test/main.c
+++ b/llvm/tools/llvm-c-test/main.c
@@ -56,6 +56,9 @@ static void print_usage(void) {
   fprintf(stderr, "  * --is-a-value-as-metadata\n");
   fprintf(stderr,
           "    Run test for checking if LLVMValueRef is a ValueAsMetadata\n");
+  fprintf(stderr, "  * --vam-mav-extract\n");
+  fprintf(stderr, "    Run test for extracting data from ValueAsMetadata and "
+                  "MetadataAsValue\n");
   fprintf(stderr, "  * --echo\n");
   fprintf(stderr, "    Read bitcode file from stdin - print it back out\n\n");
   fprintf(stderr, "  * --test-diagnostic-handler\n");
@@ -101,6 +104,8 @@ int main(int argc, char **argv) {
     return llvm_replace_md_operand();
   } else if (argc == 2 && !strcmp(argv[1], "--is-a-value-as-metadata")) {
     return llvm_is_a_value_as_metadata();
+  } else if (argc == 2 && !strcmp(argv[1], "--vam-mav-extract")) {
+    return llvm_vam_mav_extract();
   } else if (argc == 2 && !strcmp(argv[1], "--test-function-attributes")) {
     return llvm_test_function_attributes();
   } else if (argc == 2 && !strcmp(argv[1], "--test-callsite-attributes")) {
diff --git a/llvm/tools/llvm-c-test/metadata.c b/llvm/tools/llvm-c-test/metadata.c
index 4fe8c00c57481b..a08ebacb49696e 100644
--- a/llvm/tools/llvm-c-test/metadata.c
+++ b/llvm/tools/llvm-c-test/metadata.c
@@ -80,7 +80,7 @@ int llvm_is_a_value_as_metadata(void) {
   LLVMContextRef Context = LLVMGetModuleContext(M);
 
   {
-    LLVMValueRef Int = LLVMConstInt(LLVMInt32Type(), 0, 0);
+    LLVMValueRef Int = LLVMConstInt(LLVMInt32TypeInContext(Context), 0, 0);
     LLVMValueRef NodeMD = LLVMMDNode(&Int, 1);
     assert(LLVMIsAValueAsMetadata(NodeMD) == NodeMD);
     (void)NodeMD;
@@ -98,3 +98,21 @@ int llvm_is_a_value_as_metadata(void) {
 
   return 0;
 }
+
+int llvm_vam_mav_extract(void) {
+  LLVMModuleRef M = LLVMModuleCreateWithName("Mod");
+  LLVMContextRef Context = LLVMGetModuleContext(M);
+
+  LLVMValueRef Val = LLVMConstInt(LLVMInt32TypeInContext(Context), 0, 0);
+  LLVMMetadataRef MD = LLVMMDStringInContext2(Context, "foo", 3);
+
+  // construction
+  LLVMValueRef MAV = LLVMMetadataAsValue(Context, MD);
+  LLVMMetadataRef VAM = LLVMValueAsMetadata(Val);
+
+  // extraction
+  assert(LLVMMetadataAsValue(Context, VAM) == Val);
+  assert(LLVMValueAsMetadata(MAV) == MD);
+
+  return 0;
+}

>From 1890fb547517cdde0fb1e1eefffa894335b2d774 Mon Sep 17 00:00:00 2001
From: Tim Besard <tim.besard at gmail.com>
Date: Wed, 21 Aug 2024 14:10:31 +0200
Subject: [PATCH 2/2] Switch to a unit test.

---
 llvm/test/Bindings/llvm-c/vam_mav_extract.ll |  2 --
 llvm/tools/llvm-c-test/llvm-c-test.h         |  1 -
 llvm/tools/llvm-c-test/main.c                |  5 -----
 llvm/tools/llvm-c-test/metadata.c            | 18 ------------------
 llvm/unittests/IR/MetadataTest.cpp           | 12 ++++++++++++
 5 files changed, 12 insertions(+), 26 deletions(-)
 delete mode 100644 llvm/test/Bindings/llvm-c/vam_mav_extract.ll

diff --git a/llvm/test/Bindings/llvm-c/vam_mav_extract.ll b/llvm/test/Bindings/llvm-c/vam_mav_extract.ll
deleted file mode 100644
index 31640c460ceab7..00000000000000
--- a/llvm/test/Bindings/llvm-c/vam_mav_extract.ll
+++ /dev/null
@@ -1,2 +0,0 @@
-; RUN: llvm-c-test --vam-mav-extract < /dev/null
-; This used to trigger an assertion
diff --git a/llvm/tools/llvm-c-test/llvm-c-test.h b/llvm/tools/llvm-c-test/llvm-c-test.h
index 44790e6a3bc8b5..1da6596cd5a8f2 100644
--- a/llvm/tools/llvm-c-test/llvm-c-test.h
+++ b/llvm/tools/llvm-c-test/llvm-c-test.h
@@ -45,7 +45,6 @@ int llvm_add_named_metadata_operand(void);
 int llvm_set_metadata(void);
 int llvm_replace_md_operand(void);
 int llvm_is_a_value_as_metadata(void);
-int llvm_vam_mav_extract(void);
 
 // object.c
 int llvm_object_list_sections(void);
diff --git a/llvm/tools/llvm-c-test/main.c b/llvm/tools/llvm-c-test/main.c
index 0ec9928fd942ea..8be9ea06fc68da 100644
--- a/llvm/tools/llvm-c-test/main.c
+++ b/llvm/tools/llvm-c-test/main.c
@@ -56,9 +56,6 @@ static void print_usage(void) {
   fprintf(stderr, "  * --is-a-value-as-metadata\n");
   fprintf(stderr,
           "    Run test for checking if LLVMValueRef is a ValueAsMetadata\n");
-  fprintf(stderr, "  * --vam-mav-extract\n");
-  fprintf(stderr, "    Run test for extracting data from ValueAsMetadata and "
-                  "MetadataAsValue\n");
   fprintf(stderr, "  * --echo\n");
   fprintf(stderr, "    Read bitcode file from stdin - print it back out\n\n");
   fprintf(stderr, "  * --test-diagnostic-handler\n");
@@ -104,8 +101,6 @@ int main(int argc, char **argv) {
     return llvm_replace_md_operand();
   } else if (argc == 2 && !strcmp(argv[1], "--is-a-value-as-metadata")) {
     return llvm_is_a_value_as_metadata();
-  } else if (argc == 2 && !strcmp(argv[1], "--vam-mav-extract")) {
-    return llvm_vam_mav_extract();
   } else if (argc == 2 && !strcmp(argv[1], "--test-function-attributes")) {
     return llvm_test_function_attributes();
   } else if (argc == 2 && !strcmp(argv[1], "--test-callsite-attributes")) {
diff --git a/llvm/tools/llvm-c-test/metadata.c b/llvm/tools/llvm-c-test/metadata.c
index a08ebacb49696e..9031c6e4d7ce1c 100644
--- a/llvm/tools/llvm-c-test/metadata.c
+++ b/llvm/tools/llvm-c-test/metadata.c
@@ -98,21 +98,3 @@ int llvm_is_a_value_as_metadata(void) {
 
   return 0;
 }
-
-int llvm_vam_mav_extract(void) {
-  LLVMModuleRef M = LLVMModuleCreateWithName("Mod");
-  LLVMContextRef Context = LLVMGetModuleContext(M);
-
-  LLVMValueRef Val = LLVMConstInt(LLVMInt32TypeInContext(Context), 0, 0);
-  LLVMMetadataRef MD = LLVMMDStringInContext2(Context, "foo", 3);
-
-  // construction
-  LLVMValueRef MAV = LLVMMetadataAsValue(Context, MD);
-  LLVMMetadataRef VAM = LLVMValueAsMetadata(Val);
-
-  // extraction
-  assert(LLVMMetadataAsValue(Context, VAM) == Val);
-  assert(LLVMValueAsMetadata(MAV) == MD);
-
-  return 0;
-}
diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index 17573ca57e0874..fdc16b4bb17fc0 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/IR/Metadata.h"
+#include "llvm-c/Core.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/IR/Constants.h"
@@ -404,6 +405,17 @@ TEST_F(MDNodeTest, PrintFromMetadataAsValue) {
   EXPECT_PRINTER_EQ("metadata !1", MAV1->printAsOperand(OS, true, MST));
 }
 
+TEST_F(MDNodeTest, ExtractFromValueOrMetadataWrappers) {
+  LLVMValueRef Val = LLVMConstInt(LLVMInt32TypeInContext(wrap(&Context)), 0, 0);
+  LLVMMetadataRef MD = LLVMMDStringInContext2(wrap(&Context), "foo", 3);
+
+  LLVMValueRef MAV = LLVMMetadataAsValue(wrap(&Context), MD);
+  LLVMMetadataRef VAM = LLVMValueAsMetadata(Val);
+
+  EXPECT_EQ(LLVMMetadataAsValue(wrap(&Context), VAM), Val);
+  EXPECT_EQ(LLVMValueAsMetadata(MAV), MD);
+}
+
 TEST_F(MDNodeTest, PrintWithDroppedCallOperand) {
   Module M("test", Context);
 



More information about the llvm-commits mailing list