llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-mc

Author: Kerry McLaughlin (kmclaughlin-arm)

<details>
<summary>Changes</summary>

The .cfi_set_ra_state directive indicates whether the value of PC was used
as a diversifier for return address signing. However, it is not sufficient
to distinguish whether hint-space instructions were used.

For example, when PSTATE.PACM is 1, then the PACIASP instruction is extended
to take the PC as an additional diversifier. This means that the hint-space
sequence PACM; PACIASP may produce the same result as the FEAT_PAUTH_LR
instruction PACIASPPC.

However, if PACM has a trivial implementation and does not affect PSTATE.PACM,
the sequences will give different results [1].

If FEAT_PAuth_LR instructions were used to sign the return address, the
CFI directive .cfi_non_hint_pauth_frame is emitted for the frame and the
'N' character will be added to the CIE augmentation string [2]. Libunwind
uses this information to recover the correct sequence of instructions for
authentication which matches signing (e.g. PACM; AUTIA1716 or AUTIA171615).

[1] Issue: https://github.com/ARM-software/abi-aa/issues/396
[2] ABI: 
https://github.com/ARM-software/abi-aa/blob/main/aadwarf64/aadwarf64.rst#<!-- 
-->43common-information-entries

---

Patch is 84.65 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/233885.diff


20 Files Affected:

