BPF backend with vector operations - some strange error

Hello.
     I've tried to add some simple arithmetic vector operations to the BPF backend available in the LLVM repo. Because I added in BPFRegisterInfo.td another RegisterClass (taken from the Mips backend):
   def MSA128W: RegisterClass<"BPF", [v2i64, v2f64], 128,
                            (sequence "W%u", 0, 31)>;
in order to support vector for example, ADD operations, I get the following error when building llc:
   JEQ_ri: (BPFbrcc i64:i64:$dst, (imm:i64)<<P:Predicate_i64immSExt32>>:$imm, (imm:{i64:v4i32})<<P:Predicate_BPF_CC_EQ>>, (bb:Other):$BrDst)
Included from ~/LLVM/llvm38Nov2016/llvm/lib/Target/BPF/BPF.td:14:
~/LLVM/llvm38Nov2016/llvm/lib/Target/BPF/BPFInstrInfo.td:131:1: error: In JEQ_ri: Could not infer all types in pattern!
   defm JEQ : J<0x1, "jeq", BPF_CC_EQ>;

   The error is a bit cryptic - basically it seems that we can have 2 different value types (i64 and v4i32) for immediate operand imm. I guess this is because in BPFRegisterInfo.td I define also another RegisterClass:
   def GPR : RegisterClass<"Connex", [i64], 64, (add (sequence "R%u", 0, 31))>;

   Can somebody tell me how can I get rid of this <<Could not infer all types in pattern!>> error message? (I can provide more info, if required.)

   Thank you,
     Alex

Hello.
     I solved this issue (from the previous email).

     Got inspired from http://comments.gmane.org/gmane.comp.compilers.llvm.devel/73619, (also Redirecting to Google Groups), http://lists.llvm.org/pipermail/llvm-dev/2007-April/008843.html

     What I did was to edit ConnexInstrInfo.td and replaced all occurrences:
         PatLeaf<(imm)
        %(which were ambiguous since the variable name ("in dag operator") does not have a type and this poses issues to the Type inference algorithm, since I added in ConnexRegisterInfo.td a second RegisterClass with type v2i64)
     with
         PatLeaf<(i64 imm)
     namely:
        - def i64immSExt32 : PatLeaf<(i64 imm),
                 [{return isInt<32>(N->getSExtValue()); }]>;

   Best regards,
     Alex

Great that you found a solution.
Could you share what is the end goal for this vector instructions in BPF?
Are you actually trying to extend BPF ISA and add kernel support for it?
Or just using BPF backend as as a simplest/smallest playground?
Regardless please share the patches when they're ready. I'm curious
how you're adding vectorization. May be we can actually add them to kernel.

Hi, Alexei,
     I used the BPF back end as a "template" in order to write my own back end, for a completely different architecture. But sure, I can provide you with hints how to add vector instructions to BPF itself.

     BTW, just curious, where is actually the BPF processor being used?

   Best regards,
     Alex

Hello.
     I come back to this older thread.
     Again, because of i64immSExt32 I receive TableGen error "Could not infer all types in, pattern!" (exact details written below). So far I'm not able to generate selection code with TableGen for the ADD_r* instructions, etc:
            def i64immSExt32 : PatLeaf<(imm),
                 [{return isInt<32>(N->getSExtValue()); }]>;

     As in the case of Redirecting to Google Groups : "It seems that defining a new register class changes how the tblgen infers the types in the DAG patterns. So what is the right way to add a register class for a different type?"

     Please help.

   Thank you,
     Alex

Hello.
     Note: I'm using TableGen from Nov 2015 - I can't use the one from May 2016 directly - new errors appear in my current TableGen files. But if you advise I can switch to newest version of TableGen.

     The error that I described in the previous email down here is weird: when imm is
