[llvm-dev] Adding MPX Intrinsics to X86 codegen

Przemek LeĊ›niak via llvm-dev llvm-dev at lists.llvm.org
Thu Nov 30 07:51:46 PST 2017


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)
  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

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?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171130/937562fe/attachment.html>

More information about the llvm-dev mailing list