https://github.com/AbhayKanhere created 
https://github.com/llvm/llvm-project/pull/142047

ptrauth intrinsic to safely construct relative ptr for swift coroutines.

       A ptrauth intrinsic for swift co-routine support that allows creation of 
signed pointer
 from offset stored at address relative to the pointer.

 Following C-like pseudo code (ignoring keys,discriminators) explains its 
operation:
      let rawptr = PACauth(inputptr);
      return PACsign(  rawptr +  signextend64( *(int32*)(rawptr+addend) ))

 What: Authenticate a signed pointer, load a 32bit value at offset 'addend' 
from pointer,
       add this value to pointer, sign this new pointer.
 builtin: __builtin_ptrauth_auth_load_relative_and_sign
 intrinsic: ptrauth_auth_resign_load_relative

 Also this PR removes ptr_auth intrinsics noop form 
(!__has_feature(ptrauth_intrinsics) path)

>From cf5e1c085dfa1b69986abd14509b0347458309b1 Mon Sep 17 00:00:00 2001
From: Abhay Kanhere <ab...@kanhere.net>
Date: Wed, 28 May 2025 16:35:05 -0700
Subject: [PATCH] [CodeGen][AArch64] ptrauth intrinsic to safely construct
 relative pointer for swift coroutines        A ptrauth intrinsic for swift
 co-routine support that allows creation of signed pointer  from offset stored
 at address relative to the pointer.

 Following C-like pseudo code (ignoring keys,discriminators) explains its 
operation:
      let rawptr = PACauth(inputptr);
      return PACsign(  rawptr +  *(int32*)(rawptr+addend) )

 What: Authenticate a signed pointer, load a 32bit value at offset 'addend' 
from pointer,
       add this value to pointer, sign this new pointer.
 builtin: __builtin_ptrauth_auth_load_relative_and_sign
 intrinsic: ptrauth_auth_resign_load_relative

 Also this PR removes ptr_auth intrinsics noop form 
(!__has_feature(ptrauth_intrinsics) path)
---
 clang/include/clang/Basic/Builtins.td         |   6 +
 clang/lib/CodeGen/CGBuiltin.cpp               |   6 +-
 clang/lib/Headers/ptrauth.h                   |  97 +---
 llvm/include/llvm/IR/Intrinsics.td            |  13 +
 llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp |  74 ++-
 .../Target/AArch64/AArch64ISelDAGToDAG.cpp    |  37 +-
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   |  20 +
 .../GISel/AArch64InstructionSelector.cpp      |  39 ++
 llvm/lib/Transforms/Utils/Local.cpp           |   1 +
 ...uth-intrinsic-auth-resign-relative-load.ll | 516 ++++++++++++++++++
 10 files changed, 722 insertions(+), 87 deletions(-)
 create mode 100644 
llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign-relative-load.ll

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index e43b87fb3c131..44bbe651891a7 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4595,6 +4595,12 @@ def PtrauthAuthAndResign : Builtin {
   let Prototype = "void*(void*,int,void*,int,void*)";
 }
 
+def PtrauthAuthLoadRelativeAndSign : Builtin {
+  let Spellings = ["__builtin_ptrauth_auth_load_relative_and_sign"];
+  let Attributes = [CustomTypeChecking, NoThrow];
+  let Prototype = "void*(void*,int,void*,int,void*,ptrdiff_t)";
+}
+
 def PtrauthAuth : Builtin {
   let Spellings = ["__builtin_ptrauth_auth"];
   let Attributes = [CustomTypeChecking, NoThrow];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 89b321090f2d8..fa1d778db7caa 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -5543,12 +5543,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const 
GlobalDecl GD, unsigned BuiltinID,
 
   case Builtin::BI__builtin_ptrauth_auth:
   case Builtin::BI__builtin_ptrauth_auth_and_resign:
+  case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
   case Builtin::BI__builtin_ptrauth_blend_discriminator:
   case Builtin::BI__builtin_ptrauth_sign_generic_data:
   case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
   case Builtin::BI__builtin_ptrauth_strip: {
     // Emit the arguments.
-    SmallVector<llvm::Value *, 5> Args;
+    SmallVector<llvm::Value *, 6> Args;
     for (auto argExpr : E->arguments())
       Args.push_back(EmitScalarExpr(argExpr));
 
@@ -5559,6 +5560,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
 
     switch (BuiltinID) {
     case Builtin::BI__builtin_ptrauth_auth_and_resign:
+    case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
       if (Args[4]->getType()->isPointerTy())
         Args[4] = Builder.CreatePtrToInt(Args[4], IntPtrTy);
       [[fallthrough]];
@@ -5586,6 +5588,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
         return Intrinsic::ptrauth_auth;
       case Builtin::BI__builtin_ptrauth_auth_and_resign:
         return Intrinsic::ptrauth_resign;
+      case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
+        return Intrinsic::ptrauth_resign_load_relative;
       case Builtin::BI__builtin_ptrauth_blend_discriminator:
         return Intrinsic::ptrauth_blend;
       case Builtin::BI__builtin_ptrauth_sign_generic_data:
diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h
index d489a67c533d4..cf47b7ae959b3 100644
--- a/clang/lib/Headers/ptrauth.h
+++ b/clang/lib/Headers/ptrauth.h
@@ -165,6 +165,31 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
   __builtin_ptrauth_auth_and_resign(__value, __old_key, __old_data, __new_key, 
\
                                     __new_data)
 
+/* Authenticate a pointer using one scheme, load 32bit value at offset addend
+   from the pointer, and add this value to the pointer, sign using specified
+   scheme.
+
+   If the result is subsequently authenticated using the new scheme, that
+   authentication is guaranteed to fail if and only if the initial
+   authentication failed.
+
+   The value must be an expression of pointer type.
+   The key must be a constant expression of type ptrauth_key.
+   The extra data must be an expression of pointer or integer type;
+   if an integer, it will be coerced to ptrauth_extra_data_t.
+   The addend must be an immediate ptrdiff_t value.
+   The result will have the same type as the original value.
+
+   This operation is guaranteed to not leave the intermediate value
+   available for attack before it is re-signed.
+
+   Do not pass a null pointer to this function. A null pointer
+   will not successfully authenticate. */
+#define ptrauth_auth_load_relative_and_sign(__value, __old_key, __old_data,    
\
+                                            __new_key, __new_data, __addend)   
\
+  __builtin_ptrauth_auth_load_relative_and_sign(                               
\
+      __value, __old_key, __old_data, __new_key, __new_data, __addend)
+
 /* Authenticate a pointer using one scheme and resign it as a C
    function pointer.
 
@@ -259,78 +284,6 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
 /* The value is ptrauth_string_discriminator("init_fini") */
 #define __ptrauth_init_fini_discriminator 0xd9d4
 
-#else
-
-#define ptrauth_strip(__value, __key)                                          
\
-  ({                                                                           
\
-    (void)__key;                                                               
\
-    __value;                                                                   
\
-  })
-
-#define ptrauth_blend_discriminator(__pointer, __integer)                      
\
-  ({                                                                           
\
-    (void)__pointer;                                                           
\
-    (void)__integer;                                                           
\
-    ((ptrauth_extra_data_t)0);                                                 
\
-  })
-
-#define ptrauth_sign_constant(__value, __key, __data)                          
\
-  ({                                                                           
\
-    (void)__key;                                                               
\
-    (void)__data;                                                              
\
-    __value;                                                                   
\
-  })
-
-#define ptrauth_sign_unauthenticated(__value, __key, __data)                   
\
-  ({                                                                           
\
-    (void)__key;                                                               
\
-    (void)__data;                                                              
\
-    __value;                                                                   
\
-  })
-
-#define ptrauth_auth_and_resign(__value, __old_key, __old_data, __new_key,     
\
-                                __new_data)                                    
\
-  ({                                                                           
\
-    (void)__old_key;                                                           
\
-    (void)__old_data;                                                          
\
-    (void)__new_key;                                                           
\
-    (void)__new_data;                                                          
\
-    __value;                                                                   
\
-  })
-
-#define ptrauth_auth_function(__value, __old_key, __old_data)                  
\
-  ({                                                                           
\
-    (void)__old_key;                                                           
\
-    (void)__old_data;                                                          
\
-    __value;                                                                   
\
-  })
-
-#define ptrauth_auth_data(__value, __old_key, __old_data)                      
\
-  ({                                                                           
\
-    (void)__old_key;                                                           
\
-    (void)__old_data;                                                          
\
-    __value;                                                                   
\
-  })
-
-#define ptrauth_string_discriminator(__string)                                 
\
-  ({                                                                           
\
-    (void)__string;                                                            
\
-    ((ptrauth_extra_data_t)0);                                                 
\
-  })
-
-#define ptrauth_type_discriminator(__type) ((ptrauth_extra_data_t)0)
-
-#define ptrauth_sign_generic_data(__value, __data)                             
\
-  ({                                                                           
\
-    (void)__value;                                                             
\
-    (void)__data;                                                              
\
-    ((ptrauth_generic_signature_t)0);                                          
\
-  })
-
-
-#define ptrauth_cxx_vtable_pointer(key, address_discrimination,                
\
-                                   extra_discrimination...)
-
 #endif /* __has_feature(ptrauth_intrinsics) */
 
 #endif /* __PTRAUTH_H */
