[llvm-dev] RFC: ConstantPtrAuth for signed pointers on AArch64

Tim Northover via llvm-dev llvm-dev at lists.llvm.org
Tue Dec 8 04:30:56 PST 2020

To put signed pointers into global initializers (e.g. vtables) and other
desirable features there needs to be a Constant that represents "sign this
pointer in such and such way". I propose adding a new child of Constant,
ConstantPtrAuth to represent this:

    @var = global i32* ptrauth(i32* @something, ; Pointer to be signed
                               i32 0,           ; Key to use for the signature
                               i32* @var,       ; Address
discriminator, null if none
                               i16 1234)        ; Discriminator

Anyone who has looked at the Xcode compiler output for arm64e will recognise
this as a pretty close analogue of the pseudo-Global that it emits

That was always intended to be a placeholder while the code was internal so that
we didn't introduce bitcode incompatibility with OSS. Now that arm64e is being
upstreamed, it's a good time to fix what was always really a ConstantExpr
pretending to be a global.

The fields specified were chosen to broadly match the features and relocations
available in arm64e MachO files: a 16-bit discriminator, possibly address
discriminated too.

I've posted the initial patch on Phabricator at
https://reviews.llvm.org/D92834. I've anticipated some
questions and done my best to respond below. What else occurs to people?

Shouldn't this be a ConstantExpr?

There is one key interface for ConstantExpr we cannot currently support:
getAsInstruction. When an address discriminator is present, the ptrauth constant
represents an @llvm.ptrauth.blend followed by an @llvm.ptrauth.sign, two
separate instructions.

Because of that I've so far implemented it as its own separate entity in the
Constant hierarchy (kind of like blockaddress).

It might well be better to give up on intrinsic orthogonality and add one for
this case though. It would simplify the changes to lib/IR etc.

Shouldn't the key be i2 or something?

Possibly. That has legality implications in CodeGen though and is really not a
commonly used part of LLVM (there's currently no llvm_i2_ty in
Intrinsics.td). i32 generally signals "don't care".

Why is the address discriminator not just a bool?

The relocations in MachO only allow you to use the address being relocated as
the address-discriminator, so at first sight it seems excessive to have an
entire pointer field that has only one legitimate value anyway when an i1 would

However, transformations like constant propagation can separate these
ptrauth(...) constants from their storage location, at which point CodeGen would
have no idea what address to use. So the field does need to be the actual

More information about the llvm-dev mailing list