Strange behavior when trying to use MDString and ConstantAsMetadata with MDNode


I stumbled across some strange behavior when trying to use MDString and ConstantAsMetadata. I was trying to pass some metadata to a target intrinsic using MetadataAsValue. To do that I first wrapped the Metadata in an MDNode and then used that MDNode with MetadataAsValue to pass it as an argument to the intrinsic. I used the following code to do that:

 llvm::Metadata \*Meta;
 llvm::MDNode \*Node = llvm::MDNode::get\(getLLVMContext\(\), Meta\);
 Value \*Val = llvm::MetadataAsValue::get\(getLLVMContext\(\), Node\);

Meta can either be MDString or ConstantAsMetadata:

 if \(Foo\)
   Meta = llvm::MDString::get\(getLLVMContext\(\), SomeString\)
   Meta = llvm::ConstantAsMetadata::get\(Builder\.getInt32\(SomeInt\)\)

This works for MDString but breaks for ConstantAsMetadata when the intrinsic hits the backend. There, the IRTranslator uses the following code to translate metadata arguments:

 if \(auto MD = dyn\_cast<MetadataAsValue>\(Arg\.value\(\)\)\) \{
   auto \*MDN = dyn\_cast<MDNode>\(MD\->getMetadata\(\)\);
   if \(\!MDN\) // This was probably an MDString\.
     return false;

If Meta was the MDString, this works fine. However if Meta is ConstantAsMetadata, the dynamic cast to MDNode fails, causing compilation to fail. I'm wondering why this is happening, since I am wrapping Meta in an MDNode. Although I can't test this with SelDAG, the code there is similar to the one IRTranslator. So this is not a problem with the IRTranslator, but rather some seemingly strange behavior of how Metadata appears to work.

By the way, if I wrap an MDString AND a ConstantAsMetadata in an MDNode, everything works as expected. This problem only occurs if I try to use a single ConstantAsMetadata with MDNode.

Can anybody tell me what's going on here?