[llvm] r227319 - Fix LLVMSetMetadata and LLVMAddNamedMetadataOperand for single value MDNodes

Bjorn Steinbrink bsteinbr at gmail.com
Wed Jan 28 08:36:00 PST 2015


Author: bsteinbr
Date: Wed Jan 28 10:35:59 2015
New Revision: 227319

URL: http://llvm.org/viewvc/llvm-project?rev=227319&view=rev
Log:
Fix LLVMSetMetadata and LLVMAddNamedMetadataOperand for single value MDNodes

Summary:
MetadataAsValue uses a canonical format that strips the MDNode if it
contains only a single constant value. This triggers an assertion when
trying to cast the value to a MDNode.

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D7165

Added:
    llvm/trunk/test/Bindings/llvm-c/add_named_metadata_operand.ll
    llvm/trunk/test/Bindings/llvm-c/set_metadata.ll
    llvm/trunk/tools/llvm-c-test/metadata.c
      - copied, changed from r227318, llvm/trunk/tools/llvm-c-test/llvm-c-test.h
Modified:
    llvm/trunk/lib/IR/Core.cpp
    llvm/trunk/tools/llvm-c-test/CMakeLists.txt
    llvm/trunk/tools/llvm-c-test/llvm-c-test.h
    llvm/trunk/tools/llvm-c-test/main.c

Modified: llvm/trunk/lib/IR/Core.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Core.cpp?rev=227319&r1=227318&r2=227319&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Core.cpp (original)
+++ llvm/trunk/lib/IR/Core.cpp Wed Jan 28 10:35:59 2015
@@ -563,9 +563,23 @@ LLVMValueRef LLVMGetMetadata(LLVMValueRe
   return nullptr;
 }
 
-void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef MD) {
-  MDNode *N =
-      MD ? cast<MDNode>(unwrap<MetadataAsValue>(MD)->getMetadata()) : nullptr;
+// MetadataAsValue uses a canonical format which strips the actual MDNode for
+// MDNode with just a single constant value, storing just a ConstantAsMetadata
+// This undoes this canonicalization, reconstructing the MDNode.
+static MDNode *extractMDNode(MetadataAsValue *MAV) {
+  Metadata *MD = MAV->getMetadata();
+  assert((isa<MDNode>(MD) || isa<ConstantAsMetadata>(MD)) &&
+      "Expected a metadata node or a canonicalized constant");
+
+  if (MDNode *N = dyn_cast<MDNode>(MD))
+    return N;
+
+  return MDNode::get(MAV->getContext(), MD);
+}
+
+void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef Val) {
+  MDNode *N = Val ? extractMDNode(unwrap<MetadataAsValue>(Val)) : nullptr;
+
   unwrap<Instruction>(Inst)->setMetadata(KindID, N);
 }
 
@@ -795,7 +809,7 @@ void LLVMAddNamedMetadataOperand(LLVMMod
     return;
   if (!Val)
     return;
-  N->addOperand(cast<MDNode>(unwrap<MetadataAsValue>(Val)->getMetadata()));
+  N->addOperand(extractMDNode(unwrap<MetadataAsValue>(Val)));
 }
 
 /*--.. Operations on scalar constants ......................................--*/

Added: llvm/trunk/test/Bindings/llvm-c/add_named_metadata_operand.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bindings/llvm-c/add_named_metadata_operand.ll?rev=227319&view=auto
==============================================================================
--- llvm/trunk/test/Bindings/llvm-c/add_named_metadata_operand.ll (added)
+++ llvm/trunk/test/Bindings/llvm-c/add_named_metadata_operand.ll Wed Jan 28 10:35:59 2015
@@ -0,0 +1,2 @@
+; RUN: llvm-c-test --add-named-metadata-operand < /dev/null
+; This used to trigger an assertion

Added: llvm/trunk/test/Bindings/llvm-c/set_metadata.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bindings/llvm-c/set_metadata.ll?rev=227319&view=auto
==============================================================================
--- llvm/trunk/test/Bindings/llvm-c/set_metadata.ll (added)
+++ llvm/trunk/test/Bindings/llvm-c/set_metadata.ll Wed Jan 28 10:35:59 2015
@@ -0,0 +1,2 @@
+; RUN: llvm-c-test --set-metadata < /dev/null
+; This used to trigger an assertion

