[llvm] [AArch64][PAC] Combine signing with address materialization (PR #130809)

Anatoly Trosinenko via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 27 08:03:12 PDT 2025


atrosinenko wrote:

@ojhunt Updated the test cases - turned out, there was actually an issue with `LOADgotAUTH` not being eliminated.

Considering your test cases, I just realized that they should probably be handled by #130807, not by this patch. As for converting them to LLVM IR, `f1` and `f2` are translated by Clang in a rather straightforward manner and `f3` is a bit more tricky:

```llvm
define dso_local ptr @f1(ptr noundef %p) local_unnamed_addr #0 {
entry:
  %0 = ptrtoint ptr %p to i64
  %1 = tail call i64 @llvm.ptrauth.auth(i64 %0, i32 2, i64 1234)
  tail call void asm sideeffect "", ""() #4, !srcloc !9
  %2 = tail call i64 @llvm.ptrauth.sign(i64 %1, i32 3, i64 42)
  %3 = inttoptr i64 %2 to ptr
  ret ptr %3
}

define dso_local ptr @f2(ptr noundef %p) local_unnamed_addr #0 {
entry:
  %0 = ptrtoint ptr %p to i64
  %1 = tail call i64 @llvm.ptrauth.auth(i64 %0, i32 2, i64 1234)
  %2 = inttoptr i64 %1 to ptr
  tail call void asm sideeffect "", "r"(ptr %2) #4, !srcloc !10
  %3 = tail call i64 @llvm.ptrauth.sign(i64 %1, i32 3, i64 42)
  %4 = inttoptr i64 %3 to ptr
  ret ptr %4
}

define dso_local ptr @f3(ptr noundef %p) local_unnamed_addr #0 {
entry:
  %authed = alloca ptr, align 8
  call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %authed) #4
  %0 = ptrtoint ptr %p to i64
  %1 = tail call i64 @llvm.ptrauth.auth(i64 %0, i32 2, i64 1234)
  %2 = inttoptr i64 %1 to ptr
  store ptr %2, ptr %authed, align 8, !tbaa !11
  call void asm sideeffect "", "*m"(ptr nonnull elementtype(ptr) %authed) #4, !srcloc !15
  %3 = load ptr, ptr %authed, align 8, !tbaa !11
  %4 = ptrtoint ptr %3 to i64
  %5 = call i64 @llvm.ptrauth.sign(i64 %4, i32 3, i64 42)
  %6 = inttoptr i64 %5 to ptr
  call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %authed) #4
  ret ptr %6
}
```
which can be further cleaned up.

As this PR does not handle folding "standalone" auth into sign, the following code is emitted for `f3`:
```
f3:
        sub     sp, sp, #16
        mov     x16, x0
        mov     x17, #1234
        autda   x16, x17
        mov     x17, x16
        xpacd   x17
        cmp     x16, x17
        b.eq    .Lauth_success_2
        brk     #0xc472
.Lauth_success_2:
        add     x8, sp, #8
        str     x16, [sp, #8]
        //APP
        //NO_APP
        ldr     x0, [sp, #8]
        mov     w8, #42
        pacdb   x0, x8
        add     sp, sp, #16
        ret
```
On the branch of #130807 the result is similar, which is quite surprising, moreover `x0` is not reloaded after inline asm, meaning there should be no reason not to merge auth+sign.

On the other hand, if I replace inline asm with function call like this:
```c
  void callee(void *);
  void* f3(void *p) {
     void* authed = __builtin_ptrauth_auth(p, 2, 1234);
     callee(authed);
     return __builtin_ptrauth_sign_unauthenticated(authed, 3, 42);
  }
```
... both patches behave as expected: this one calls a function and signs a potentially overwritten register:
```
// ...
        bl      callee
        mov     w8, #42
        pacdb   x19, x8
// ...
```
and with PR #130807, authentication is re-done after function call:
```
f3:
        pacibsp
        stp     x29, x30, [sp, #-32]!
        str     x19, [sp, #16]
        mov     x29, sp
        mov     x16, x0
        mov     x19, x0
        mov     x17, #1234
        autda   x16, x17
        mov     x17, x16
        xpacd   x17
        cmp     x16, x17
        b.eq    .Lauth_success_0
        brk     #0xc472
.Lauth_success_0:
        mov     x0, x16
        bl      callee
        mov     x16, x19
        mov     x17, #1234
        autda   x16, x17
        mov     x17, x16
        xpacd   x17
        cmp     x16, x17
        b.eq    .Lauth_success_1
        brk     #0xc472
.Lauth_success_1:
        mov     x17, #42
        pacdb   x16, x17
        mov     x0, x16
        ldr     x19, [sp, #16]
        ldp     x29, x30, [sp], #32
        retab
```

https://github.com/llvm/llvm-project/pull/130809


More information about the llvm-commits mailing list