diff --git a/llvm/include/llvm/IR/Intrinsics.td 
b/llvm/include/llvm/IR/Intrinsics.td
index d3899056bc240..bcf6fb0f9bbd6 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -2799,6 +2799,19 @@ def int_ptrauth_resign : Intrinsic<[llvm_i64_ty],
                                    [IntrNoMem, ImmArg<ArgIndex<1>>,
                                     ImmArg<ArgIndex<3>>]>;
 
+// Authenticate a signed pointer, load 32bit value at offset from pointer, add
+// both, and sign it. The second (key) and third (discriminator) arguments
+// specify the signing schema used for authenticating. The fourth and fifth
+// arguments specify the schema used for signing. The sixth argument is addend
+// added to pointer to load the relative offset. The signature must be valid.
+// This is a combined form of int_ptrauth_resign for relative pointers
+def int_ptrauth_resign_load_relative
+    : Intrinsic<[llvm_i64_ty],
+                [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty, llvm_i32_ty,
+                 llvm_i64_ty, llvm_i64_ty],
+                [IntrReadMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<3>>,
+                 ImmArg<ArgIndex<5>>]>;
+
 // Strip the embedded signature out of a signed pointer.
 // The second argument specifies the key.
 // This behaves like @llvm.ptrauth.auth, but doesn't require the signature to
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp 
b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index e9ccc35f34612..c92ecab17194b 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -167,7 +167,7 @@ class AArch64AsmPrinter : public AsmPrinter {
   // Check authenticated LR before tail calling.
   void emitPtrauthTailCallHardening(const MachineInstr *TC);
 
-  // Emit the sequence for AUT or AUTPAC.
+  // Emit the sequence for AUT, AUTPAC, or AUTRELLOADPAC.
   void emitPtrauthAuthResign(const MachineInstr *MI);
 
   // Emit the sequence to compute the discriminator.
@@ -2065,8 +2065,9 @@ void 
AArch64AsmPrinter::emitPtrauthTailCallHardening(const MachineInstr *TC) {
 }
 
 void AArch64AsmPrinter::emitPtrauthAuthResign(const MachineInstr *MI) {
-  const bool IsAUTPAC = MI->getOpcode() == AArch64::AUTPAC;
-
+  const bool IsAUTPAC = MI->getOpcode() == AArch64::AUTPAC ||
+                        MI->getOpcode() == AArch64::AUTRELLOADPAC;
+  const bool HasLoad = MI->getOpcode() == AArch64::AUTRELLOADPAC;
   // We expand AUT/AUTPAC into a sequence of the form
   //
   //      ; authenticate x16
@@ -2141,11 +2142,75 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(const 
MachineInstr *MI) {
   }
 
   // We already emitted unchecked and checked-but-non-trapping AUTs.
-  // That left us with trapping AUTs, and AUTPACs.
+  // That left us with trapping AUTs, and AUTPA/AUTRELLOADPACs.
   // Trapping AUTs don't need PAC: we're done.
   if (!IsAUTPAC)
     return;
 
+  if (HasLoad) {
+    int64_t Addend = MI->getOperand(6).getImm();
+    // incoming rawpointer in X16, X17 is not live at this point.
+    //   LDSRWpre x17, x16, simm9  ; note: x16+simm9 used later.
+    if (isInt<9>(Addend)) {
+      EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::LDRSWpre)
+                                       .addReg(AArch64::X16)
+                                       .addReg(AArch64::X17)
+                                       .addReg(AArch64::X16)
+                                       .addImm(/*simm9:*/ Addend));
+    } else {
+      //   x16 = x16 + Addend computation has 2 variants
+      if (isUInt<24>(Addend)) {
+        // variant 1: add x16, x16, Addend >> shift12 ls shift12
+        // This can take upto 2 instructions.
+        for (int BitPos = 0; BitPos != 24 && (Addend >> BitPos); BitPos += 12) 
{
+          EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ADDXri)
+                                           .addReg(AArch64::X16)
+                                           .addReg(AArch64::X16)
+                                           .addImm((Addend >> BitPos) & 0xfff)
+                                           .addImm(AArch64_AM::getShifterImm(
+                                               AArch64_AM::LSL, BitPos)));
+        }
+      } else {
+        // variant 2: accumulate constant in X17 16 bits at a time, and add to
+        // X16 This can take 2-5 instructions.
+        EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::MOVZXi)
+                                         .addReg(AArch64::X17)
+                                         .addImm(Addend & 0xffff)
+                                         .addImm(AArch64_AM::getShifterImm(
+                                             AArch64_AM::LSL, 0)));
+
+        for (int Offset = 16; Offset < 64; Offset += 16) {
+          uint16_t Fragment = static_cast<uint16_t>(Addend >> Offset);
+          if (!Fragment)
+            continue;
+          EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::MOVKXi)
+                                           .addReg(AArch64::X17)
+                                           .addReg(AArch64::X17)
+                                           .addImm(Fragment)
+                                           .addImm(/*shift:*/ Offset));
+        }
+        // addx x16, x16, x17
+        EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ADDXrs)
+                                         .addReg(AArch64::X16)
+                                         .addReg(AArch64::X16)
+                                         .addReg(AArch64::X17)
+                                         .addImm(0));
+      }
+      // ldrsw x17,x16(0)
+      EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::LDRSWui)
+                                       .addReg(AArch64::X17)
+                                       .addReg(AArch64::X16)
+                                       .addImm(0));
+    }
+    // addx x16, x16, x17
+    EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ADDXrs)
+                                     .addReg(AArch64::X16)
+                                     .addReg(AArch64::X16)
+                                     .addReg(AArch64::X17)
+                                     .addImm(0));
+
+  } /* HasLoad == true */
+
   auto PACKey = (AArch64PACKey::ID)MI->getOperand(3).getImm();
   uint64_t PACDisc = MI->getOperand(4).getImm();
   unsigned PACAddrDisc = MI->getOperand(5).getReg();
