[llvm-dev] Problems with Inline ASM expressions generated in the back end

Alex Susu via llvm-dev llvm-dev at lists.llvm.org
Thu Nov 10 09:05:11 PST 2016


   Hello.
     I managed to fix this bug (at least for the tests I have). It is a bit weird - the 
error is at the creation of a (less-standard) MDNode like this:
          // Creating an SDNode MDNode<null> (MetaData) with a ch out port
          SDValue mdNode = CrtDAG->getNode(ISD::MDNODE_SDNODE, DL,
                                     CrtDAG->getVTList(MVT::Other)
                                     );
          SDNode *mdNodeSDNode = mdNode.getNode();

     This code generates an error if we generate 2 or more of these nodes in the compiled 
ASM module generated. Note that sometimes the error message is less complete - but the 
error manifests exactly when printing the MDNode, since it stops  after printing the tag 
"[attdialect]" for the INLINEASM node. I wasn't able to understand well why this error is 
happening - probably it has something with the null metadata.


     The code that does not produce the bug (w.r.t. the above) is the following:
         /* Creating a NON-null-MDNode MDNodeSDNode object (has a
                  hexadecimal value when outputing the DOT file).
           From http://llvm.org/docs/doxygen/html/classllvm_1_1MDNode.html:
           Detailed Description
             Metadata nodes can be uniqued, like constants, or distinct.
         */
         MDNode *mdNode = MDNode::get(* (CrtDAG->getContext()), None);

         /*
         From http://llvm.org/docs/doxygen/html/classllvm_1_1SelectionDAG.html
                <<SDValue getMDNode (const MDNode *MD)
              	Return an MDNodeSDNode which holds an MDNode.>>
         */
         SDNode *mdNodeSDNode = CrtDAG->getMDNode(mdNode).getNode();

   Best regards,
     Alex