explicitly i64 instead of being polymorphic (and TableGen unifies it with i64 or v8i64 since now I have vector values and registers in my back end) the resulting GenDAGISel.inc has fundamental differences at MatcherTable.
     Is this a more hidden error of TableGen?

     More exactly, originally I had:
      def i64immSExt32 : PatLeaf<(imm),
          [{return isInt<32>(N->getSExtValue()); }]>;

     Since I get a few errors like:
       SLL_ri: (set GPR:i64:$dst, (shl:i64 GPR:i64:$src2, (imm:{i64:v8i64}):$imm))
       Included from Connex.td:26:
       Included from ConnexInstrInfo.td:22:
       ConnexInstrInfo_scalar.td:297:3: error: In SLL_ri: Could not infer all types in pattern!
       defm SLL : ALU<0x6, "sll", shl>;
       ^
       Included from Connex.td:26:
       Included from ConnexInstrInfo.td:22:
       ConnexInstrInfo_scalar.td:288:3: note: instantiated from multiclass
       def _ri : ALU_RI<Opc, OpcodeStr, OpNode>;
       ^

     I decided to use:
          def i64immSExt32 : PatLeaf<(i64 imm),
                   [{return isInt<32>(N->getSExtValue()); }]>;

    But:
     - My new GenDAGISel.inc has:
       /*928*/ /*SwitchOpcode*/ 30, TARGET_VAL(ISD::ADD),// ->961
       /*931*/ OPC_SwitchType /*2 cases */, 13, MVT::i64,// ->947
       /*934*/ OPC_RecordNode, // #0 = $addr
       /*935*/ OPC_CheckComplexPat, /*CP*/1, /*#*/0, // SelectFIAddr:$addr #1 #2
       /*938*/ OPC_MorphNodeTo, TARGET_VAL(Connex::FI_ri), 0,
                     1/*#VTs*/, MVT::i64, 2/*#Ops*/, 1, 2,.
                 // Src: FIri:i64:$addr - Complexity = 9
                 // Dst: (FI_ri:i64 FIri:i64:$addr)

       /*947*/ /*SwitchType*/ 11, MVT::v8i64,// ->960
       /*949*/ OPC_RecordChild0, // #0 = $ws
       /*950*/ OPC_RecordChild1, // #1 = $wt
       /*951*/ OPC_MorphNodeTo, TARGET_VAL(Connex::ADDV_D), 0,
                     1/*#VTs*/, MVT::v8i64, 2/*#Ops*/, 0, 1,.
                 // Src: (add:v8i64 MSA128DOpnd:v8i64:$ws, MSA128DOpnd:v8i64:$wt) - Complexity = 3
                 // Dst: (ADDV_D:v8i64 MSA128DOpnd:v8i64:$ws, MSA128DOpnd:v8i64:$wt)
       /*960*/ 0, // EndSwitchType
       /*961*/ /*SwitchOpcode*/ 69, TARGET_VAL(ISD::OR),// ->1033

      - and the original BPFGenDAGISel.inc has:
       /*807*/ /*SwitchOpcode*/ 53, TARGET_VAL(ISD::ADD),// ->863
       /*810*/ OPC_Scope, 15, /*->827*/ // 2 children in Scope
       /*812*/ OPC_RecordNode, // #0 = $addr
       /*813*/ OPC_CheckType, MVT::i64,
       /*815*/ OPC_CheckComplexPat, /*CP*/1, /*#*/0, // SelectFIAddr:$addr #1 #2
       /*818*/ OPC_MorphNodeTo, TARGET_VAL(BPF::FI_ri), 0,
                     1/*#VTs*/, MVT::i64, 2/*#Ops*/, 1, 2,.
                 // Src: FIri:i64:$addr - Complexity = 9
                 // Dst: (FI_ri:i64 FIri:i64:$addr)

       /*827*/ /*Scope*/ 34, /*->862*/
       /*828*/ OPC_RecordChild0, // #0 = $src2
       /*829*/ OPC_RecordChild1, // #1 = $imm
       /*830*/ OPC_Scope, 19, /*->851*/ // 2 children in Scope
       /*832*/ OPC_MoveChild, 1,
       /*834*/ OPC_CheckOpcode, TARGET_VAL(ISD::Constant),
       /*837*/ OPC_CheckPredicate, 0, // Predicate_i64immSExt32

       /*839*/ OPC_MoveParent,
       /*840*/ OPC_EmitConvertToTarget, 1,
       /*842*/ OPC_MorphNodeTo, TARGET_VAL(BPF::ADD_ri), 0,
                       1/*#VTs*/, MVT::i64, 2/*#Ops*/, 0, 2,.
                   // Src: (add:i64 GPR:i64:$src2, (imm:i64)<<P:Predicate_i64immSExt32>>:$imm) - Complexity = 7
                   // Dst: (ADD_ri:i64 GPR:i64:$src2, (imm:i64):$imm)
       /*851*/ /*Scope*/ 9, /*->861*/
       /*852*/ OPC_MorphNodeTo, TARGET_VAL(BPF::ADD_rr), 0,
                       1/*#VTs*/, MVT::i64, 2/*#Ops*/, 0, 1,.
                   // Src: (add:i64 i64:i64:$src2, i64:i64:$src) - Complexity = 3
                   // Dst: (ADD_rr:i64 i64:i64:$src2, i64:i64:$src)
       /*861*/ 0, /*End of Scope*/
       /*862*/ 0, /*End of Scope*/
       /*863*/ /*SwitchOpcode*/ 53, TARGET_VAL(ISD::OR),// ->919

   Best regards,
     Alex

Hello.
     I solved the problem: unfortunately, I commented a line sort of by mistake a few months back in InstrInfo.td:
      //defm ADD : ALU<0x0, "add", add>;

     This is the reason why I was obtaining an incomplete MatcherTable for ISD::ADD...
     I should have looked at the ISD::MUL entry in MatcherTable and see it was OK and check in the .td file why the differences for ADD vs MUL.

     Anyhow, the simple answer to the original problem in this thread is, as said back in Jan 2016, to use i64 type qualifier for imm:
        def i64immSExt32 : PatLeaf<(i64 imm),
            [{return isInt<32>(N->getSExtValue()); }]>;

     Sorry for writing in a hurry the previous 2 emails in this thread.

   Best regards,
     Alex