Our target has a load.idx opcode with the following semantics: load.idx r1,r2,r3, SIZE : r1 <- mem[r2 + (r3 << sizeof(operand))] (where sizeof(operand) is in the range 0..3 Here's a snippet of the DAG I want to match so that a load.idx instruction is selected: ... 0x30d29c0: i64 = Constant<3> 0x30d2e00: i64 = shl 0x30d2be0, 0x30d29c0 [ORD=3] 0x30d2f10: i64 = add 0x30d2cf0, 0x30d2e00 [ORD=3] 0x30d28b0: <multiple use> 0x30d3020: i64,ch = load 0x30a3ec0, 0x30d2f10, 0x30d28b0<LD8[%arrayidx16(addrspace=4)](tbaa=<0x3082188>)> [ORD=4] ... Here's what I'm trying in TargetInstrInfo.td: class Addr< int numArgs, string funcName, dag opInfo > : Operand<i64>, ComplexPattern< i64, numArgs, funcName, [], [SDNPWantParent] > { let MIOperandInfo = opInfo; } let PrintMethod = "printMemOperand" in { def ADDR_RR : Addr< 2, "SelectAddrRegReg", (ops GPRC:$base, GPRC:$offsetreg) >; def ADDR_RI : Addr< 2, "SelectAddrRegImm", (ops GPRC:$base, i64imm:$offsetimm) >; } def ADDR_I : Addr< 1, "SelectAddrImmLocal", (ops i64imm:$imm) >; def ADDR_SHLI : Addr< 2, "SelectAddrShlImm", (ops GPRC:$base, ( shl GPRC:$offsetreg, (i64 3))) >; ... multiclass LoadOp< bits<7> op, string instr_asm, OperandInfo info, InstrItinClass itin=II_LOAD1_RR > { let opsize = info.sizeCode in { ... // // store: mem[r2 + r3] = r1 // def _RR : FR3< op, (outs), (ins ADDR_RR:$addr, info.regClass:$r1), instr_asm # "\t\t$r1, $addr, " # info.sizeStr, [(store info.regClass:$r1, ADDR_RR:$addr)], itin > { let regcount = 5; // ISA change } // // load: r1 = mem[r2 + (r3 << sizeof(operand) ] // def _SHLI : FR3< op, (outs info.regClass:$r1), (ins ADDR_SHLI:$addr), //instr_asm#"\t$r1, $r2, $r3, "#info.sizeStr, instr_asm # "\t\t$r1, $addr, " # info.sizeStr, [(set info.regClass:$r1, (load ADDR_SHLI:$addr))], itin > { } ... } ... defm LOADI64_SHL : LoadOp< 0b1001100, "load.idx", OpInfo_I64 >; //end (Note: ADDR_RR, ADDR_RI, ADDR_I definitions already existed, I'm trying to add ADDR_SHLI). When I try to run llvm-tblgen with -gen-instr-info I get: llvm-tblgen: /home/phil/eqware/tg/tg/xe-llvm/include/llvm/Support/Casting.h:237: typename llvm::cast_retty<X, Y*>::ret_type llvm::cast(Y*) [with X llvm::DefInit; Y = llvm::Init; typename llvm::cast_retty<X, Y*>::ret_type llvm::DefInit*]: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed. The problem seems to be the (ins ADDR_SHLI:$addr in def _SHLI above. If I change it to: (ins ADDR_RR:$addr) it runs ok, but then it's not going to match what I'm trying to match. Am I going about this the right way or is there be a different approach? Phil -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160923/4dd13a75/attachment.html>