[llvm-branch-commits] [llvm] 1a802d5 - [AArch64][PAC] Mark $Scratch operand of AUTxMxN as earlyclobber (#173999)
Cullen Rhodes via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Feb 23 07:26:49 PST 2026
Author: Anatoly Trosinenko
Date: 2026-02-23T15:26:40Z
New Revision: 1a802d58deacc0d3b8d92a9ace1105e8a45b689b
URL: https://github.com/llvm/llvm-project/commit/1a802d58deacc0d3b8d92a9ace1105e8a45b689b
DIFF: https://github.com/llvm/llvm-project/commit/1a802d58deacc0d3b8d92a9ace1105e8a45b689b.diff
LOG: [AArch64][PAC] Mark $Scratch operand of AUTxMxN as earlyclobber (#173999)
This fixes an assertions when emitting code at `-O0`.
(cherry picked from commit a47f3802bfd7f8f4c56cb11bad89d844398e6662)
Added:
Modified:
llvm/lib/Target/AArch64/AArch64InstrInfo.td
llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign-with-blend.ll
llvm/test/CodeGen/AArch64/ptrauth-isel.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index cb8f7c3d70afc..279507c8dba22 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -2203,10 +2203,21 @@ let Predicates = [HasPAuth] in {
let Uses = [X16];
}
+ // AArch64AsmPrinter can clobber the $AddrDisc register as long as it is
+ // marked "killed", otherwise an assertion in emitPtrauthDiscriminator checks
+ // that $Scratch != $AddrDisc. The problem is that it is always correct to
+ // *omit* the "killed" flag, thus an instruction like this is valid:
+ //
+ // $x8, $x9 = AUTxMxN $x8, 0, 12345, /* is actually killed */ $x9, implicit-def $nzcv
+ // // $x9 is dead past this point
+ //
+ // While it is possible to allow emitPtrauthDiscriminator to clobber $Scratch
+ // iff ($AddrDisc is killed OR $Scratch == $AddrDisc), it is easier and more
+ // straightforward to mark $Scratch as @earlyclobber.
def AUTxMxN : Pseudo<(outs GPR64:$AuthVal, GPR64common:$Scratch),
(ins GPR64:$Val, i32imm:$Key,
i64imm:$Disc, GPR64:$AddrDisc),
- [], "$AuthVal = $Val">, Sched<[WriteI, ReadI]> {
+ [], "$AuthVal = $Val, at earlyclobber $Scratch">, Sched<[WriteI, ReadI]> {
let isCodeGenOnly = 1;
let hasSideEffects = 1;
let mayStore = 0;
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign-with-blend.ll b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign-with-blend.ll
index e2aea6df78250..a56921d008712 100644
--- a/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign-with-blend.ll
+++ b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign-with-blend.ll
@@ -29,6 +29,11 @@
; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -global-isel -global-isel-abort=1 -verify-machineinstrs \
; RUN: -aarch64-ptrauth-auth-checks=trap | FileCheck %s -DL=".L" --check-prefixes=TRAP,TRAP-ELF
+; Make sure codegen at -O0 does not crash:
+;
+; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -O0 -verify-machineinstrs -global-isel=0
+; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -O0 -verify-machineinstrs -global-isel=1 -global-isel-abort=1
+
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
define i64 @test_auth_blend(i64 %arg, i64 %arg1) {
@@ -299,6 +304,28 @@ define i64 @test_auth_too_large_discriminator(i64 %arg, i64 %arg1) {
ret i64 %tmp1
}
+; Without "@earlyclobber $Scratch" constraint on AUTxMxN pseudo, the following
+; instruction was fed to AArch64AsmPrinter at -O0
+;
+; renamable $x8, dead renamable $x9 = AUTxMxN renamable $x8(tied-def 0), 0, 1, renamable $x9, implicit-def dead $nzcv
+;
+; resulting in an assertion:
+;
+; Assertion `ScratchReg != AddrDisc && "Forbidden to clobber AddrDisc, but have to"
+;
+define i64 @autxmxn_scratch_is_earlyclobber(i64 %ptr, i64 %arg) {
+entry:
+ %discr = call i64 @llvm.ptrauth.blend(i64 %arg, i64 1)
+ br label %some.bb
+
+some.bb:
+ %authed = call i64 @llvm.ptrauth.auth(i64 %ptr, i32 0, i64 %discr)
+ br label %some.other.bb
+
+some.other.bb:
+ ret i64 %authed
+}
+
declare i64 @llvm.ptrauth.auth(i64, i32, i64)
declare i64 @llvm.ptrauth.resign(i64, i32, i64, i32, i64)
declare i64 @llvm.ptrauth.blend(i64, i64)
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-isel.ll b/llvm/test/CodeGen/AArch64/ptrauth-isel.ll
index 7011b946aad74..6ecfb5852f790 100644
--- a/llvm/test/CodeGen/AArch64/ptrauth-isel.ll
+++ b/llvm/test/CodeGen/AArch64/ptrauth-isel.ll
@@ -1,12 +1,12 @@
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple arm64e-apple-darwin -verify-machineinstrs -stop-after=finalize-isel -global-isel=0 \
-; RUN: | FileCheck %s --check-prefixes=DAGISEL
+; RUN: | FileCheck %s --check-prefixes=DAGISEL,DAGISEL-DARWIN
; RUN: llc < %s -mtriple arm64e-apple-darwin -verify-machineinstrs -stop-after=finalize-isel -global-isel=1 -global-isel-abort=1 \
-; RUN: | FileCheck %s --check-prefixes=GISEL
+; RUN: | FileCheck %s --check-prefixes=GISEL,GISEL-DARWIN
; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -verify-machineinstrs -stop-after=finalize-isel -global-isel=0 \
-; RUN: | FileCheck %s --check-prefixes=DAGISEL
+; RUN: | FileCheck %s --check-prefixes=DAGISEL,DAGISEL-GNU
; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -verify-machineinstrs -stop-after=finalize-isel -global-isel=1 -global-isel-abort=1 \
-; RUN: | FileCheck %s --check-prefixes=GISEL
+; RUN: | FileCheck %s --check-prefixes=GISEL,GISEL-GNU
; Check MIR produced by the instruction selector to validate properties that
; cannot be reliably tested by only inspecting the final asm output.
@@ -267,3 +267,56 @@ exit:
%signed = call i64 @llvm.ptrauth.sign(i64 %addr, i32 2, i64 %disc)
ret i64 %signed
}
+
+; On non-Darwin platforms, AUTxMxN allows allocating arbitrary scratch registers.
+; To simplify expansion of AUTxMxN in AArch64AsmPrinter, $Scratch operand
+; should be marked as @earlyclobber, which is checked by this test case.
+define i64 @autxmxn_earlyclobbered_scratch(i64 %addr, i64 %disc) {
+ ; DAGISEL-DARWIN-LABEL: name: autxmxn_earlyclobbered_scratch
+ ; DAGISEL-DARWIN: bb.0.entry:
+ ; DAGISEL-DARWIN-NEXT: liveins: $x0, $x1
+ ; DAGISEL-DARWIN-NEXT: {{ $}}
+ ; DAGISEL-DARWIN-NEXT: [[COPY:%[0-9]+]]:gpr64noip = COPY $x1
+ ; DAGISEL-DARWIN-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x0
+ ; DAGISEL-DARWIN-NEXT: $x16 = COPY [[COPY1]]
+ ; DAGISEL-DARWIN-NEXT: AUTx16x17 2, 0, [[COPY]], implicit-def $x16, implicit-def dead $x17, implicit-def dead $nzcv, implicit $x16
+ ; DAGISEL-DARWIN-NEXT: [[COPY2:%[0-9]+]]:gpr64all = COPY $x16
+ ; DAGISEL-DARWIN-NEXT: $x0 = COPY [[COPY2]]
+ ; DAGISEL-DARWIN-NEXT: RET_ReallyLR implicit $x0
+ ;
+ ; GISEL-DARWIN-LABEL: name: autxmxn_earlyclobbered_scratch
+ ; GISEL-DARWIN: bb.1.entry:
+ ; GISEL-DARWIN-NEXT: liveins: $x0, $x1
+ ; GISEL-DARWIN-NEXT: {{ $}}
+ ; GISEL-DARWIN-NEXT: [[COPY:%[0-9]+]]:gpr64all = COPY $x0
+ ; GISEL-DARWIN-NEXT: [[COPY1:%[0-9]+]]:gpr64noip = COPY $x1
+ ; GISEL-DARWIN-NEXT: $x16 = COPY [[COPY]]
+ ; GISEL-DARWIN-NEXT: $x17 = IMPLICIT_DEF
+ ; GISEL-DARWIN-NEXT: AUTx16x17 2, 0, [[COPY1]], implicit-def $x16, implicit-def $x17, implicit-def dead $nzcv, implicit $x16
+ ; GISEL-DARWIN-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY $x16
+ ; GISEL-DARWIN-NEXT: $x0 = COPY [[COPY2]]
+ ; GISEL-DARWIN-NEXT: RET_ReallyLR implicit $x0
+ ;
+ ; DAGISEL-GNU-LABEL: name: autxmxn_earlyclobbered_scratch
+ ; DAGISEL-GNU: bb.0.entry:
+ ; DAGISEL-GNU-NEXT: liveins: $x0, $x1
+ ; DAGISEL-GNU-NEXT: {{ $}}
+ ; DAGISEL-GNU-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x1
+ ; DAGISEL-GNU-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x0
+ ; DAGISEL-GNU-NEXT: %2:gpr64, early-clobber %3:gpr64common = AUTxMxN [[COPY1]], 2, 0, [[COPY]], implicit-def dead $nzcv
+ ; DAGISEL-GNU-NEXT: $x0 = COPY %2
+ ; DAGISEL-GNU-NEXT: RET_ReallyLR implicit $x0
+ ;
+ ; GISEL-GNU-LABEL: name: autxmxn_earlyclobbered_scratch
+ ; GISEL-GNU: bb.1.entry:
+ ; GISEL-GNU-NEXT: liveins: $x0, $x1
+ ; GISEL-GNU-NEXT: {{ $}}
+ ; GISEL-GNU-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
+ ; GISEL-GNU-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1
+ ; GISEL-GNU-NEXT: %2:gpr64, early-clobber %3:gpr64common = AUTxMxN [[COPY]], 2, 0, [[COPY1]], implicit-def dead $nzcv
+ ; GISEL-GNU-NEXT: $x0 = COPY %2
+ ; GISEL-GNU-NEXT: RET_ReallyLR implicit $x0
+entry:
+ %auted = call i64 @llvm.ptrauth.auth(i64 %addr, i32 2, i64 %disc)
+ ret i64 %auted
+}
More information about the llvm-branch-commits
mailing list