[llvm-dev] Pattern matching question

Phil Tomson via llvm-dev llvm-dev at lists.llvm.org
Fri Sep 23 12:48:38 PDT 2016


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>


More information about the llvm-dev mailing list