- (modified) libunwind/src/DwarfInstructions.hpp (+33-10) 
- (modified) libunwind/src/DwarfParser.hpp (+5) 
- (added) libunwind/test/ra_sign_state_lr.pass.cpp (+159) 
- (modified) llvm/include/llvm/MC/MCDwarf.h (+1) 
- (modified) llvm/include/llvm/MC/MCStreamer.h (+1) 
- (modified) llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp (+4) 
- (modified) llvm/lib/MC/MCAsmStreamer.cpp (+7) 
- (modified) llvm/lib/MC/MCDwarf.cpp (+9-4) 
- (modified) llvm/lib/MC/MCStreamer.cpp (+7) 
- (modified) llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp (+7-2) 
- (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.td (+4) 
- (modified) llvm/lib/Target/AArch64/AArch64PointerAuth.cpp (+2) 
- (modified) llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp (+12) 
- (modified) llvm/test/CodeGen/AArch64/pauth-lr-tail-call-fpdiff.ll (+8) 
- (modified) llvm/test/CodeGen/AArch64/sign-return-address-pauth-lr-mir.ll 
(+13) 
- (modified) llvm/test/CodeGen/AArch64/sign-return-address-pauth-lr.ll (+29-3) 
- (modified) llvm/test/CodeGen/AArch64/sign-return-address-pauthlr-slh.ll (+2) 
- (modified) llvm/test/CodeGen/AArch64/swifttail-ptrauth.ll (+4) 
- (modified) llvm/test/MC/AArch64/directives-case_insensitive.s (+2) 
- (modified) llvm/test/MC/ELF/AArch64/cfi.s (+292-277) 


``````````diff
diff --git a/libunwind/src/DwarfInstructions.hpp 
b/libunwind/src/DwarfInstructions.hpp
index b06877d45f689..07c594ff668a8 100644
--- a/libunwind/src/DwarfInstructions.hpp
+++ b/libunwind/src/DwarfInstructions.hpp
@@ -84,6 +84,9 @@ class DwarfInstructions {
   static RASignStatus getReturnAddressSignStatus(A &addressSpace, R registers,
                                                  pint_t cfa,
                                                  PrologInfo &prolog);
+
+  __attribute__((target("pauth-lr"))) static pint_t
+  emitPAuthLRInsts(pint_t ptrAuthDiv, pint_t cfa, pint_t returnAddr, bool 
BKey);
 #endif
 };
 
@@ -204,6 +207,21 @@ DwarfInstructions<A, R>::getReturnAddressSignStatus(A 
&addressSpace,
   assert((raSignState & 0x3) != 3 && "unexpected RA sign state");
   return static_cast<RASignStatus>(raSignState & 0x3);
 }
+
+template <typename A, typename R>
+__attribute__((target("pauth-lr"))) typename A::pint_t
+DwarfInstructions<A, R>::emitPAuthLRInsts(pint_t ptrAuthDiv, pint_t cfa,
+                                          pint_t returnAddr, bool BKey) {
+  register unsigned long long x15 __asm("x15") = ptrAuthDiv;
+  register unsigned long long x16 __asm("x16") = cfa;
+  register unsigned long long x17 __asm("x17") = returnAddr;
+  if (BKey)
+    asm("autib171615" : "+r"(x17) : "r"(x16), "r"(x15));
+  else
+    asm("autia171615" : "+r"(x17) : "r"(x16), "r"(x15));
+
+  return x17;
+}
 #endif
 
 template <typename A, typename R>
@@ -343,18 +361,23 @@ int DwarfInstructions<A, R>::stepWithDwarf(
         if (RAState == RASignedWithPC) {
           register unsigned long long x15 __asm("x15") =
               prolog.ptrAuthDiversifier;
-          if (cieInfo.addressesSignedWithBKey) {
-            asm("hint 0x27\n\t" // pacm
-                "hint 0xe"
-                : "+r"(x17)
-                : "r"(x16), "r"(x15)); // autib1716
-          } else {
-            asm("hint 0x27\n\t" // pacm
-                "hint 0xc"
-                : "+r"(x17)
-                : "r"(x16), "r"(x15)); // autia1716
+          if (cieInfo.nonHintPAuthFrame)
+            x17 =
+                emitPAuthLRInsts(prolog.ptrAuthDiversifier, cfa, returnAddress,
+                                 cieInfo.addressesSignedWithBKey);
+          else {
+            asm("hint 0x27\n\t"); // pacm
+
+            if (cieInfo.addressesSignedWithBKey) {
+              asm("hint 0xe" : "+r"(x17) : "r"(x16), "r"(x15)); // autib1716
+            } else {
+              asm("hint 0xc" : "+r"(x17) : "r"(x16), "r"(x15)); // autia1716
+            }
           }
         } else {
+          assert(!cieInfo.nonHintPAuthFrame &&
+                 "Non-hint space FEAT_PAuth_LR instructions expect"
+                 "RASignedWithPC");
           if (cieInfo.addressesSignedWithBKey)
             asm("hint 0xe" : "+r"(x17) : "r"(x16)); // autib1716
           else
diff --git a/libunwind/src/DwarfParser.hpp b/libunwind/src/DwarfParser.hpp
index d60e3e11325d3..cb276ab3cfdf4 100644
--- a/libunwind/src/DwarfParser.hpp
+++ b/libunwind/src/DwarfParser.hpp
@@ -57,6 +57,7 @@ class CFI_Parser {
 #if defined(_LIBUNWIND_TARGET_AARCH64)
     bool      addressesSignedWithBKey;
     bool      mteTaggedFrame;
+    bool      nonHintPAuthFrame;
 #endif
   };
 
@@ -342,6 +343,7 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t 
cie,
 #if defined(_LIBUNWIND_TARGET_AARCH64)
   cieInfo->addressesSignedWithBKey = false;
   cieInfo->mteTaggedFrame = false;
+  cieInfo->nonHintPAuthFrame = false;
 #endif
   cieInfo->cieStart = cie;
   pint_t p = cie;
@@ -443,6 +445,9 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t 
cie,
       case 'G':
         cieInfo->mteTaggedFrame = true;
         break;
+      case 'N':
+        cieInfo->nonHintPAuthFrame = true;
+        break;
 #endif
       default:
         // ignore unknown letters
diff --git a/libunwind/test/ra_sign_state_lr.pass.cpp 
b/libunwind/test/ra_sign_state_lr.pass.cpp
new file mode 100644
index 0000000000000..86ac6da1bee95
--- /dev/null
+++ b/libunwind/test/ra_sign_state_lr.pass.cpp
@@ -0,0 +1,159 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// clang-format off
+
+// REQUIRES: target={{aarch64.*}}
+// UNSUPPORTED: target={{.*-windows.*}}
+
+// clang-format on
+
+#undef NDEBUG
+#include "../src/config.h"
+#include "support/func_bounds.h"
+
+#include <assert.h>
+#include <inttypes.h>
+#include <libunwind.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <unwind.h>
+
+#if defined(_LIBUNWIND_HAVE_GETAUXVAL) || defined(_LIBUNWIND_HAVE_ELF_AUX_INFO)
+#include <asm/hwcap.h>
+#include <sys/auxv.h>
+#endif
+
+// Note: This test requires FEAT_PAuth_LR (and is setup to pass on other
+// targets).
+
+static bool hasPAuthLR() {
+  uint64_t isa_r1, isa_r2;
+  asm("mrs %0, ID_AA64ISAR1_EL1" : "=r"(isa_r1));
+  asm("mrs %0, ID_AA64ISAR2_EL1" : "=r"(isa_r2));
+
+  uint64_t api = (isa_r1 >> 8) & 0xf;
+  uint64_t apa = (isa_r1 >> 4) & 0xf;
+  uint64_t apa3 = (isa_r2 >> 12) & 0xf;
+
+  return api == 6 || apa == 6 || apa3 == 6;
+}
+
+#if defined(_LIBUNWIND_HAVE_GETAUXVAL)
+static bool checkHasPAuthLR() {
+  unsigned long hwcap = getauxval(AT_HWCAP);
+  if ((hwcap & HWCAP_CPUID) == 0)
+    return false;
+
+  return hasPAuthLR();
+}
+#elif defined(_LIBUNWIND_HAVE_ELF_AUX_INFO)
+static bool checkHasPAuthLR() {
+  unsigned long hwcap;
+  if (elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)) != 0)
+    return false;
+
+  if ((hwcap & HWCAP_CPUID) == 0)
+    return false;
+
+  return hasPAuthLR();
+}
+#elif defined(_LIBUNWIND_IS_BAREMETAL)
+static bool checkHasPAuthLR() {
+  return hasPAuthLR();
+}
+#else
+static bool checkHasPAuthLR() {
+  // TODO: Support other platforms.
+  return false;
+}
+#endif
+
+FUNC_BOUNDS_DECL(main_func);
+
+static _Unwind_Reason_Code frame_handler(struct _Unwind_Context *ctx,
+                                         void *arg) {
+  fprintf(stderr, "frame_handler\n");
+  uintptr_t ip = _Unwind_GetIP(ctx);
+
+  if (ip >= (uintptr_t)FUNC_START(main_func) &&
+      ip < (uintptr_t)FUNC_END(main_func)) {
+    *(bool *)arg = true;
+
+    // Unwind until main is reached, above frames depend on the platform and
+    // architecture.
+    return _URC_END_OF_STACK;
+  }
+
+  return _URC_NO_REASON;
+}
+
+__attribute__((noinline)) extern "C" uintptr_t reaches_main_via_backtrace() {
+  bool reached_main = false;
+  _Unwind_Backtrace(frame_handler, &reached_main);
+  fprintf(stderr, "reached_main = %d\n", reached_main);
+  return reached_main;
+}
+
+__attribute__((noinline)) static uint64_t check_vanilla() {
+  return reaches_main_via_backtrace();
+}
+
+#if defined(HAVE_CFI_SET_RA_STATE)
+__attribute__((naked, target("pauth-lr"))) uint64_t check_set() {
+  // clang-format off
+  asm(
+      ".cfi_b_key_frame\n"
+      ".cfi_non_hint_pauth_frame\n"
+      ".Lsign:\n"
+      "pacibsppc\n"
+      ".cfi_set_ra_state 2, .Lsign\n"
+
+      "stp x29, x30, [sp, #-16]!\n"
+      ".cfi_def_cfa_offset 16\n"
+      ".cfi_offset x29, -16\n"
+      ".cfi_offset x30, -8\n"
+
+      "bl " SYMBOL_NAME(reaches_main_via_backtrace) "\n"
+
+      "ldp x29, x30, [sp], #16\n"
+      ".cfi_def_cfa_offset 0\n"
+      ".cfi_restore x29\n"
+      ".cfi_restore x30\n"
+
+      ".cfi_set_ra_state 0, -20\n"
+      "retabsppc .Lsign");
+  // clang-format on
+}
+#endif
+
+FUNC_ATTR(main_func) int main(int, char **) {
+  uint64_t ret;
+
+  ret = check_vanilla();
+  fprintf(stderr, "check_vanilla: ret = 0x%" PRIx64 "\n", ret);
+  assert(ret == 1);
+
+  if (!checkHasPAuthLR()) {
+    fprintf(stderr, "target does not have FEAT_PAuth_LR\n");
+    return 0;
+  }
+
+#if defined(HAVE_CFI_SET_RA_STATE)
+  ret = check_set();
+  fprintf(stderr, "check_set: ret = 0x%" PRIx64 "\n", ret);
+  assert(ret == 1);
+#endif
+
+  fprintf(stderr, "success\n");
+  return 0;
+}
diff --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h
index 3534a4f349331..ce9237efd4280 100644
--- a/llvm/include/llvm/MC/MCDwarf.h
+++ b/llvm/include/llvm/MC/MCDwarf.h
@@ -913,6 +913,7 @@ struct MCDwarfFrameInfo {
   unsigned RAReg = static_cast<unsigned>(INT_MAX);
   bool IsBKeyFrame = false;
   bool IsMTETaggedFrame = false;
+  bool IsNonHintPAuthFrame = false;
 };
 
 // Emit DWARF call frame information and, when available, compact unwind
diff --git a/llvm/include/llvm/MC/MCStreamer.h 
b/llvm/include/llvm/MC/MCStreamer.h
index 614b8d79c5da4..33e8c78d8eae8 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -915,6 +915,7 @@ class LLVM_ABI MCStreamer {
 
   virtual void emitCFIBKeyFrame();
   virtual void emitCFIMTETaggedFrame();
+  virtual void emitCFINonHintPAuthFrame();
 
   /// This implements the DWARF2 '.loc fileno lineno ...' assembler
   /// directive.
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp 
b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index b88967ae20cfa..ebcc67100a2d1 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
@@ -312,6 +312,10 @@ Error DWARFDebugFrame::parse(DWARFDataExtractor Data, bool 
ParseCFIProgram) {
             // untagged on unwind.
           case 'G':
             break;
+          case 'N':
+            // Non hint-space FEAT_PAuth_LR instructions used for signing
+            // functions associated with this augmentation string.
+            break;
           }
         }
 
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 2dd964edb738a..16f5607b21a7c 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -473,6 +473,7 @@ class MCAsmStreamer final : public MCAsmBaseStreamer {
   void emitIdent(StringRef IdentString) override;
   void emitCFIBKeyFrame() override;
   void emitCFIMTETaggedFrame() override;
+  void emitCFINonHintPAuthFrame() override;
   void emitCFISections(bool EH, bool Debug, bool SFrame) override;
   void emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc) override;
   void emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc) override;
@@ -2436,6 +2437,12 @@ void MCAsmStreamer::emitCFIMTETaggedFrame() {
   EmitEOL();
 }
 
+void MCAsmStreamer::emitCFINonHintPAuthFrame() {
+  MCStreamer::emitCFINonHintPAuthFrame();
+  OS << "\t.cfi_non_hint_pauth_frame";
+  EmitEOL();
+}
+
 void MCAsmStreamer::emitCFIValOffset(int64_t Register, int64_t Offset,
                                      SMLoc Loc) {
   MCStreamer::emitCFIValOffset(Register, Offset, Loc);
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index da8e057f0f9ee..4aeb1e7d4ad42 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -1943,6 +1943,8 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(const 
MCDwarfFrameInfo &Frame) {
       Augmentation += "B";
     if (Frame.IsMTETaggedFrame)
       Augmentation += "G";
+    if (Frame.IsNonHintPAuthFrame)
+      Augmentation += "N";
     Streamer.emitBytes(Augmentation);
   }
   Streamer.emitInt8(0);
@@ -2112,7 +2114,8 @@ struct CIEKey {
         LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
         IsSimple(Frame.IsSimple), RAReg(Frame.RAReg),
         IsBKeyFrame(Frame.IsBKeyFrame),
-        IsMTETaggedFrame(Frame.IsMTETaggedFrame), IsEH(IsEH) {}
+        IsMTETaggedFrame(Frame.IsMTETaggedFrame),
+        IsNonHintPAuthFrame(Frame.IsNonHintPAuthFrame), IsEH(IsEH) {}
 
   StringRef PersonalityName() const {
     if (!Personality)
@@ -2128,11 +2131,11 @@ struct CIEKey {
 
     return std::make_tuple(PersonalityName(), PersonalityEncoding, 
LsdaEncoding,
                            IsSignalFrame, IsSimple, RAReg, IsBKeyFrame,
-                           IsMTETaggedFrame) <
+                           IsMTETaggedFrame, IsNonHintPAuthFrame) <
            std::make_tuple(Other.PersonalityName(), Other.PersonalityEncoding,
                            Other.LsdaEncoding, Other.IsSignalFrame,
                            Other.IsSimple, Other.RAReg, Other.IsBKeyFrame,
-                           Other.IsMTETaggedFrame);
+                           Other.IsMTETaggedFrame, Other.IsNonHintPAuthFrame);
   }
 
   bool operator==(const CIEKey &Other) const {
@@ -2145,7 +2148,8 @@ struct CIEKey {
            LsdaEncoding == Other.LsdaEncoding &&
            IsSignalFrame == Other.IsSignalFrame && IsSimple == Other.IsSimple 
&&
            RAReg == Other.RAReg && IsBKeyFrame == Other.IsBKeyFrame &&
-           IsMTETaggedFrame == Other.IsMTETaggedFrame;
+           IsMTETaggedFrame == Other.IsMTETaggedFrame &&
+           IsNonHintPAuthFrame == Other.IsNonHintPAuthFrame;
   }
   bool operator!=(const CIEKey &Other) const { return !(*this == Other); }
 
@@ -2157,6 +2161,7 @@ struct CIEKey {
   unsigned RAReg = UINT_MAX;
   bool IsBKeyFrame = false;
   bool IsMTETaggedFrame = false;
+  bool IsNonHintPAuthFrame = false;
   bool IsEH = false;
 };
 
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 1d51fbc46a43c..85ac375027539 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -232,6 +232,13 @@ void MCStreamer::emitCFIMTETaggedFrame() {
   CurFrame->IsMTETaggedFrame = true;
 }
 
+void MCStreamer::emitCFINonHintPAuthFrame() {
+  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
+  CurFrame->IsNonHintPAuthFrame = true;
+}
+
 void MCStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
                                        unsigned Column, unsigned Flags,
                                        unsigned Isa, unsigned Discriminator,
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp 
b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 683b8ffb94e43..acf89a3d90ca2 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -3588,7 +3588,8 @@ void AArch64AsmPrinter::emitInstruction(const 
MachineInstr *MI) {
     }
     return;
 
-  case AArch64::EMITBKEY: {
+  case AArch64::EMITBKEY:
+  case AArch64::EMITPAUTH: {
     ExceptionHandling ExceptionHandlingType = MAI.getExceptionHandlingType();
     if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
         ExceptionHandlingType != ExceptionHandling::ARM)
@@ -3597,7 +3598,11 @@ void AArch64AsmPrinter::emitInstruction(const 
MachineInstr *MI) {
     if (getFunctionCFISectionType(*MF) == CFISection::None)
       return;
 
-    OutStreamer->emitCFIBKeyFrame();
+    if (MI->getOpcode() == AArch64::EMITBKEY)
+      OutStreamer->emitCFIBKeyFrame();
+    else
+      OutStreamer->emitCFINonHintPAuthFrame();
+
     return;
   }
 
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td 
b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 2afc537225dca..61e01882ef53b 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -3791,6 +3791,10 @@ def EMITBKEY : Pseudo<(outs), (ins), []>, Sched<[]> {}
 // augmentation string.
 def EMITMTETAGGED : Pseudo<(outs), (ins), []>, Sched<[]> {}
 
+// Pseudo instruction to tell the streamer to emit an 'N' character into the
+// augmentation string.
+def EMITPAUTH : Pseudo<(outs), (ins), []>, Sched<[]> {}
+
 // FIXME: maybe the scratch register used shouldn't be fixed to X1?
 // FIXME: can "hasSideEffects be dropped?
 // This gets lowered to an instruction sequence which takes 16 bytes
diff --git a/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp 
b/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp
index 606a160e3572e..dd28f8ac66c5c 100644
--- a/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp
+++ b/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp
@@ -251,6 +251,8 @@ void AArch64PointerAuthImpl::signLR(MachineFunction &MF,
   // No SEH opcode for this one; it doesn't materialize into an
   // instruction on Windows.
   if (MFnI.branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) {
+    BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITPAUTH))
+        .setMIFlag(MachineInstr::FrameSetup);
     decoratePACWithCFI(MBB, MBBI, EmitCFI, [&]() {
       BuildMI(MBB, MBBI, DL,
               TII->get(UseBKey ? AArch64::PACIBSPPC : AArch64::PACIASPPC))
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp 
b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 69a807bf866fd..499df76938ec2 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -203,6 +203,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
   bool parseDirectiveCFILLVMSetRAState();
   bool parseDirectiveCFIBKeyFrame();
   bool parseDirectiveCFIMTETaggedFrame();
+  bool parseDirectiveCFINonHintPAuthFrame();
 
   bool parseDirectiveVariantPCS(SMLoc L);
 
@@ -7125,6 +7126,8 @@ bool AArch64AsmParser::ParseDirective(AsmToken 
DirectiveID) {
     parseDirectiveCFIBKeyFrame();
   else if (IDVal == ".cfi_mte_tagged_frame")
     parseDirectiveCFIMTETaggedFrame();
+  else if (IDVal == ".cfi_non_hint_pauth_frame")
+    parseDirectiveCFINonHintPAuthFrame();
   else if (IDVal == ".arch_extension")
     parseDirectiveArchExtension(Loc);
   else if (IDVal == ".variant_pcs")
@@ -7647,6 +7650,15 @@ bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() 
{
   return false;
 }
 
+/// parseDirectiveCFINonHintPAuthFrame
+/// ::= .cfi_non_hint_pauth_frame
+bool AArch64AsmParser::parseDirectiveCFINonHintPAuthFrame() {
+  if (parseEOL())
+    return true;
+  getStreamer().emitCFINonHintPAuthFrame();
+  return false;
+}
+
 /// parseDirectiveVariantPCS
 /// ::= .variant_pcs symbolname
 bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
diff --git a/llvm/test/CodeGen/AArch64/pauth-lr-tail-call-fpdiff.ll 
b/llvm/test/CodeGen/AArch64/pauth-lr-tail-call-fpdiff.ll
index 34a8dc5143eee..e416d57e66b37 100644
--- a/llvm/test/CodeGen/AArch64/pauth-lr-tail-call-fpdiff.ll
+++ b/llvm/test/CodeGen/AArch64/pauth-lr-tail-call-fpdiff.ll
@@ -27,6 +27,7 @@ define swifttailcc void @tail_call_fpdiff_a_key(ptr 
swiftasync %ctx) "branch-pro
 ; V83A-NEXT:     paciasp
 ; V83A-NEXT:     .cfi_set_ra_state 2, .Ltmp0
 
+; V9A-NEXT:      .cfi_non_hint_pauth_frame
 ; V9A-NEXT:    .Ltmp0:
 ; V9A-NEXT:      paciasppc
 ; V9A-NEXT:      .cfi_set_ra_state 2, .Ltmp0
@@ -109,6 +110,7 @@ define swifttailcc void @tail_call_fpdiff_b_key(ptr 
swiftasync %ctx) "branch-pro
 ; V83A-NEXT:     pacibsp
 ; V83A-NEXT:     .cfi_set_ra_state 2, .Ltmp1
 
+; V9A-NEXT:      .cfi_non_hint_pauth_frame
 ; V9A-NEXT:    .Ltmp1:
 ; V9A-NEXT:      pacibsppc
 ; V9A-NEXT:      .cfi_set_ra_state 2, .Ltmp1
@@ -190,6 +192,7 @@ define swifttailcc void @tail_call_no_fpdiff_a_key(ptr 
swiftasync %ctx) "branch-
 ; V83A-NEXT:     paciasp
 ; V83A-NEXT:     .cfi_set_ra_state 2, .Ltmp2
 
+; V9A-NEXT:      .cfi_non_hint_pauth_frame
 ; V9A-NEXT:    .Ltmp2:
 ; V9A-NEXT:      paciasppc
 ; V9A-NEXT:      .cfi_set_ra_state 2, .Ltmp2
@@ -253,6 +256,7 @@ define swifttailcc void @tail_call_no_fpdiff_b_key(ptr 
swiftasync %ctx) "branch-
 ; V83A-NEXT:     pacibsp
 ; V83A-NEXT:     .cfi_set_ra_state 2, .Ltmp3
 
+; V9A-NEXT:      .cfi_non_hint_pauth_frame
 ; V9A-NEXT:    .Ltmp3:
 ; V9A-NEXT:      pacibsppc
 ; V9A-NEXT:      .cfi_set_ra_state 2, .Ltmp3
@@ -315,6 +319,7 @@ define swifttailcc void 
@indirect_tail_call_fpdiff_a_key(ptr swiftasync %ctx, pt
 ; V83A-NEXT:     paciasp
 ; V83A-NEXT:     .cfi_set_ra_state 2, .Ltmp4
 
+; V9A-NEXT:      .cfi_non_hint_pauth_frame
 ; V9A-NEXT:    .Ltmp4:
 ; V9A-NEXT:      paciasppc
 ; V9A-NEXT:      .cfi_set_ra_state 2, .Ltmp4
@@ -398,6 +403,7 @@ define swifttailcc void 
@indirect_tail_call_fpdiff_b_key(ptr swiftasync %ctx, pt
 ; V83A-NEXT:     pacibsp
 ; V83A-NEXT:     .cfi_set_ra_state 2, .Ltmp5
 
+; V9A-NEXT:      .cfi_non_hint_pauth_frame
 ; V9A-NEXT:    .Ltmp5:
 ; V9A-NEXT:      pacibsppc
 ; V9A-NEXT:      .cfi_set_ra_state 2, .Ltmp5
@@ -480,6 +486,7 @@ define swifttailcc void 
@indirect_tail_call_no_fpdiff_a_key(ptr swiftasync %ctx,
 ; V83A-NEXT:     paciasp
 ; V83A-NEXT:     .cfi_set_ra_state 2, .Ltmp6
 
+; V9A-NEXT:      .cfi_non_hint_pauth_frame
 ; V9A-NEXT:    .Ltmp6:
 ; V9A-NEXT:      paciasppc
 ; V9A-NEXT:      .cfi_set_ra_state 2, .Ltmp6
@@ -543,6 +550,7 @@ define swifttailcc void 
@indirect_tail_call_no_fpdiff_b_key(ptr...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/233885
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to