On 10/29/2016 3:25 AM, Alex Susu wrote:
>   Hello.
>     I generated in the back end by hand (in C++ code, not with TableGen) some fancy
> assembly code using Inline ASM expressions and if I use 2 functions in my source code (but
> NOT just 1 function; I will not present the functions, but each requires me to generate an
> Inline ASM expression) I get this error at compilation (at scheduling):
>           BB#0: derived from LLVM BB %entry
>             Live Ins: %R1 %R2
>                 %vreg6<def> = COPY %R2; GPR:%vreg6
>                 %vreg5<def> = COPY %R1; GPR:%vreg5
>                 %vreg12<def> = VLOAD_D_WO_IMM; MSA128D:%vreg12 dbg:IfVectorize.c:39:5
>                 INLINEASM <es:    (Param1 -  Param2); // MSA_I10> [sideeffect]
> [attdialect], <llc: /llvm/include/llvm/Support/Casting.h:237: typename llvm::cast_retty<X,
> Y*>::ret_type llvm::cast(Y*) [with X = llvm::ValueAsMetadata; Y = const llvm::Metadata;
> typename llvm::cast_retty<X, Y*>::ret_type = const llvm::ValueAsMetadata*]: Assertion
> `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
>         #0 0x00007f50baa5c700 llvm::sys::PrintStackTrace(llvm::raw_ostream&)
> /llvm/lib/Support/Unix/Signals.inc:402:0
>         #1 0x00007f50baa5ca9a PrintStackTraceSignalHandler(void*)
> /llvm/lib/Support/Unix/Signals.inc:470:0
>         #2 0x00007f50baa5ab55 llvm::sys::RunSignalHandlers()
> /llvm/lib/Support/Signals.cpp:44:0
>         ...
>         #8 0x00007f50b9904c82 (/lib/x86_64-linux-gnu/libc.so.6+0x2dc82)
>         #9 0x00007f50bc68f6e4 llvm::cast_retty<llvm::ValueAsMetadata, llvm::Metadata
> const*>::ret_type llvm::cast<llvm::ValueAsMetadata, llvm::Metadata const>(llvm::Metadata
> const*) /llvm/include/llvm/Support/Casting.h:239:0
>         #10 0x00007f50bc679010 WriteAsOperandInternal(llvm::raw_ostream&, llvm::Metadata
> const*, (anonymous namespace)::TypePrinting*, llvm::SlotTracker*, llvm::Module const*,
> bool) /llvm/lib/IR/AsmWriter.cpp:2045:0
>         #11 0x00007f50bc680e2c printMetadataImpl(llvm::raw_ostream&, llvm::Metadata
> const&, llvm::ModuleSlotTracker&, llvm::Module const*, bool)
> /llvm/lib/IR/AsmWriter.cpp:3504:0
>         #12 0x00007f50bc680fcc llvm::Metadata::printAsOperand(llvm::raw_ostream&,
> llvm::ModuleSlotTracker&, llvm::Module const*) const /llvm/lib/IR/AsmWriter.cpp:3520:0
>         #13 0x00007f50bd2ee8e2 llvm::MachineOperand::print(llvm::raw_ostream&,
> llvm::ModuleSlotTracker&, llvm::TargetRegisterInfo const*) const
> /llvm/lib/CodeGen/MachineInstr.cpp:449:0
>         #14 0x00007f50bd2f4141 llvm::MachineInstr::print(llvm::raw_ostream&,
> llvm::ModuleSlotTracker&, bool) const /llvm/lib/CodeGen/MachineInstr.cpp:1770:0
>         #15 0x00007f50bd288580 llvm::MachineBasicBlock::print(llvm::raw_ostream&,
> llvm::ModuleSlotTracker&, llvm::SlotIndexes const*) const
> /llvm/lib/CodeGen/MachineBasicBlock.cpp:295:0
>         #16 0x00007f50bd2da1cf llvm::MachineFunction::print(llvm::raw_ostream&,
> llvm::SlotIndexes const*) const /llvm/lib/CodeGen/MachineFunction.cpp:442:0
>         #17 0x00007f50baffedb1
> llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&)
> /llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:662:0
>
>
>     My code that creates an inline ASM expression (in ConnexISelDAGToDAG.cpp, method
> Select) looks something like this:
>         /* IMPORTANT: it seems we must malloc the char * that is
>              passed to getTargetExternalSymbol as a reference, so
>              we must make sure the value persists after we get out of
>              this function.
>              Hopefully no leak will happen either - maybe when deleting
>                SDNode the destructor frees the char *.
>
>            // This seems to be so because of this method doing
>            creation of the SDNode, which is used also by
>            getTargetExternalSymbol():
>             template <typename SDNodeT, typename... ArgTypes>
>               SDNodeT *newSDNode(ArgTypes &&... Args) {
>                 return new (NodeAllocator.template Allocate<SDNodeT>())
>                     SDNodeT(std::forward<ArgTypes>(Args)...);
>             }
>         */
>         char *exprStrChar = (char *)malloc(2048);
>         strcpy(exprStrChar, "test... ...");
>         SDValue extSym = CurDAG->getTargetExternalSymbol(
>                                                   exprStrChar,
>                                                   MVT::i64);
>         SDNode *extSymNode = extSym.getNode();
>
>         std::vector<SDValue> opsRes;
>
>         opsRes.push_back(SDValue(vloadSpecial, 0));
>
>         opsRes.push_back(extSym);
>
>         // Creating an SDNode MDNode<null> (MetaData) with a ch out port
>         SDNode *mdNodeSDNode = CurDAG->getNode(ISD::MDNODE_SDNODE, DL,
>                                 CurDAG->getVTList(MVT::Other)).getNode();
>
>         opsRes.push_back(SDValue(mdNodeSDNode, 0));
>
>         SDValue targetConstant = CurDAG->getTargetConstant(1, DL, MVT::i64);
>         SDNode *targetConstantSDNode = targetConstant.getNode();
>         opsRes.push_back(SDValue(targetConstantSDNode, 0));
>
>
>         SDValue inlineAsm = CurDAG->getNode(ISD::INLINEASM, DL,
>                                 CurDAG->getVTList(MVT::Other, MVT::Glue),
>                                 opsRes);
>
>         SDNode *inlineAsmNode = inlineAsm.getNode();
>         ...
>
>
>
>     Does anyone have an idea why is this happening.
>
>
>   Thank you very much,
>     Alex


More information about the llvm-dev mailing list