<div dir="auto"><div><div class="gmail_quote"><br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">







<div bgcolor="white" lang="EN-GB" link="#0563C1" vlink="#954F72">
<div class="m_4338375225339091784WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt">Hey,<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">I’ve been working on custom lowering ISD::UMUL_LOHI and ISD::SMUL_LOHI. Our target has some legal vector types but no support for these so would like to mark them as Expand. This yields “Cannot unroll a vector
 with multiple results!” from the default case in VectorLegalizer::Expand. Hence custom lowering. All the types are legal at this stage.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">I would appreciate some clarification on how custom lowering of nodes with multiple return values behaves. My theory is:<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">- The lowering function is called once per ResNo<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">- On each invocation, generate an SDValue for each ResNo<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">- Generate an ISD::MERGE_VALUES nodes to combine all of these SDValues<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">- Mutate the ResNo in the SDValue wrapping the ISD::MERGE_VALUES to match the input ResNo<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">If that’s the right way to go, great. Confirmation would be appreciated.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">My first few attempts involved only generating an SDValue for the requested ResNo (which asserts when asked for ResNo == 1 and returning ResNo == 0) and returning a ISD::MERGE_VALUES without mutating the ResNo
 (which leads to constant folding merging the two result values together, effectively dropping the second one).<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">The code I based this on is LowerXALUO in AArch64ISelLowering which returns a MERGE_VALUES without mutating the ResNo. I’m concerned that AArch64 may be dropping the carry bit based on the semantics observed
 above, but don’t know AArch64 well enough to verify.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">SDValue MyTarget::LowerXMUL_LOHI(<wbr>SDValue Op, SelectionDAG &DAG) const {<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  EVT VT = Op.getValueType();<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  SDLoc dl(Op);<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  unsigned Opc = Op.getOpcode();<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  unsigned ResNo = Op.getResNo();<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  assert(Opc == ISD::UMUL_LOHI || Opc == ISD::SMUL_LOHI);<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  assert(ResNo == 0 || ResNo == 1);<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  SDValue Op0 = Op.getOperand(0);<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  SDValue Op1 = Op.getOperand(1);<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  unsigned MULHXOpcode = Opc == ISD::UMUL_LOHI ? ISD::MULHU : ISD::MULHS;<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  SDValue res[2] = { // Seems wasteful to generate both of these twice per node<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">    DAG.getNode(ISD::MUL, dl, VT, Op0, Op1),<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">    LowerMULHX(DAG.getNode(<wbr>MULHXOpcode, dl, VT, Op0, Op1), DAG),<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  };<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  SDVTList VTs = DAG.getVTList(VT, VT);<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  SDNode * N =  DAG.getNode(ISD::MERGE_VALUES, dl, VTs, res[0], res[1]).getNode();<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  return SDValue(N,Op.getResNo()); // AArch64 doesn’t do this<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">}<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">The above is weird in at least two respects. It generates an ISD::MUL when ResNo == 1, which will then be dropped elsewhere, and likewise the result of custom lowering MULHX when ResNo == 0. It also mutates
 the ResNo before returning, but without that codegen just drops the second half of the lowering.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">The reference from AArch64 is:<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">SDVTList VTs = DAG.getVTList(Op.getValueType(<wbr>), MVT::i32);<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">return DAG.getNode(ISD::MERGE_VALUES, dl, VTs, Value, Overflow);<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Am I on the right track here?<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Cheers!<font color="#888888"><u></u><u></u></font></span></p><font color="#888888">
<p class="MsoNormal"><span style="font-size:11.0pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Jon<u></u><u></u></span></p>
</font></div>
</div>

</blockquote></div><br></div></div>