@@ -2863,6 +2928,7 @@ void AArch64AsmPrinter::emitInstruction(const 
MachineInstr *MI) {
 
   case AArch64::AUT:
   case AArch64::AUTPAC:
+  case AArch64::AUTRELLOADPAC:
     emitPtrauthAuthResign(MI);
     return;
 
diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp 
b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
index 2eb8c6008db0f..67559e8705b4c 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -1544,12 +1544,15 @@ void AArch64DAGToDAGISel::SelectPtrauthAuth(SDNode *N) {
 
 void AArch64DAGToDAGISel::SelectPtrauthResign(SDNode *N) {
   SDLoc DL(N);
-  // IntrinsicID is operand #0
-  SDValue Val = N->getOperand(1);
-  SDValue AUTKey = N->getOperand(2);
-  SDValue AUTDisc = N->getOperand(3);
-  SDValue PACKey = N->getOperand(4);
-  SDValue PACDisc = N->getOperand(5);
+  // IntrinsicID is operand #0, if W_CHAIN it is #1
+  int OffsetBase = N->getOpcode() == ISD::INTRINSIC_W_CHAIN ? 1 : 0;
+  SDValue Val = N->getOperand(OffsetBase + 1);
+  SDValue AUTKey = N->getOperand(OffsetBase + 2);
+  SDValue AUTDisc = N->getOperand(OffsetBase + 3);
+  SDValue PACKey = N->getOperand(OffsetBase + 4);
+  SDValue PACDisc = N->getOperand(OffsetBase + 5);
+  uint32_t IntNum = N->getConstantOperandVal(OffsetBase + 0);
+  bool HasLoad = IntNum == Intrinsic::ptrauth_resign_load_relative;
 
   unsigned AUTKeyC = cast<ConstantSDNode>(AUTKey)->getZExtValue();
   unsigned PACKeyC = cast<ConstantSDNode>(PACKey)->getZExtValue();
@@ -1568,11 +1571,22 @@ void AArch64DAGToDAGISel::SelectPtrauthResign(SDNode 
*N) {
   SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(), DL,
                                          AArch64::X16, Val, SDValue());
 
-  SDValue Ops[] = {AUTKey,       AUTConstDisc, AUTAddrDisc,        PACKey,
-                   PACConstDisc, PACAddrDisc,  X16Copy.getValue(1)};
+  if (HasLoad) {
+    SDValue Addend = N->getOperand(OffsetBase + 6);
+    SDValue Ops[] = {AUTKey, AUTConstDisc,       AUTAddrDisc,
+                     PACKey, PACConstDisc,       PACAddrDisc,
+                     Addend, X16Copy.getValue(1)};
 
-  SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC, DL, MVT::i64, Ops);
-  ReplaceNode(N, AUTPAC);
+    SDNode *AUTRELLOADPAC = CurDAG->getMachineNode(AArch64::AUTRELLOADPAC, DL,
+                                                   MVT::i64, MVT::Other, Ops);
+    ReplaceNode(N, AUTRELLOADPAC);
+  } else {
+    SDValue Ops[] = {AUTKey,       AUTConstDisc, AUTAddrDisc,        PACKey,
+                     PACConstDisc, PACAddrDisc,  X16Copy.getValue(1)};
+
+    SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC, DL, MVT::i64, 
Ops);
+    ReplaceNode(N, AUTPAC);
+  }
 }
 
 bool AArch64DAGToDAGISel::tryIndexedLoad(SDNode *N) {
@@ -5634,6 +5648,9 @@ void AArch64DAGToDAGISel::Select(SDNode *Node) {
               {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
         SelectCVTIntrinsicFP8(Node, 2, Opc);
       return;
+    case Intrinsic::ptrauth_resign_load_relative:
+      SelectPtrauthResign(Node);
+      return;
     }
   } break;
   case ISD::INTRINSIC_WO_CHAIN: {
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td 
b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 72445172059bf..a0f5cff5c77d0 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -2124,6 +2124,26 @@ let Predicates = [HasPAuth] in {
     let Uses = [X16];
   }
 
+  // Similiar to AUTPAC, except a 32bit value is loaded at Addend offset from
+  // pointer and this value is added to the pointer before signing. This
+  // directly manipulates x16/x17, which are the only registers the OS
+  // guarantees are safe to use for sensitive operations.
+  def AUTRELLOADPAC
+      : Pseudo<(outs),
+               (ins i32imm:$AUTKey, i64imm:$AUTDisc, GPR64:$AUTAddrDisc,
+                   i32imm:$PACKey, i64imm:$PACDisc, GPR64noip:$PACAddrDisc,
+                   i64imm:$Addend),
+               []>,
+        Sched<[WriteI, ReadI]> {
+    let isCodeGenOnly = 1;
+    let hasSideEffects = 1;
+    let mayStore = 0;
+    let mayLoad = 1;
+    let Size = 84;
+    let Defs = [X16, X17, NZCV];
+    let Uses = [X16];
+  }
+
   // Materialize a signed global address, with adrp+add and PAC.
   def MOVaddrPAC : Pseudo<(outs),
                           (ins i64imm:$Addr, i32imm:$Key,
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp 
b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index e0c693bff3c0a..4e4b34bc348c9 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -6640,6 +6640,45 @@ bool 
AArch64InstructionSelector::selectIntrinsicWithSideEffects(
     constrainSelectedInstRegOperands(*Memset, TII, TRI, RBI);
     break;
   }
+  case Intrinsic::ptrauth_resign_load_relative: {
+    Register DstReg = I.getOperand(0).getReg();
+    Register ValReg = I.getOperand(2).getReg();
+    uint64_t AUTKey = I.getOperand(3).getImm();
+    Register AUTDisc = I.getOperand(4).getReg();
+    uint64_t PACKey = I.getOperand(5).getImm();
+    Register PACDisc = I.getOperand(6).getReg();
+    int64_t Addend = I.getOperand(7).getImm();
+
+    Register AUTAddrDisc = AUTDisc;
+    uint16_t AUTConstDiscC = 0;
+    std::tie(AUTConstDiscC, AUTAddrDisc) =
+        extractPtrauthBlendDiscriminators(AUTDisc, MRI);
+
+    Register PACAddrDisc = PACDisc;
+    uint16_t PACConstDiscC = 0;
+    std::tie(PACConstDiscC, PACAddrDisc) =
+        extractPtrauthBlendDiscriminators(PACDisc, MRI);
+
+    MIB.buildCopy({AArch64::X16}, {ValReg});
+
+    // we dont support AUTRELLOADPACunchecked
+    unsigned Opc = AArch64::AUTRELLOADPAC;
+
+    MIB.buildInstr(Opc)
+        .addImm(AUTKey)
+        .addImm(AUTConstDiscC)
+        .addUse(AUTAddrDisc)
+        .addImm(PACKey)
+        .addImm(PACConstDiscC)
+        .addUse(PACAddrDisc)
+        .addImm(Addend)
+        .constrainAllUses(TII, TRI, RBI);
+    MIB.buildCopy({DstReg}, Register(AArch64::X16));
+
+    RBI.constrainGenericRegister(DstReg, AArch64::GPR64RegClass, MRI);
+    I.eraseFromParent();
+    return true;
+  }
   }
 
   I.eraseFromParent();
diff --git a/llvm/lib/Transforms/Utils/Local.cpp 
b/llvm/lib/Transforms/Utils/Local.cpp
index fe1391a501b43..ef598bc14bca6 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -463,6 +463,7 @@ bool llvm::wouldInstructionBeTriviallyDead(const 
Instruction *I,
     case Intrinsic::wasm_trunc_unsigned:
     case Intrinsic::ptrauth_auth:
     case Intrinsic::ptrauth_resign:
+    case Intrinsic::ptrauth_resign_load_relative:
       return true;
     default:
       return false;
diff --git 
a/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign-relative-load.ll 
b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign-relative-load.ll
new file mode 100644
index 0000000000000..affa0c2369ba2
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign-relative-load.ll
@@ -0,0 +1,516 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple arm64e-apple-darwin -global-isel=0                    
-verify-machineinstrs \
+; RUN:   -aarch64-ptrauth-auth-checks=none | FileCheck %s -DL="L" 
--check-prefix=UNCHECKED
+; RUN: llc < %s -mtriple arm64e-apple-darwin -global-isel -global-isel-abort=1 
-verify-machineinstrs \
+; RUN:   -aarch64-ptrauth-auth-checks=none | FileCheck %s -DL="L" 
--check-prefix=UNCHECKED
+
+; RUN: llc < %s -mtriple arm64e-apple-darwin -global-isel=0                    
-verify-machineinstrs \
+; RUN:                                     | FileCheck %s -DL="L" 
--check-prefix=CHECKED
+; RUN: llc < %s -mtriple arm64e-apple-darwin -global-isel -global-isel-abort=1 
-verify-machineinstrs \
+; RUN:                                     | FileCheck %s -DL="L" 
--check-prefix=CHECKED
+
+; RUN: llc < %s -mtriple arm64e-apple-darwin -global-isel=0                    
-verify-machineinstrs \
+; RUN:   -aarch64-ptrauth-auth-checks=trap | FileCheck %s -DL="L" 
--check-prefix=TRAP
+; RUN: llc < %s -mtriple arm64e-apple-darwin -global-isel -global-isel-abort=1 
-verify-machineinstrs \
+; RUN:   -aarch64-ptrauth-auth-checks=trap | FileCheck %s -DL="L" 
--check-prefix=TRAP
+
+;RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -global-isel=0         
           -verify-machineinstrs \
+;RUN:   -aarch64-ptrauth-auth-checks=none | FileCheck %s -DL=".L" 
--check-prefix=UNCHECKED
+;RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -global-isel 
-global-isel-abort=1 -verify-machineinstrs \
+;RUN:   -aarch64-ptrauth-auth-checks=none | FileCheck %s -DL=".L" 
--check-prefix=UNCHECKED
+
+;RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -global-isel=0         
           -verify-machineinstrs \
+;RUN:                                     | FileCheck %s -DL=".L" 
--check-prefix=CHECKED
+;RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -global-isel 
-global-isel-abort=1 -verify-machineinstrs \
+;RUN:                                     | FileCheck %s -DL=".L" 
--check-prefix=CHECKED
+
+;RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -global-isel=0         
           -verify-machineinstrs \
+;RUN:   -aarch64-ptrauth-auth-checks=trap | FileCheck %s -DL=".L" 
--check-prefix=TRAP
+;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-prefix=TRAP
+
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+
+define i64 @test_resign_load_relative_ia_ia(i64 %arg, i64 %arg1, i64 %arg2) {
+; UNCHECKED-LABEL: test_resign_load_relative_ia_ia:
+; UNCHECKED:         %bb.0:
+; UNCHECKED-NEXT:    mov x16, x0
+; UNCHECKED-NEXT:    autia x16, x1
+; UNCHECKED-NEXT:    ldrsw x17, [x16, #-256]!
+; UNCHECKED-NEXT:    add x16, x16, x17
+; UNCHECKED-NEXT:    pacia x16, x2
+; UNCHECKED-NEXT:    mov x0, x16
+; UNCHECKED-NEXT:    ret
+;
+; CHECKED-LABEL: test_resign_load_relative_ia_ia:
+; CHECKED:         %bb.0:
+; CHECKED-NEXT:    mov x16, x0
+; CHECKED-NEXT:    autia x16, x1
+; CHECKED-NEXT:    mov x17, x16
+; CHECKED-NEXT:    xpaci x17
+; CHECKED-NEXT:    cmp x16, x17
+; CHECKED-NEXT:    b.eq [[L]]auth_success_0
+; CHECKED-NEXT:    mov x16, x17
+; CHECKED-NEXT:    b [[L]]resign_end_0
+; CHECKED-NEXT:  Lauth_success_0:
+; CHECKED-NEXT:    ldrsw x17, [x16, #-256]!
+; CHECKED-NEXT:    add x16, x16, x17
+; CHECKED-NEXT:    pacia x16, x2
+; CHECKED-NEXT:  Lresign_end_0:
+; CHECKED-NEXT:    mov x0, x16
+; CHECKED-NEXT:    ret
+;
+; TRAP-LABEL: test_resign_load_relative_ia_ia:
+; TRAP:         %bb.0:
+; TRAP-NEXT:    mov x16, x0
+; TRAP-NEXT:    autia x16, x1
+; TRAP-NEXT:    mov x17, x16
+; TRAP-NEXT:    xpaci x17
+; TRAP-NEXT:    cmp x16, x17
+; TRAP-NEXT:    b.eq [[L]]auth_success_0
+; TRAP-NEXT:    brk #0xc470
+; TRAP-NEXT:  Lauth_success_0:
+; TRAP-NEXT:    ldrsw x17, [x16, #-256]!
+; TRAP-NEXT:    add x16, x16, x17
+; TRAP-NEXT:    pacia x16, x2
+; TRAP-NEXT:    mov x0, x16
+; TRAP-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.resign.load.relative(i64 %arg, i32 0, i64 
%arg1, i32 0, i64 %arg2, i64 -256)
+  ret i64 %tmp
+}
+
+; note: offset 256 is larger tha 255 (largest simm9), is uint<24>
+define i64 @test_resign_load_relative_ib_ia(i64 %arg, i64 %arg1, i64 %arg2) {
+; UNCHECKED-LABEL: test_resign_load_relative_ib_ia:
+; UNCHECKED:         %bb.0:
+; UNCHECKED-NEXT:    mov x16, x0
+; UNCHECKED-NEXT:    autib x16, x1
+; UNCHECKED-NEXT:    add x16, x16, #256
+; UNCHECKED-NEXT:    ldrsw x17, [x16]
+; UNCHECKED-NEXT:    add x16, x16, x17
+; UNCHECKED-NEXT:    pacia x16, x2
+; UNCHECKED-NEXT:    mov x0, x16
+; UNCHECKED-NEXT:    ret
+;
+; CHECKED-LABEL: test_resign_load_relative_ib_ia:
+; CHECKED:         %bb.0:
+; CHECKED-NEXT:    mov x16, x0
+; CHECKED-NEXT:    autib x16, x1
+; CHECKED-NEXT:    mov x17, x16
+; CHECKED-NEXT:    xpaci x17
+; CHECKED-NEXT:    cmp x16, x17
+; CHECKED-NEXT:    b.eq [[L]]auth_success_1
+; CHECKED-NEXT:    mov x16, x17
+; CHECKED-NEXT:    b [[L]]resign_end_1
+; CHECKED-NEXT:  Lauth_success_1:
+; CHECKED-NEXT:    add x16, x16, #256
+; CHECKED-NEXT:    ldrsw x17, [x16]
+; CHECKED-NEXT:    add x16, x16, x17
+; CHECKED-NEXT:    pacia x16, x2
+; CHECKED-NEXT:  Lresign_end_1:
+; CHECKED-NEXT:    mov x0, x16
+; CHECKED-NEXT:    ret
+;
+; TRAP-LABEL: test_resign_load_relative_ib_ia:
+; TRAP:         %bb.0:
+; TRAP-NEXT:    mov x16, x0
+; TRAP-NEXT:    autib x16, x1
+; TRAP-NEXT:    mov x17, x16
+; TRAP-NEXT:    xpaci x17
+; TRAP-NEXT:    cmp x16, x17
+; TRAP-NEXT:    b.eq [[L]]auth_success_1
+; TRAP-NEXT:    brk #0xc471
+; TRAP-NEXT:  Lauth_success_1:
+; TRAP-NEXT:    add x16, x16, #256
+; TRAP-NEXT:    ldrsw x17, [x16]
+; TRAP-NEXT:    add x16, x16, x17
+; TRAP-NEXT:    pacia x16, x2
+; TRAP-NEXT:    mov x0, x16
+; TRAP-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.resign.load.relative(i64 %arg, i32 1, i64 
%arg1, i32 0, i64 %arg2, i64 256)
+  ret i64 %tmp
+}
+
+define i64 @test_resign_load_relative_da_ia(i64 %arg, i64 %arg1, i64 %arg2) {
+; UNCHECKED-LABEL: test_resign_load_relative_da_ia:
+; UNCHECKED:         %bb.0:
+; UNCHECKED-NEXT:    mov x16, x0
+; UNCHECKED-NEXT:    autda x16, x1
+; UNCHECKED-NEXT:    add x16, x16, #256
+; UNCHECKED-NEXT:    ldrsw x17, [x16]
+; UNCHECKED-NEXT:    add x16, x16, x17
+; UNCHECKED-NEXT:    pacia x16, x2
+; UNCHECKED-NEXT:    mov x0, x16
+; UNCHECKED-NEXT:    ret
+;
+; CHECKED-LABEL: test_resign_load_relative_da_ia:
+; CHECKED:         %bb.0:
+; CHECKED-NEXT:    mov x16, x0
+; CHECKED-NEXT:    autda x16, x1
+; CHECKED-NEXT:    mov x17, x16
+; CHECKED-NEXT:    xpacd x17
+; CHECKED-NEXT:    cmp x16, x17
+; CHECKED-NEXT:    b.eq [[L]]auth_success_2
+; CHECKED-NEXT:    mov x16, x17
+; CHECKED-NEXT:    b [[L]]resign_end_2
+; CHECKED-NEXT:  Lauth_success_2:
+; CHECKED-NEXT:    add x16, x16, #256
+; CHECKED-NEXT:    ldrsw x17, [x16]
+; CHECKED-NEXT:    add x16, x16, x17
+; CHECKED-NEXT:    pacia x16, x2
+; CHECKED-NEXT:  Lresign_end_2:
+; CHECKED-NEXT:    mov x0, x16
+; CHECKED-NEXT:    ret
+;
+; TRAP-LABEL: test_resign_load_relative_da_ia:
+; TRAP:         %bb.0:
+; TRAP-NEXT:    mov x16, x0
+; TRAP-NEXT:    autda x16, x1
+; TRAP-NEXT:    mov x17, x16
+; TRAP-NEXT:    xpacd x17
+; TRAP-NEXT:    cmp x16, x17
+; TRAP-NEXT:    b.eq [[L]]auth_success_2
+; TRAP-NEXT:    brk #0xc472
+; TRAP-NEXT:  Lauth_success_2:
+; TRAP-NEXT:    add x16, x16, #256
+; TRAP-NEXT:    ldrsw x17, [x16]
+; TRAP-NEXT:    add x16, x16, x17
+; TRAP-NEXT:    pacia x16, x2
+; TRAP-NEXT:    mov x0, x16
+; TRAP-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.resign.load.relative(i64 %arg, i32 2, i64 
%arg1, i32 0, i64 %arg2, i64 256)
+  ret i64 %tmp
+}
+
+define i64 @test_resign_load_relative_db_da(i64 %arg, i64 %arg1, i64 %arg2) {
+; UNCHECKED-LABEL: test_resign_load_relative_db_da:
+; UNCHECKED:         %bb.0:
+; UNCHECKED-NEXT:    mov x16, x0
+; UNCHECKED-NEXT:    autdb x16, x1
+; UNCHECKED-NEXT:    add x16, x16, #256
+; UNCHECKED-NEXT:    ldrsw x17, [x16]
+; UNCHECKED-NEXT:    add x16, x16, x17
+; UNCHECKED-NEXT:    pacda x16, x2
+; UNCHECKED-NEXT:    mov x0, x16
+; UNCHECKED-NEXT:    ret
+;
+; CHECKED-LABEL: test_resign_load_relative_db_da:
+; CHECKED:         %bb.0:
+; CHECKED-NEXT:    mov x16, x0
+; CHECKED-NEXT:    autdb x16, x1
+; CHECKED-NEXT:    mov x17, x16
+; CHECKED-NEXT:    xpacd x17
+; CHECKED-NEXT:    cmp x16, x17
+; CHECKED-NEXT:    b.eq [[L]]auth_success_3
+; CHECKED-NEXT:    mov x16, x17
+; CHECKED-NEXT:    b [[L]]resign_end_3
+; CHECKED-NEXT:  Lauth_success_3:
+; CHECKED-NEXT:    add x16, x16, #256
+; CHECKED-NEXT:    ldrsw x17, [x16]
+; CHECKED-NEXT:    add x16, x16, x17
+; CHECKED-NEXT:    pacda x16, x2
+; CHECKED-NEXT:  Lresign_end_3:
+; CHECKED-NEXT:    mov x0, x16
+; CHECKED-NEXT:    ret
+;
+; TRAP-LABEL: test_resign_load_relative_db_da:
+; TRAP:         %bb.0:
+; TRAP-NEXT:    mov x16, x0
+; TRAP-NEXT:    autdb x16, x1
+; TRAP-NEXT:    mov x17, x16
+; TRAP-NEXT:    xpacd x17
+; TRAP-NEXT:    cmp x16, x17
+; TRAP-NEXT:    b.eq [[L]]auth_success_3
+; TRAP-NEXT:    brk #0xc473
+; TRAP-NEXT:  Lauth_success_3:
+; TRAP-NEXT:    add x16, x16, #256
+; TRAP-NEXT:    ldrsw x17, [x16]
+; TRAP-NEXT:    add x16, x16, x17
+; TRAP-NEXT:    pacda x16, x2
+; TRAP-NEXT:    mov x0, x16
+; TRAP-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.resign.load.relative(i64 %arg, i32 3, i64 
%arg1, i32 2, i64 %arg2, i64 256)
+  ret i64 %tmp
+}
+
+define i64 @test_resign_load_relative_iza_db(i64 %arg, i64 %arg1, i64 %arg2) {
+; UNCHECKED-LABEL: test_resign_load_relative_iza_db:
+; UNCHECKED:         %bb.0:
+; UNCHECKED-NEXT:    mov x16, x0
+; UNCHECKED-NEXT:    autiza x16
+; UNCHECKED-NEXT:    add x16, x16, #256
+; UNCHECKED-NEXT:    ldrsw x17, [x16]
+; UNCHECKED-NEXT:    add x16, x16, x17
+; UNCHECKED-NEXT:    pacdb x16, x2
+; UNCHECKED-NEXT:    mov x0, x16
+; UNCHECKED-NEXT:    ret
+;
+; CHECKED-LABEL: test_resign_load_relative_iza_db:
+; CHECKED:         %bb.0:
+; CHECKED-NEXT:    mov x16, x0
+; CHECKED-NEXT:    autiza x16
+; CHECKED-NEXT:    mov x17, x16
+; CHECKED-NEXT:    xpaci x17
+; CHECKED-NEXT:    cmp x16, x17
+; CHECKED-NEXT:    b.eq [[L]]auth_success_4
+; CHECKED-NEXT:    mov x16, x17
+; CHECKED-NEXT:    b [[L]]resign_end_4
+; CHECKED-NEXT:  Lauth_success_4:
+; CHECKED-NEXT:    add x16, x16, #256
+; CHECKED-NEXT:    ldrsw x17, [x16]
+; CHECKED-NEXT:    add x16, x16, x17
+; CHECKED-NEXT:    pacdb x16, x2
+; CHECKED-NEXT:  Lresign_end_4:
+; CHECKED-NEXT:    mov x0, x16
+; CHECKED-NEXT:    ret
+;
+; TRAP-LABEL: test_resign_load_relative_iza_db:
+; TRAP:         %bb.0:
+; TRAP-NEXT:    mov x16, x0
+; TRAP-NEXT:    autiza x16
+; TRAP-NEXT:    mov x17, x16
+; TRAP-NEXT:    xpaci x17
+; TRAP-NEXT:    cmp x16, x17
+; TRAP-NEXT:    b.eq [[L]]auth_success_4
+; TRAP-NEXT:    brk #0xc470
+; TRAP-NEXT:  Lauth_success_4:
+; TRAP-NEXT:    add x16, x16, #256
+; TRAP-NEXT:    ldrsw x17, [x16]
+; TRAP-NEXT:    add x16, x16, x17
+; TRAP-NEXT:    pacdb x16, x2
+; TRAP-NEXT:    mov x0, x16
+; TRAP-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.resign.load.relative(i64 %arg, i32 0, i64 0, 
i32 3, i64 %arg2, i64 256)
+  ret i64 %tmp
+}
+
+define i64 @test_resign_load_relative_da_dzb(i64 %arg, i64 %arg1, i64 %arg2) {
+; UNCHECKED-LABEL: test_resign_load_relative_da_dzb:
+; UNCHECKED:         %bb.0:
+; UNCHECKED-NEXT:    mov x16, x0
+; UNCHECKED-NEXT:    autda x16, x1
+; UNCHECKED-NEXT:    add x16, x16, #256
+; UNCHECKED-NEXT:    ldrsw x17, [x16]
+; UNCHECKED-NEXT:    add x16, x16, x17
+; UNCHECKED-NEXT:    pacdzb x16
+; UNCHECKED-NEXT:    mov x0, x16
+; UNCHECKED-NEXT:    ret
+;
+; CHECKED-LABEL: test_resign_load_relative_da_dzb:
+; CHECKED:         %bb.0:
+; CHECKED-NEXT:    mov x16, x0
+; CHECKED-NEXT:    autda x16, x1
+; CHECKED-NEXT:    mov x17, x16
+; CHECKED-NEXT:    xpacd x17
+; CHECKED-NEXT:    cmp x16, x17
+; CHECKED-NEXT:    b.eq [[L]]auth_success_5
+; CHECKED-NEXT:    mov x16, x17
+; CHECKED-NEXT:    b [[L]]resign_end_5
+; CHECKED-NEXT:  Lauth_success_5:
+; CHECKED-NEXT:    add x16, x16, #256
+; CHECKED-NEXT:    ldrsw x17, [x16]
+; CHECKED-NEXT:    add x16, x16, x17
+; CHECKED-NEXT:    pacdzb x16
+; CHECKED-NEXT:  Lresign_end_5:
+; CHECKED-NEXT:    mov x0, x16
+; CHECKED-NEXT:    ret
+;
+; TRAP-LABEL: test_resign_load_relative_da_dzb:
+; TRAP:         %bb.0:
+; TRAP-NEXT:    mov x16, x0
+; TRAP-NEXT:    autda x16, x1
+; TRAP-NEXT:    mov x17, x16
+; TRAP-NEXT:    xpacd x17
+; TRAP-NEXT:    cmp x16, x17
+; TRAP-NEXT:    b.eq [[L]]auth_success_5
+; TRAP-NEXT:    brk #0xc472
+; TRAP-NEXT:  Lauth_success_5:
+; TRAP-NEXT:    add x16, x16, #256
+; TRAP-NEXT:    ldrsw x17, [x16]
+; TRAP-NEXT:    add x16, x16, x17
+; TRAP-NEXT:    pacdzb x16
+; TRAP-NEXT:    mov x0, x16
+; TRAP-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.resign.load.relative(i64 %arg, i32 2, i64 
%arg1, i32 3, i64 0,i64 256)
+  ret i64 %tmp
+}
+
+define i64 @test_resign_load_relative_da_constdisc(i64 %arg, i64 %arg1) {
+; UNCHECKED-LABEL: test_resign_load_relative_da_constdisc:
+; UNCHECKED:         %bb.0:
+; UNCHECKED-NEXT:    mov x16, x0
+; UNCHECKED-NEXT:    autda x16, x1
+; UNCHECKED-NEXT:    add x16, x16, #256
+; UNCHECKED-NEXT:    ldrsw x17, [x16]
+; UNCHECKED-NEXT:    add x16, x16, x17
+; UNCHECKED-NEXT:    mov x17, #256 
+; UNCHECKED-NEXT:    pacda x16, x17
+; UNCHECKED-NEXT:    mov x0, x16
+; UNCHECKED-NEXT:    ret
+;
+; CHECKED-LABEL: test_resign_load_relative_da_constdisc:
+; CHECKED:         %bb.0:
+; CHECKED-NEXT:    mov x16, x0
+; CHECKED-NEXT:    autda x16, x1
+; CHECKED-NEXT:    mov x17, x16
+; CHECKED-NEXT:    xpacd x17
+; CHECKED-NEXT:    cmp x16, x17
+; CHECKED-NEXT:    b.eq [[L]]auth_success_6
+; CHECKED-NEXT:    mov x16, x17
+; CHECKED-NEXT:    b [[L]]resign_end_6
+; CHECKED-NEXT:  Lauth_success_6:
+; CHECKED-NEXT:    add x16, x16, #256
+; CHECKED-NEXT:    ldrsw x17, [x16]
+; CHECKED-NEXT:    add x16, x16, x17
+; CHECKED-NEXT:    mov x17, #256 
+; CHECKED-NEXT:    pacda x16, x17
+; CHECKED-NEXT:  Lresign_end_6:
+; CHECKED-NEXT:    mov x0, x16
+; CHECKED-NEXT:    ret
+;
+; TRAP-LABEL: test_resign_load_relative_da_constdisc:
+; TRAP:         %bb.0:
+; TRAP-NEXT:    mov x16, x0
+; TRAP-NEXT:    autda x16, x1
+; TRAP-NEXT:    mov x17, x16
+; TRAP-NEXT:    xpacd x17
+; TRAP-NEXT:    cmp x16, x17
+; TRAP-NEXT:    b.eq [[L]]auth_success_6
+; TRAP-NEXT:    brk #0xc472
+; TRAP-NEXT:  Lauth_success_6:
+; TRAP-NEXT:    add x16, x16, #256
+; TRAP-NEXT:    ldrsw x17, [x16]
+; TRAP-NEXT:    add x16, x16, x17
+; TRAP-NEXT:    mov x17, #256 
+; TRAP-NEXT:    pacda x16, x17
+; TRAP-NEXT:    mov x0, x16
+; TRAP-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.resign.load.relative(i64 %arg, i32 2, i64 
%arg1, i32 2, i64 256,i64 256)
+  ret i64 %tmp
+}
+
+; note: addend is larger than 24bit integer
+define i64 @test_resign_load_relative_loadNegOffset_constdisc(i64 %arg,i64 
%arg1) {
+; UNCHECKED-LABEL: test_resign_load_relative_loadNegOffset_constdisc:
+; UNCHECKED:         %bb.0:
+; UNCHECKED-NEXT:    mov x16, x0
+; UNCHECKED-NEXT:    autda x16, x1
+; UNCHECKED-NEXT:    mov x17, #62980 
+; UNCHECKED-NEXT:    movk x17, #65535, lsl #16
+; UNCHECKED-NEXT:    movk x17, #65535, lsl #32
+; UNCHECKED-NEXT:    movk x17, #65535, lsl #48
+; UNCHECKED-NEXT:    add x16, x16, x17
+; UNCHECKED-NEXT:    ldrsw x17, [x16]
+; UNCHECKED-NEXT:    add x16, x16, x17
+; UNCHECKED-NEXT:    mov x17, #256 
+; UNCHECKED-NEXT:    pacda x16, x17
+; UNCHECKED-NEXT:    mov x0, x16
+; UNCHECKED-NEXT:    ret
+;
+; CHECKED-LABEL: test_resign_load_relative_loadNegOffset_constdisc:
+; CHECKED:         %bb.0:
+; CHECKED-NEXT:    mov x16, x0
+; CHECKED-NEXT:    autda x16, x1
+; CHECKED-NEXT:    mov x17, x16
+; CHECKED-NEXT:    xpacd x17
+; CHECKED-NEXT:    cmp x16, x17
+; CHECKED-NEXT:    b.eq [[L]]auth_success_7
+; CHECKED-NEXT:    mov x16, x17
+; CHECKED-NEXT:    b [[L]]resign_end_7
+; CHECKED-NEXT:  Lauth_success_7:
+; CHECKED-NEXT:    mov x17, #62980 
+; CHECKED-NEXT:    movk x17, #65535, lsl #16
+; CHECKED-NEXT:    movk x17, #65535, lsl #32
+; CHECKED-NEXT:    movk x17, #65535, lsl #48
+; CHECKED-NEXT:    add x16, x16, x17
+; CHECKED-NEXT:    ldrsw x17, [x16]
+; CHECKED-NEXT:    add x16, x16, x17
+; CHECKED-NEXT:    mov x17, #256 
+; CHECKED-NEXT:    pacda x16, x17
+; CHECKED-NEXT:  Lresign_end_7:
+; CHECKED-NEXT:    mov x0, x16
+; CHECKED-NEXT:    ret
+;
+; TRAP-LABEL: test_resign_load_relative_loadNegOffset_constdisc:
+; TRAP:         %bb.0:
+; TRAP-NEXT:    mov x16, x0
+; TRAP-NEXT:    autda x16, x1
+; TRAP-NEXT:    mov x17, x16
+; TRAP-NEXT:    xpacd x17
+; TRAP-NEXT:    cmp x16, x17
+; TRAP-NEXT:    b.eq [[L]]auth_success_7
+; TRAP-NEXT:    brk #0xc472
+; TRAP-NEXT:  Lauth_success_7:
+; TRAP-NEXT:    mov x17, #62980
+; TRAP-NEXT:    movk x17, #65535, lsl #16
+; TRAP-NEXT:    movk x17, #65535, lsl #32
+; TRAP-NEXT:    movk x17, #65535, lsl #48
+; TRAP-NEXT:    add x16, x16, x17
+; TRAP-NEXT:    ldrsw x17, [x16]
+; TRAP-NEXT:    add x16, x16, x17
+; TRAP-NEXT:    mov x17, #256 
+; TRAP-NEXT:    pacda x16, x17
+; TRAP-NEXT:    mov x0, x16
+; TRAP-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.resign.load.relative(i64 %arg,i32 2,i64 
%arg1,i32 2,i64 256,i64 -2556)
+  ret i64 %tmp
+}
+define i64 @test_resign_load_relative_largeOffset_constdisc(i64 %arg,i64 
%arg1) {
+; UNCHECKED-LABEL: test_resign_load_relative_largeOffset_constdisc:
+; UNCHECKED:         %bb.0:
+; UNCHECKED-NEXT:    mov x16, x0
+; UNCHECKED-NEXT:    autda x16, x1
+; UNCHECKED-NEXT:    add x16, x16, #3884
+; UNCHECKED-NEXT:    add x16, x16, #7, lsl #12
+; UNCHECKED-NEXT:    ldrsw x17, [x16]
+; UNCHECKED-NEXT:    add x16, x16, x17
+; UNCHECKED-NEXT:    mov x17, #256 
+; UNCHECKED-NEXT:    pacda x16, x17
+; UNCHECKED-NEXT:    mov x0, x16
+; UNCHECKED-NEXT:    ret
+;
+; CHECKED-LABEL: test_resign_load_relative_largeOffset_constdisc:
+; CHECKED:         %bb.0:
+; CHECKED-NEXT:    mov x16, x0
+; CHECKED-NEXT:    autda x16, x1
+; CHECKED-NEXT:    mov x17, x16
+; CHECKED-NEXT:    xpacd x17
+; CHECKED-NEXT:    cmp x16, x17
+; CHECKED-NEXT:    b.eq [[L]]auth_success_8
+; CHECKED-NEXT:    mov x16, x17
+; CHECKED-NEXT:    b [[L]]resign_end_8
+; CHECKED-NEXT:  Lauth_success_8:
+; CHECKED-NEXT:    add x16, x16, #3884
+; CHECKED-NEXT:    add x16, x16, #7, lsl #12 
+; CHECKED-NEXT:    ldrsw x17, [x16]
+; CHECKED-NEXT:    add x16, x16, x17
+; CHECKED-NEXT:    mov x17, #256 
+; CHECKED-NEXT:    pacda x16, x17
+; CHECKED-NEXT:  Lresign_end_8:
+; CHECKED-NEXT:    mov x0, x16
+; CHECKED-NEXT:    ret
+;
+; TRAP-LABEL: test_resign_load_relative_largeOffset_constdisc:
+; TRAP:         %bb.0:
+; TRAP-NEXT:    mov x16, x0
+; TRAP-NEXT:    autda x16, x1
+; TRAP-NEXT:    mov x17, x16
+; TRAP-NEXT:    xpacd x17
+; TRAP-NEXT:    cmp x16, x17
+; TRAP-NEXT:    b.eq [[L]]auth_success_8
+; TRAP-NEXT:    brk #0xc472
+; TRAP-NEXT:  Lauth_success_8:
+; TRAP-NEXT:    add x16, x16, #3884
+; TRAP-NEXT:    add x16, x16, #7, lsl #12 
+; TRAP-NEXT:    ldrsw x17, [x16]
+; TRAP-NEXT:    add x16, x16, x17
+; TRAP-NEXT:    mov x17, #256 
+; TRAP-NEXT:    pacda x16, x17
+; TRAP-NEXT:    mov x0, x16
+; TRAP-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.resign.load.relative(i64 %arg,i32 2,i64 
%arg1,i32 2,i64 256,i64 32556)
+  ret i64 %tmp
+}
+declare i64 @llvm.ptrauth.auth(i64, i32, i64)
+declare i64 @llvm.ptrauth.resign(i64, i32, i64, i32, i64)
+declare i64 @llvm.ptrauth.resign.load.relative(i64,i32,i64,i32,i64,i64)

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to