Przemek Leśniak via llvm-dev
2017-Nov-30 15:51 UTC
[llvm-dev] Adding MPX Intrinsics to X86 codegen
Hello I'm working on adding MPX instruction intrinsics to llvm for research purposes (it's for my use only, and it doesn't necessarily have to be merged into LLVM, so don't worry about design). I've spent some time trying to figure out how to add this, but I'm making progress very slowly so I decided to ask for some help. The problem: To describe problem more precisely, what I want to have is intrinsic usable in IR that maps to one instruction. Simplest example is probably 'bndcl' instruction that takes 'bnd' register, integer (can be address in memory, or value in gpr) and checks if address is bounded from the bottom by bnd register. Its corresponding intrinsic can look like this: declare void @llvm.x86.mpx.bndcl(<2 x i64>, i64) The type <2 x i64> is because bnd register is 128-bit register that holds two addresses (upper and lower bound), it also corresponds to how bnd registers are defined in LLVM (as <2 x i64>). The type i64 is because it does bound checking on address, I think it can be a i8* type as well, but I had some problems generating intrinsics. Using this instruction would generate bndcl instruction in resulting code using the register where <2 x i64> value is stored and comparing it against address of the pointer. What I did: According to the documentation (the Extending LLVM document: https://llvm.org/docs/ExtendingLLVM.html), I'm supposed to add the intrinsics to IntrinsicsX86.td so that the code generator sees it. I've added the intrinsic (IntrinsicsX86.td): let TargetPrefix = "x86" in { def int_x86_mpx_bndcl: Intrinsic<[], [llvm_v2i64_ty, llvm_i64_ty], [IntrNoMem]>; } And checked whether there is any error using llc on the code: define void @intel_mpx(<2 x i64> %bnd, i64 %ptr) { entry: call void @llvm.x86.mpx.bndcl(<2 x i64> %bnd, i64 %ptr) ret void } declare void @llvm.x86.mpx.bndcl(<2 x i64>, i64) nounwind And there was an error: 2. Running pass 'X86 DAG->DAG Instruction Selection' on function '@intel_mpx' Reading a bit through the documentation and looking and other examples made me realise that I need to add pattern for the Intrinsic. Probably in the file X86InstrMPX.td: multiclass mpx_bound_check<bits<8> opc, string OpcodeStr> { let mayLoad = 1 in { def 32rm: I<opc, MRMSrcMem, (outs), (ins BNDR:$src1, i32mem:$src2), OpcodeStr#"\t{$src2, $src1|$src1, $src2}", [ pattern ]>, Requires<[HasMPX, Not64BitMode]>; def 64rm: RI<opc, MRMSrcMem, (outs), (ins BNDR:$src1, i64mem:$src2), OpcodeStr#"\t{$src2, $src1|$src1, $src2}", [ pattern ]>, Requires<[HasMPX, In64BitMode]>; } def 32rr: I<opc, MRMSrcReg, (outs), (ins BNDR:$src1, GR32:$src2), OpcodeStr#"\t{$src2, $src1|$src1, $src2}", [ pattern ]>, Requires<[HasMPX, Not64BitMode]>; def 64rr: RI<opc, MRMSrcReg, (outs), (ins BNDR:$src1, GR64:$src2), OpcodeStr#"\t{$src2, $src1|$src1, $src2}", [ pattern ]>, Requires<[HasMPX, In64BitMode]>; } This is where real difficulty appears. I need to add correct pattern in brackets that have "pattern" inside (and this muliclass has to be parametrised with Intrinsic probably, or split into smaller subclasses as other instructions 'bndcu' and 'bndcn' are defined using this template). I've been experimenting with this for a while and nothing seems to work. I need to make sure that my intrinsic somehow matches against general purpose register (GR32 / GR64 registers) and memory address (i32mem / i64mem) which also brings some problems. Keep in mind that I've been focusing only on 64 bit version to make things a little bit simpler. Is there any good soul that could help me with this? Thanks, Przemek -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171130/937562fe/attachment.html>