[llvm-dev] TableGen - Help to implement a form of gather/scatter operations for Mips MSA

Alex Susu via llvm-dev llvm-dev at lists.llvm.org
Sat Dec 10 19:31:09 PST 2016


   Hello.
     Will, thanks a lot for pointing me to the MaskedGatherSDNode and mgatherv4i32. I have 
to say that the definition of the "multiclass avx512_gather" from 
lib/Target/X86/X86InstrAVX512.td is difficult to follow and I prefer not to use it.

     I currently have some serious problems with TableGen - it gives an assertion failure: 
"llvm/utils/TableGen/CodeGenDAGPatterns.cpp:2153: llvm::TreePatternNode* 
llvm::TreePattern::ParseTreePattern(llvm::Init*, llvm::StringRef): Assertion 
`New->getNumTypes() == 1 && "FIXME: Unhandled"' failed."

     Can somebody help me with the code below responsible for this error?

     // From llvm/lib/Target/X86/X86InstrFragmentsSIMD.td
     def mgatherv128i16 : PatFrag<(ops node:$src1, node:$src2, node:$src3),
       (masked_gather node:$src1, node:$src2, node:$src3) , [{
       if (MaskedGatherSDNode *mgNode = dyn_cast<MaskedGatherSDNode>(N))
         return (mgNode->getIndex().getValueType() == MVT::v128i16 ||
                 mgNode->getBasePtr().getValueType() == MVT::v128i16);
       return false;
     }]>;

     foreach RegId = 0-31 in
         def Mask#RegId : MipsReg<0, "Mask"#RegId>, DwarfRegNum<[!add(RegId, 10)]>;
     def VK128: RegisterClass<"Connex", [v128i1], 32, (sequence "Mask%u", 0, 31)>;
     def VK128Opnd : RegisterOperand<VK128> {
       let ParserMatchClass = MSA128AsmOperand;
     }

     class LD_INDIRECT_DESC_BASE2<string instr_asm,
                     ValueType TyNode,
                     RegisterOperand ROWD,
                     RegisterOperand ROWSI = ROWD,
                     RegisterOperand ROWSP = ROWD, // passthru register
                     InstrItinClass itin = NoItinerary> {
       dag OutOperandList = (outs ROWD:$wd);
       dag InOperandList = (ins ROWSP:$wsp, VK128Opnd:$wsm, ROWSI:$wsptr, ROWSI:$wsi);
       string AsmString = "$wd = LS[R($wsi )];";
       list<dag> Pattern = [(set ROWD:$wd, (TyNode (masked_gather ROWSP:$wsp, VK128Opnd 
:$wsm, ROWSI:$wsptr, ROWSI:$wsi)))];
       InstrItinClass Itinerary = itin;
       string DecoderMethod = "DecodeMSA128Mem";
     }
     class LD_INDIRECT_D_DESC2 : LD_INDIRECT_DESC_BASE2<"read", v128i16, MSA128DOpnd>;
     class LD_INDIRECT_D_ENC2 : MSA_2R_FMT<0b101001110>;
     def LD_INDIRECT_D2: LD_INDIRECT_D_ENC2, LD_INDIRECT_D_DESC2;

     /*
     // From http://llvm.org/docs/doxygen/html/SelectionDAGNodes_8h_source.html:
         02115   // In the both nodes address is Op1, mask is Op2:
         02116   // MaskedGatherSDNode  (Chain, src0, mask, base, index), src0 is a 
passthru value
         02117   // MaskedScatterSDNode (Chain, value, mask, base, index)
         02118   // Mask is a vector of i1 elements
         02119   const SDValue &getBasePtr() const { return getOperand(3); }
         02120   const SDValue &getIndex()   const { return getOperand(4); }
         02121   const SDValue &getMask()    const { return getOperand(2); }
         02122   const SDValue &getValue()   const { return getOperand(1); } // Alex: this 
is pass-thru

     */


   Thank you very much,
     Alex

On 12/9/2016 4:18 PM, Will Lovett wrote:
> Hi Alex,
>
> I don’t know too much about recent MIPS, but have recently been doing something similar
> for the new ARM SVE architecture, so hopefully this will get you closer to what you need:
>
> If you’re looking where I think you are (lib/Target/X86/X86InstrAVX512.td), ‘GatherNode’
> is a template argument, not a definition.
> It allows a PatFrag be passed into the avx512_gather multiclass definition.
>
> Working backwards from here, the actual PatFrags passed into this are things like
> ‘mgatherv4i32’.  These are patterns that match a MaskedGatherSDNode for a particular data
> type.
>
> MaskedGatherSDNode is the generic SD node that represents a predicated gather, which in
> turn was generated from Intrinsic::masked_gather in the IR
> (in SelectionDAGBuilder::visitMaskedGather)
>
> If your MIPS instruction has a predicate, you will need to create MIPS tablegen that
> matches MaskedGatherSDNode.  If not, I guess you’ll need to create a new intrinsic that
> represents an unpredicted gather, and add appropriate uses of it during IR creation (such
> as in LoopVectorize, where masked gathers are created today)
>
> Hope that helps,
>
> Will Lovett
>
>
> On 9 December 2016 at 01:52:48, Alex Susu via llvm-dev (llvm-dev at lists.llvm.org
> <mailto:llvm-dev at lists.llvm.org>) wrote:
>
>> Hello.
>> I read on page 4 of http://www.cs.fsu.edu/~whalley/cda5155/chap4.pdf that gather and
>> scatter operations exist for Mips, named LVI and SVI, respectively.
>>
>> Did anyone think of implementing in the LLVM Mips back end (part of the MSA vector
>> instructions) gather and scatter operations?
>> If so, can you share with me the TableGen spec? (I tried to start from LD_DESC_BASE,
>> but it doesn't seem to be trivial. Also, LLVM seems to have implemented scatter/gather
>> instructions only for the x86 processor - there, they defined new SDNodes called
>> GatherNode and ScatterNode.)
>>
>> Thank you,
>> Alex
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev


More information about the llvm-dev mailing list