Modified: llvm/trunk/tools/llvm-c-test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-c-test/CMakeLists.txt?rev=227319&r1=227318&r2=227319&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-c-test/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-c-test/CMakeLists.txt Wed Jan 28 10:35:59 2015
@@ -41,6 +41,7 @@ add_llvm_tool(llvm-c-test
   include-all.c
   main.c
   module.c
+  metadata.c
   object.c
   targets.c
   )

Modified: llvm/trunk/tools/llvm-c-test/llvm-c-test.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-c-test/llvm-c-test.h?rev=227319&r1=227318&r2=227319&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-c-test/llvm-c-test.h (original)
+++ llvm/trunk/tools/llvm-c-test/llvm-c-test.h Wed Jan 28 10:35:59 2015
@@ -27,6 +27,10 @@ int calc(void);
 // disassemble.c
 int disassemble(void);
 
+// metadata.c
+int add_named_metadata_operand(void);
+int set_metadata(void);
+
 // object.c
 int object_list_sections(void);
 int object_list_symbols(void);

Modified: llvm/trunk/tools/llvm-c-test/main.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-c-test/main.c?rev=227319&r1=227318&r2=227319&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-c-test/main.c (original)
+++ llvm/trunk/tools/llvm-c-test/main.c Wed Jan 28 10:35:59 2015
@@ -65,6 +65,10 @@ int main(int argc, char **argv) {
     return disassemble();
   } else if (argc == 2 && !strcmp(argv[1], "--calc")) {
     return calc();
+  } else if (argc == 2 && !strcmp(argv[1], "--add-named-metadata-operand")) {
+    return add_named_metadata_operand();
+  } else if (argc == 2 && !strcmp(argv[1], "--set-metadata")) {
+    return set_metadata();
   } else {
     print_usage();
   }

Copied: llvm/trunk/tools/llvm-c-test/metadata.c (from r227318, llvm/trunk/tools/llvm-c-test/llvm-c-test.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-c-test/metadata.c?p2=llvm/trunk/tools/llvm-c-test/metadata.c&p1=llvm/trunk/tools/llvm-c-test/llvm-c-test.h&r1=227318&r2=227319&rev=227319&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-c-test/llvm-c-test.h (original)
+++ llvm/trunk/tools/llvm-c-test/metadata.c Wed Jan 28 10:35:59 2015
@@ -1,4 +1,4 @@
-/*===-- llvm-c-test.h - tool for testing libLLVM and llvm-c API -----------===*\
+/*===-- object.c - tool for testing libLLVM and llvm-c API ----------------===*\
 |*                                                                            *|
 |*                     The LLVM Compiler Infrastructure                       *|
 |*                                                                            *|
@@ -7,31 +7,33 @@
 |*                                                                            *|
 |*===----------------------------------------------------------------------===*|
 |*                                                                            *|
-|* Header file for llvm-c-test                                                *|
+|* This file implements the --add-named-metadata-operand and --set-metadata   *|
+|* commands in llvm-c-test.                                                   *|
 |*                                                                            *|
 \*===----------------------------------------------------------------------===*/
-#ifndef LLVM_C_TEST_H
-#define LLVM_C_TEST_H
 
-// helpers.c
-void tokenize_stdin(void (*cb)(char **tokens, int ntokens));
+#include "llvm-c-test.h"
+#include "llvm-c/Core.h"
 
-// module.c
-int module_dump(void);
-int module_list_functions(void);
-int module_list_globals(void);
+int add_named_metadata_operand(void) {
+  LLVMModuleRef m = LLVMModuleCreateWithName("Mod");
+  LLVMValueRef values[] = { LLVMConstInt(LLVMInt32Type(), 0, 0) };
+
+  // This used to trigger an assertion
+  LLVMAddNamedMetadataOperand(m, "name", LLVMMDNode(values, 1));
+
+  return 0;
+}
+
+int set_metadata(void) {
+  LLVMBuilderRef b = LLVMCreateBuilder();
+  LLVMValueRef values[] = { LLVMConstInt(LLVMInt32Type(), 0, 0) };
+
+  // This used to trigger an assertion
+  LLVMSetMetadata(
+      LLVMBuildRetVoid(b),
+      LLVMGetMDKindID("kind", 4),
+      LLVMMDNode(values, 1));
 
-// calc.c
-int calc(void);
-
-// disassemble.c
-int disassemble(void);
-
-// object.c
-int object_list_sections(void);
-int object_list_symbols(void);
-
-// targets.c
-int targets_list(void);
-
-#endif
+  return 0;
+}





More information about the llvm-commits mailing list