Hello.
I wanted to inform that I fixed the bug from the previous email.
The main reason for the bug was that I thought that the SDNode masked_gather is returning only 1 value, but it returns 2 (hence, I guess, the earlier reported, difficult to follow, error: "Assertion `New->getNumTypes() == 1").
masked_gather returns 2 values because:
// SDTypeProfile - This profile describes the type requirements of a Selection
// DAG node.
class SDTypeProfile<int numresults, int numoperands,
list<SDTypeConstraint> constraints> {
int NumResults = numresults;
int NumOperands = numoperands;
list<SDTypeConstraint> Constraints = constraints;
}
// So: 2 results, 3 operands.
// Params are: passthru, mask, index; results are: vector of i1, ptr!!
// Params are 0, 1, 2 and results are 3, 4.
// Opnds 0 and 1 have vector type, with same number of elements.
// Opnds 0 and 2 have identical types.
// Opnds 1 and 3 have identical types.
// --> Opnd 3 (result 0?) is i1 vector
// Opnd 4 (result 1?) has pointer type.
// Opnd 1 is vector type with element type of i1.
def SDTMaskedGather: SDTypeProfile<2, 3, [ // masked gather
SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<1, 3>,
SDTCisPtrTy<4>, SDTCVecEltisVT<1, i1>, SDTCisSameNumEltsAs<0, 1>
]>;
def masked_gather : SDNode<"ISD::MGATHER", SDTMaskedGather,
[SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
Also, we need to make the operand $wsi a memory operand (otherwise we get the difficult error: <<In LD_INDIRECT_D2: Type inference contradiction found, 'v128i16' needs to be scalar>>), like in the following complete specification:
// Inspired heavily from lib/Target/X86/X86InstrInfo.td
class X86MemOperand<string printMethod> : Operand<iPTR> {
let PrintMethod = printMethod;
let MIOperandInfo = (ops i8imm, i32imm);
let OperandType = "OPERAND_MEMORY";
}
// Gather mem operands
class X86VMemOperand<RegisterClass RC, string printMethod>
: X86MemOperand<printMethod> {
let MIOperandInfo = (ops i8imm, RC, i32imm);
}
def vx256xmem : X86VMemOperand<MSA128D, "printi256mem">;
def vectoraddr : ComplexPattern<iPTR, 5, "selectVectorAddr", ,[SDNPWantParent]>;
class LD_INDIRECT_DESC_BASE2<string instr_asm,
RegisterOperand ROWD,
RegisterOperand ROWSP = ROWD,
InstrItinClass itin = NoItinerary> {
dag OutOperandList = (outs ROWD:$wd, VK128Opnd:$wdm);
dag InOperandList = (ins ROWSP:$wsp, VK128Opnd:$wsm, vx256xmem:$wsi);
string AsmString = !strconcat("$wd = LS[$wsi]; // iread (or Mips MSA's LD) strinstr_asm = ",
instr_asm);
list<dag> Pattern = [(set ROWD:$wd, VK128Opnd:$wdm,
(masked_gather
ROWSP:$wsp, VK128Opnd:$wsm, vectoraddr:$wsi))];
InstrItinClass Itinerary = itin;
string DecoderMethod = "DecodeMSA128Mem";
}
class LD_INDIRECT_D_DESC2 : LD_INDIRECT_DESC_BASE2<"read", MSA128DOpnd>;
class LD_INDIRECT_D_ENC2 : MSA_3R_FMT<0b101001110>;
def LD_INDIRECT_D2: LD_INDIRECT_D_ENC2, LD_INDIRECT_D_DESC2;
Unfortunately, now I have another problem: llc fails when trying to select my masked_gather node. More exactly, it first tries to split it and then gives an error:
Split node operand: t13: v128i16,ch = masked_gather<LD256[<unknown>]> t0, t23, t40, TargetConstant:i64<0>, t24
Widen node result 0: t46: v64i16 = extract_subvector t23, Constant:i64<64>
Widen node result 0: t48: v64i16,ch = masked_gather<LD128[<unknown>](align=256)> t0, t46, t44, TargetConstant:i64<0>, t26
Split node result: t121: v128i64 = BUILD_VECTOR Constant:i64<0>, Constant:i64<0>, Constant:i64<0>, Constant:i64<0>, Constant:i64<0>, Constant:i64<0>, Constant:i64<0>, Constant:i64<0>, Constant:i64<0>, Constant:i64<0>, Constant:i64<0>, Constant:i64<0>, Constant:i...
Split node result: t123: v64i64 = BUILD_VECTOR undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:...
Split node result: t124: v32i64 = BUILD_VECTOR undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:...
Split node result: t125: v16i64 = BUILD_VECTOR undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64...
Split node result: t126: v8i64 = BUILD_VECTOR undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64, undef:i64...
Split node result: t127: v4i64 = BUILD_VECTOR undef:i64, undef:i64, undef:i64, undef:i64...
Split node result: t128: v2i64 = BUILD_VECTOR undef:i64, undef:i64
Split node operand: t122: v128i16,ch = masked_gather<LD128[<unknown>](align=256)> t0, t130, t193, TargetConstant:i64<0>, t121
llc: /home/asusu/LLVM/llvm38Nov2016/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:6804: llvm::MemSDNode::MemSDNode(unsigned int, unsigned int, const llvm::DebugLoc&, llvm::SDVTList, llvm::EVT, llvm::MachineMemOperand*): Assertion `memvt.getStoreSize() <= MMO->getSize() && "Size mismatch!"' failed.
Does anybody know why this happens? I'd like to mention that I also gave in [Target]ISelLowering.cpp a call to setOperationAction(ISD::MGATHER, aType, Legal), which should have fixed this problem, but it doesn't.
Best regards,
Alex