Creating Pointer Constants

Hello,

I am writing a JIT compiler for a subset of the Matlab language and as a
part of my implementation, I would like to be able to pass a constant
pointer to a native function I'm calling.

Right now, this is what I do:

llvm::Constant* constInt = llvm::ConstantInt::get(llvm::Type::Int64Ty,
(int64)thePointer);
llvm::Value* constPtr = llvm::ConstantExpr::getIntToPtr(constInt,
llvm::PointerType::getUnqual(llvm::Type::Int32Ty));
  
builder.CreateCall(my_function, constPtr);

The resulting IR call looks like this:

call void @nativeFunc(i32* inttoptr (i64 146876396 to i32*))

I'm just wondering if there is a better way to approach this. Casting a
pointer to a signed integer and back to a pointer looks both hack-ish, and
potentially risky (what happens if the address falls in the negative range
of the signed integer?). Unfortunately, I couldn't call a pointer constant
type in the LLVM doxygen documentation.

Thank you for your time,

- Maxime

I am writing a JIT compiler for a subset of the Matlab language and as a
part of my implementation, I would like to be able to pass a constant
pointer to a native function I'm calling.

Right now, this is what I do:

llvm::Constant* constInt = llvm::ConstantInt::get(llvm::Type::Int64Ty,
(int64)thePointer);
llvm::Value* constPtr = llvm::ConstantExpr::getIntToPtr(constInt,
llvm::PointerType::getUnqual(llvm::Type::Int32Ty));
  
builder.CreateCall(my_function, constPtr);

The resulting IR call looks like this:

call void @nativeFunc(i32* inttoptr (i64 146876396 to i32*))

This is correct.

I'm just wondering if there is a better way to approach this. Casting a
pointer to a signed integer and back to a pointer looks both hack-ish, and
potentially risky (what happens if the address falls in the negative range
of the signed integer?).

The inttoptr/ptrtoint conversion is perfectly safe so long as you match the pointer size and the integer size. (i.e., a 64-bit pointer obviously can't fit in an i32.)

— Gordon

I'm just wondering if there is a better way to approach this.
Casting a
pointer to a signed integer and back to a pointer looks both hack-
ish, and
potentially risky (what happens if the address falls in the negative
range
of the signed integer?).

If you're worried about sign extension, you could always case through uintptr_t instead of int64. The LLVM target data holds the equivalent LLVM type; if you're writing a JIT, you can do jitEngine- >getTargetData()->getIntPtrType().

John.