codeGen, instruction write one value to the input register.

Hi Guys,

In LLVM codegen,a typical binary operation instruction is defined something like below:

" def _rr: NVPTXInst<(outs Int1Regs:$dst), (ins Int1Regs:$a, Int1Regs:$b),
“xor.pred \t$dst, $a, $b;”,
[(set Int1Regs:$dst, (OpNode Int1Regs:$a, Int1Regs:$b))]>;

which takes two inputs and write the result to the $dst register.

Then how to define a binary instruction which returns two results, one is written to the $dst register, and the other one is written to one of the inputs? I mean, to implement something like:

Type sincos( Type input, Type * cosVal)

the instruction will compute sin and cos value of input, return the sin result and write the cos result to cosVal.
Is there anything special constraints or something I should put onto the cos register?

Best

Kevin

Hey Kevin,

You might get a good start looking at the AVX2 VGATHER patterns in
llvm/lib/Target/X86/X86InstrSSE.td. Those patterns return two results.
They also make use of the @earlyclobber constraint.

Hope that helps,
Cameron

Tks Cameron,

I did some study on it.

Now I am having the same problem as mentioned in this thread;"http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-January/057654.html” ,

><i> Looking at the X86 back-end code, it looks like there do exist
</i>><i> multi-output instructions, but they all use physical (implicit) registers
</i>><i> for the second destination, not arbitrary register types.  And if I change
</i>><i> the second destination to be a certain physical register, this problem goes
</i>><i> away in my code.  Is this just not a supported case currently?  Or am I
</i>> *doing something wrong?*

Wondering if there is any update about it?

best

kevin

Now I am having the same problem as mentioned in this
thread;"http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-January/057654.html”

[...]

Wondering if there is any update about it?

This has been a known issue since almost the beginning of LLVM from
what I've picked up (certainly long before I'd even heard of the
project). There hasn't been any progress since those messages, I'm
afraid: for two or more generic outputs you need C++ for ISel
(usually).

Cheers.

Tim.

Hi All,

In XCore backend, I saw

……

EVT VT = Op.getValueType();
SDValue Data =
DAG.getNode(XCoreISD::CRC8, DL, DAG.getVTList(VT, VT),
Op.getOperand(1), Op.getOperand(2) , Op.getOperand(3));
SDValue Crc(Data.getNode(), 1);
SDValue Results[] = { Crc, Data };
return DAG.getMergeValues(Results, 2, DL);

“ which is used to lower an instruction that returns two values.

I am trying to something like this:

…….
SDValue z = DAG.getNode(my_ISD::test_op, DL, VT, Op.getOperand(0);
SDValue w = DAG.getConstant(1, MVT::i32);

SDValue DataZ = DAG.getNode(ISD::BUILDER_VECTOR, DL, MVT::v4i32, z, z, z, z);

SDValue DataW = DAG.getNode(ISD::BUILDER_VECTOR, DL, MVT::v4i32, w, w, w, w);
SDValue result[] = {DataZ, DataW};
return DAg.getMergeValues(results, 2, DL);


but my view-dag only shows one return value, wondering what is wrong?
should the results dags must be somehow “dependent” on each other?

Best

kevin

Hi Kevin,

It's quite difficult to tell exactly what's going wrong here without
more context. If you could post a screenshot (or similar) of the
viewDAG output before and after, that would be very helpful. Or
describe in more detail what you're expecting to see but don't.

Hi Tim,

Thank you for the quick answer.
basically my first step is to solve the my_sincos(v4f32). which returns sin and cos results into two separate vector registers.
I have sin, and cos target instructions.

so my plan is to lower it like the following when I see the “sincos(v4f32)” node.

SDValue sin = DAG.getNode(my_ISD::sin, DL, VT, Op.getOperand(0);
SDValue cos = DAG.getNode(my_ISD::cos, DL, VT, Op.getOperand(0);

SDValue sinVal = DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v4f32, sin, sin, sin, sin);
SDValue cosVal = DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v4f32, cos, cos, cos, cos);

SDValue results[] = {sinVal, cosVal};
return DAG.getMergeValues(results, 2, DL);
"

So in a test, I am expecting the my_sincos(v4f32) node should appears have two return values in view-dag-combine1-dags even I am using only sinVal.

best

Kevin

so my plan is to lower it like the following when I see the “sincos(v4f32)” node.

SDValue sin = DAG.getNode(my_ISD::sin, DL, VT, Op.getOperand(0);
SDValue cos = DAG.getNode(my_ISD::cos, DL, VT, Op.getOperand(0);

SDValue sinVal = DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v4f32, sin, sin, sin, sin);
SDValue cosVal = DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v4f32, cos, cos, cos, cos);

SDValue results[] = {sinVal, cosVal};
return DAG.getMergeValues(results, 2, DL);
"

So in a test, I am expecting the my_sincos(v4f32) node should appears
have two return values in view-dag-combine1-dags even I am using only
sinVal.

The code looks reasonable in isolation. But I wouldn't expect this to
show up in dag-combine1-dags: that's before even type legalization
happens. Very little of your custom lowering code will have run at
that stage (function arg/return values only, pretty much).

Perhaps try attaching a debugger and calling DAG.viewGraph() manually
just after your code has run.

Cheers.

Tim.