X86WrapperRIP in non-small code model

Currently it appears X86WrapperRIP is only implemented in the small code model, which causes code to fail to select in other code models. My particular use case is MCJIT, where the default code model is large (the X86WrapperRIP comes from a TLS variable reference). What would be the best way to implement this? I’d be happy to take a crack at it myself, but I really don’t know my way around the backend code, so I’d need some guidance (e.g. how I insert the necessary movabs instructions).


Here's the relevant comment in X86DAGToDAGISel::MatchWrapper():

      // Under X86-64 non-small code model, GV (and friends) are 64-bits, so
      // they cannot be folded into immediate fields.

When you put together CodeModel = Large and x86_64, it means that code might land more than 2^31 bytes away from the data. (Hypothetically 2^64 bytes away, but really the max is something like 2^48.) 2^31 is the magic number for RIP: a RIP-relative relocation involves a signed 32-bit offset from the instruction pointer. Hence, for the code generator to be able to safely use RIP-relative relocations, the JIT needs to guarantee that it will place code within 2^31 bytes of data. The MCJIT, by default, uses a memory management scheme that may place code and data arbitrarily far apart, and so it cannot guarantee the 2^31 distance. That's what "Large CodeModel" means: it's the JIT's way of saying to the codegen, "I cannot guarantee distances between sections".

If you really want to use RIP-relative relocations, the best way to approach this is to:

1) Create your own JIT memory manager and make sure that it places both code and data within a 2GB region of virtual memory. For example, you might have a 1GB region for code and a 1GB region for data.

2) Force the MCJIT to use a different code model. Small oughta work.

3) File bugs! :wink: I'm not sure anyone is using the MCJIT with anything but the large code model. So you might run into some other issues.


I agree that that is a useable workaround, but my real concern is this TLS initialexec in the large code model. Wouldn’t that also fail if I were to use clang and just set the code model to large? It seems if WrapperRIP can’t be selected, then the TLS implementation shouldn’t emit it.

Just to note, there is at least one other user out there trying to do similar things. :slight_smile: I haven't hit this particular bug yet, but am working my way through a couple of potentially related issues.