[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