[LLVMdev] DAG: specify dependency between nodes.

Tom Stellard tom at stellard.net
Tue Sep 2 07:25:16 PDT 2014


On Sat, Aug 30, 2014 at 03:51:46PM +0400, Dmitri Kovalenko wrote:
> 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);
>   }

Here you are adding two inputs to an instruction defined as
having only one input.  Is N->getOperand(1) supposed to be the
output register?

-Tom

> 
> 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

> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev




More information about the llvm-dev mailing list