[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