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

Alex Susu via llvm-dev llvm-dev at lists.llvm.org
Fri Oct 28 17:25:16 PDT 2016


   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