[LLVMdev] DAG: specify dependency between nodes.

Dmitri Kovalenko dmitri.a.kovalenko at gmail.com
Sat Aug 30 04:51:46 PDT 2014


I'm struggling for a while with the following problem:
I have added couple of intrinsics which output result to the global
register.
They have form of: void intrinsic1(int,int) void intrinsic2(int,int,int).
Hence, they were getting removed from DAG on the first combine.
I was able to enforce their place in DAG by creating control flow
dependency between them.

That solved all problems in DAG, but llc fails in assert at InstrPrinter
call. Debugging shows that for 1-arg instruction, InstrPrinter tries to
access second arg.
So, it looks like adding root to DAG node as first arg of type MVT::Other
breaks accordance with respective instruction.

Now, I'm gonna get more specific and provide some code.
Instrisic looks in IR like that: call void @llvm.sparc.srxacc(i32 %0)

Creating node in SelectionDAGBuilder::visitIntrinsicCall:

  case Intrinsic::sparc_srxacc: {
    SDVTList nodeTys = DAG.getVTList(MVT::Other, MVT::i32);
    SDValue Ops[2];
    Ops[0] = getControlRoot();
    Ops[1] = getValue(I.getArgOperand(0));
    SDValue srCall = DAG.getNode(ISD::SRXACC, sdl, nodeTys, Ops);
    DAG.setRoot(srCall.getValue(0));
    return nullptr;
  }

Then, custom legalize it (SparcISelLowering):

static SDValue LowerSRXACC(SDValue Op, SelectionDAG &DAG,
                           const SparcTargetLowering &TLI) {
    SDLoc dl(Op);
    SDValue xacc = DAG.getRegister(SP::XACC, MVT::i32);
    SDVTList nodeTys = DAG.getVTList(MVT::Other, MVT::i32,
                                     MVT::i32);
    SDValue Ops[3];
    Ops[0] = Op.getOperand(0);
    Ops[1] = Op.getOperand(1);
    Ops[2] = xacc;

    return DAG.getNode(ISD::SRXACC, dl, nodeTys, Ops);
}

Then, select it (SparcISelDAGToDAG):

  case ISD::SRXACC: {
    SDVTList nodeTys = CurDAG->getVTList(MVT::i32);

    SDValue Ops[2];
    Ops[0] = N->getOperand(1);
    Ops[1] = N->getOperand(2);
    return CurDAG->SelectNodeTo(N, SP::SRXACC, nodeTys,
                                Ops);
  }

Corresponding instruction is:
def SRXACC : F3_1<2, 0b011101,
                   (outs IntRegs:$rd), (ins IntRegs:$rs1),
                   "srxacc $rs1, $rd", []>;

Please, note:
My problem is of self-educational and investigative nature.
This instruction srxacc and register xacc are not real.
Produced code aren't supposed to work anywhere.
I just need llc to be able to output assembly file.
Thanks for your insights.

-- 
Sincerely,
Dmitri Kovalenko
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140830/784cb1cf/attachment.html>


More information about the llvm-dev mailing list