[clang] [llvm] [PAC][Driver] Support `pauthtest` ABI for AArch64 Linux triples (PR #97237)

Daniil Kovalev via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 18 01:50:04 PDT 2024


https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/97237

>From 3b4b1b1739b810d758e68f30c48b648963cff740 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Mon, 1 Jul 2024 00:50:21 +0300
Subject: [PATCH 1/8] [PAC][Driver] Implement `-mbranch-protection=pauthabi`
 option

Enable the following ptrauth flags when `pauthabi` is passed as branch
protection:

- `intrinsics`;
- `calls`;
- `returns`;
- `auth-traps`;
- `vtable-pointer-address-discrimination`;
- `vtable-pointer-type-discrimination`;
- `init-fini`.

Co-authored-by: Anatoly Trosinenko <atrosinenko at accesssoftek.com>
---
 clang/lib/Driver/ToolChains/Clang.cpp         | 38 +++++++++++++++++++
 clang/test/Driver/aarch64-ptrauth.c           | 36 ++++++++++++++----
 .../llvm/TargetParser/ARMTargetParserCommon.h |  1 +
 .../TargetParser/ARMTargetParserCommon.cpp    |  6 ++-
 4 files changed, 72 insertions(+), 9 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 1b7cc82ea816e..4ed1ece22b7aa 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1484,6 +1484,39 @@ void AddUnalignedAccessWarning(ArgStringList &CmdArgs) {
 }
 }
 
+static void handlePAuthABIOption(const ArgList &DriverArgs,
+                                 ArgStringList &CC1Args, const Driver &D) {
+  if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics,
+                         options::OPT_fno_ptrauth_intrinsics))
+    CC1Args.push_back("-fptrauth-intrinsics");
+
+  if (!DriverArgs.hasArg(options::OPT_fptrauth_calls,
+                         options::OPT_fno_ptrauth_calls))
+    CC1Args.push_back("-fptrauth-calls");
+
+  if (!DriverArgs.hasArg(options::OPT_fptrauth_returns,
+                         options::OPT_fno_ptrauth_returns))
+    CC1Args.push_back("-fptrauth-returns");
+
+  if (!DriverArgs.hasArg(options::OPT_fptrauth_auth_traps,
+                         options::OPT_fno_ptrauth_auth_traps))
+    CC1Args.push_back("-fptrauth-auth-traps");
+
+  if (!DriverArgs.hasArg(
+          options::OPT_fptrauth_vtable_pointer_address_discrimination,
+          options::OPT_fno_ptrauth_vtable_pointer_address_discrimination))
+    CC1Args.push_back("-fptrauth-vtable-pointer-address-discrimination");
+
+  if (!DriverArgs.hasArg(
+          options::OPT_fptrauth_vtable_pointer_type_discrimination,
+          options::OPT_fno_ptrauth_vtable_pointer_type_discrimination))
+    CC1Args.push_back("-fptrauth-vtable-pointer-type-discrimination");
+
+  if (!DriverArgs.hasArg(options::OPT_fptrauth_init_fini,
+                         options::OPT_fno_ptrauth_init_fini))
+    CC1Args.push_back("-fptrauth-init-fini");
+}
+
 static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
                                     ArgStringList &CmdArgs, bool isAArch64) {
   const Arg *A = isAArch64
@@ -1537,11 +1570,16 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
     if (!isAArch64 && PBP.Key == "b_key")
       D.Diag(diag::warn_unsupported_branch_protection)
           << "b-key" << A->getAsString(Args);
+    if (!isAArch64 && PBP.HasPauthABI)
+      D.Diag(diag::warn_unsupported_branch_protection)
+          << "pauthabi" << A->getAsString(Args);
     Scope = PBP.Scope;
     Key = PBP.Key;
     BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
     IndirectBranches = PBP.BranchTargetEnforcement;
     GuardedControlStack = PBP.GuardedControlStack;
+    if (isAArch64 && PBP.HasPauthABI)
+      handlePAuthABIOption(Args, CmdArgs, D);
   }
 
   CmdArgs.push_back(
diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c
index fa0125f4b22a9..dc63545a47a86 100644
--- a/clang/test/Driver/aarch64-ptrauth.c
+++ b/clang/test/Driver/aarch64-ptrauth.c
@@ -13,13 +13,33 @@
 // RUN:   %s 2>&1 | FileCheck %s --check-prefix=ALL
 // ALL: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini"
 
+// RUN: %clang -### -c --target=aarch64 -mbranch-protection=pauthabi %s 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=PAUTHABI1
+// PAUTHABI1: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini"
+
+// RUN: %clang -### -c --target=aarch64 -mbranch-protection=pauthabi -fno-ptrauth-intrinsics \
+// RUN:   -fno-ptrauth-calls -fno-ptrauth-returns -fno-ptrauth-auth-traps \
+// RUN:   -fno-ptrauth-vtable-pointer-address-discrimination -fno-ptrauth-vtable-pointer-type-discrimination \
+// RUN:   -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2
+// PAUTHABI2-NOT: "-fptrauth-intrinsics"
+// PAUTHABI2-NOT: "-fptrauth-calls"
+// PAUTHABI2-NOT: "-fptrauth-returns"
+// PAUTHABI2-NOT: "-fptrauth-auth-traps"
+// PAUTHABI2-NOT: "-fptrauth-vtable-pointer-address-discrimination"
+// PAUTHABI2-NOT: "-fptrauth-vtable-pointer-type-discrimination"
+// PAUTHABI2-NOT: "-fptrauth-init-fini"
+
 // RUN: not %clang -### -c --target=x86_64 -fptrauth-intrinsics -fptrauth-calls -fptrauth-returns -fptrauth-auth-traps \
 // RUN:   -fptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-type-discrimination \
-// RUN:   -fptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=ERR
-// ERR:      error: unsupported option '-fptrauth-intrinsics' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-calls' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-returns' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-auth-traps' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-vtable-pointer-address-discrimination' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-vtable-pointer-type-discrimination' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-init-fini' for target '{{.*}}'
+// RUN:   -fptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=ERR1
+// ERR1:      error: unsupported option '-fptrauth-intrinsics' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-calls' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-returns' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-auth-traps' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-vtable-pointer-address-discrimination' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-vtable-pointer-type-discrimination' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-init-fini' for target '{{.*}}'
+
+// RUN: not %clang -### -c --target=x86_64 -mbranch-protection=pauthabi %s 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=ERR2
+// ERR2: error: unsupported option '-mbranch-protection=' for target 'x86_64'
diff --git a/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h b/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h
index f6115718e9f5f..ca634ed969d84 100644
--- a/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h
+++ b/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h
@@ -43,6 +43,7 @@ struct ParsedBranchProtection {
   bool BranchTargetEnforcement;
   bool BranchProtectionPAuthLR;
   bool GuardedControlStack;
+  bool HasPauthABI;
 };
 
 bool parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
diff --git a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
index d6ce6581bb1a9..0b1e6d3356f68 100644
--- a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
+++ b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
@@ -140,7 +140,7 @@ ARM::EndianKind ARM::parseArchEndian(StringRef Arch) {
 // an erroneous part of the spec.
 bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
                                 StringRef &Err, bool EnablePAuthLR) {
-  PBP = {"none", "a_key", false, false, false};
+  PBP = {"none", "a_key", false, false, false, false};
   if (Spec == "none")
     return true; // defaults are ok
 
@@ -160,6 +160,10 @@ bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
       PBP.BranchTargetEnforcement = true;
       continue;
     }
+    if (Opt == "pauthabi") {
+      PBP.HasPauthABI = true;
+      continue;
+    }
     if (Opt == "pac-ret") {
       PBP.Scope = "non-leaf";
       for (; I + 1 != E; ++I) {

>From fcd090caac9ede6b915db991819298bed4a5d44e Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Wed, 3 Jul 2024 12:52:18 +0300
Subject: [PATCH 2/8] Address review comments

---
 clang/lib/Driver/ToolChains/Clang.cpp | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 63134ab733e4b..3f9beb05215a9 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1484,8 +1484,11 @@ void AddUnalignedAccessWarning(ArgStringList &CmdArgs) {
 }
 }
 
+// Each combination of options here forms a signing schema, and in most cases
+// each signing schema is its own incompatible ABI. The default values of the
+// options represent the default signing schema.
 static void handlePAuthABIOption(const ArgList &DriverArgs,
-                                 ArgStringList &CC1Args, const Driver &D) {
+                                 ArgStringList &CC1Args) {
   if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics,
                          options::OPT_fno_ptrauth_intrinsics))
     CC1Args.push_back("-fptrauth-intrinsics");
@@ -1579,7 +1582,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
     IndirectBranches = PBP.BranchTargetEnforcement;
     GuardedControlStack = PBP.GuardedControlStack;
     if (isAArch64 && PBP.HasPauthABI)
-      handlePAuthABIOption(Args, CmdArgs, D);
+      handlePAuthABIOption(Args, CmdArgs);
   }
 
   CmdArgs.push_back(

>From 1d81b91d88f4f93dc6cf9bbec0c5f7fb851f89ab Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Fri, 5 Jul 2024 02:05:38 +0300
Subject: [PATCH 3/8] Enhance test

---
 clang/test/Driver/aarch64-ptrauth.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c
index dc63545a47a86..b8b370cc3e405 100644
--- a/clang/test/Driver/aarch64-ptrauth.c
+++ b/clang/test/Driver/aarch64-ptrauth.c
@@ -21,13 +21,7 @@
 // RUN:   -fno-ptrauth-calls -fno-ptrauth-returns -fno-ptrauth-auth-traps \
 // RUN:   -fno-ptrauth-vtable-pointer-address-discrimination -fno-ptrauth-vtable-pointer-type-discrimination \
 // RUN:   -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2
-// PAUTHABI2-NOT: "-fptrauth-intrinsics"
-// PAUTHABI2-NOT: "-fptrauth-calls"
-// PAUTHABI2-NOT: "-fptrauth-returns"
-// PAUTHABI2-NOT: "-fptrauth-auth-traps"
-// PAUTHABI2-NOT: "-fptrauth-vtable-pointer-address-discrimination"
-// PAUTHABI2-NOT: "-fptrauth-vtable-pointer-type-discrimination"
-// PAUTHABI2-NOT: "-fptrauth-init-fini"
+// PAUTHABI2-NOT: "-fptrauth-
 
 // RUN: not %clang -### -c --target=x86_64 -fptrauth-intrinsics -fptrauth-calls -fptrauth-returns -fptrauth-auth-traps \
 // RUN:   -fptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-type-discrimination \

>From 3067c934a957eed21cb3ae73404675242425e5cb Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Fri, 5 Jul 2024 15:48:19 +0300
Subject: [PATCH 4/8] Allow `pauthabi+bti` and disallow other combinations with
 `pauthabi`

---
 clang/test/Driver/aarch64-ptrauth.c             | 10 ++++++++++
 llvm/lib/TargetParser/ARMTargetParserCommon.cpp | 12 ++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c
index b8b370cc3e405..976c74b9b0ba2 100644
--- a/clang/test/Driver/aarch64-ptrauth.c
+++ b/clang/test/Driver/aarch64-ptrauth.c
@@ -37,3 +37,13 @@
 // RUN: not %clang -### -c --target=x86_64 -mbranch-protection=pauthabi %s 2>&1 | \
 // RUN:   FileCheck %s --check-prefix=ERR2
 // ERR2: error: unsupported option '-mbranch-protection=' for target 'x86_64'
+
+// RUN: not %clang -### -c --target=aarch64 -mbranch-protection=pauthabi+pac-ret %s 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=ERR3
+// ERR3: error: unsupported argument 'pauthabi+pac-ret' to option '-mbranch-protection='
+
+// RUN: not %clang -### -c --target=aarch64 -mbranch-protection=gcs+pauthabi %s 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=ERR4
+// ERR4: error: unsupported argument 'pauthabi+gcs' to option '-mbranch-protection='
+
+// RUN: %clang -### -c --target=aarch64 -mbranch-protection=bti+pauthabi %s 2>&1
diff --git a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
index 0b1e6d3356f68..219842f6469a3 100644
--- a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
+++ b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
@@ -190,5 +190,17 @@ bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
     return false;
   }
 
+  if (!PBP.HasPauthABI)
+    return true;
+
+  if (PBP.Scope != "none") {
+    Err = "pauthabi+pac-ret";
+    return false;
+  }
+  if (PBP.GuardedControlStack) {
+    Err = "pauthabi+gcs";
+    return false;
+  }
+
   return true;
 }

>From 501a43b7486058a912893f2460fcf0500816cb35 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Fri, 5 Jul 2024 15:59:05 +0300
Subject: [PATCH 5/8] Update comment

---
 llvm/lib/TargetParser/ARMTargetParserCommon.cpp | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
index 219842f6469a3..dcaa96be72303 100644
--- a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
+++ b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
@@ -134,10 +134,11 @@ ARM::EndianKind ARM::parseArchEndian(StringRef Arch) {
 }
 
 // Parse a branch protection specification, which has the form
-//   standard | none | [bti,pac-ret[+b-key,+leaf,+pc]*]
-// Returns true on success, with individual elements of the specification
-// returned in `PBP`. Returns false in error, with `Err` containing
-// an erroneous part of the spec.
+//   standard | none | [bti,pac-ret[+b-key,+leaf,+pc]*,gcs,pauthabi]
+// Note: pauthabi is allowed with bti and disallowed with pac-ret and gcs.
+// Returns true on success, with individual elements of the
+// specification returned in `PBP`. Returns false in error, with `Err`
+// containing an erroneous part of the spec.
 bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
                                 StringRef &Err, bool EnablePAuthLR) {
   PBP = {"none", "a_key", false, false, false, false};

>From f06bc88c4e6d77cf7a49679ceff549720c06567e Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Fri, 12 Jul 2024 18:23:05 +0300
Subject: [PATCH 6/8] [PAC][Driver] Support `pauthtest` ABI for AArch64 Linux
 triples

When `pauthtest` is either passed as environment part of AArch64 Linux triple
or passed via `-mabi=`, enable the following ptrauth flags:

- `intrinsics`;
- `calls`;
- `returns`;
- `auth-traps`;
- `vtable-pointer-address-discrimination`;
- `vtable-pointer-type-discrimination`;
- `init-fini`.

Some related stuff is still subject to change, and the ABI itself might
be changed, so end users are not expected to use this and the ABI name
has 'test' suffix.

If `-mabi=pauthtest` option is used, it's normalized to effective triple.

When the environment part of the effective triple is `pauthtest`, try
to use `aarch64-linux-pauthtest` as multilib directory.

The following is not supported:
- combination of `pauthtest` ABI with any branch protection scheme except BTI;
- explicit set of environment part of the triple to a value different
  from `pauthtest` in combination with `-mabi=pauthtest`;
- usage on non-Linux OS.
---
 clang/lib/Basic/Targets/AArch64.cpp           |  9 ++-
 clang/lib/Basic/Targets/ARM.cpp               |  3 +
 clang/lib/CodeGen/CodeGenModule.cpp           |  2 +
 clang/lib/CodeGen/TargetInfo.h                |  1 +
 clang/lib/Driver/ToolChain.cpp                |  5 +-
 clang/lib/Driver/ToolChains/Arch/AArch64.cpp  | 21 ++++++
 clang/lib/Driver/ToolChains/Arch/AArch64.h    |  3 +
 clang/lib/Driver/ToolChains/Clang.cpp         | 31 +++++---
 clang/lib/Driver/ToolChains/Linux.cpp         |  3 +
 .../usr/include/aarch64-linux-gnu/.keep       |  0
 .../usr/include/aarch64-linux-pauthtest/.keep |  0
 clang/test/Driver/aarch64-multilib-pauthabi.c |  4 ++
 clang/test/Driver/aarch64-ptrauth.c           | 71 +++++++++++++++----
 .../llvm/TargetParser/ARMTargetParserCommon.h |  1 -
 llvm/include/llvm/TargetParser/Triple.h       |  6 +-
 llvm/lib/TargetParser/ARMTargetParser.cpp     |  2 +
 .../TargetParser/ARMTargetParserCommon.cpp    | 27 ++-----
 llvm/lib/TargetParser/Triple.cpp              |  3 +
 llvm/unittests/TargetParser/TripleTest.cpp    |  6 ++
 19 files changed, 146 insertions(+), 52 deletions(-)
 create mode 100644 clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-gnu/.keep
 create mode 100644 clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-pauthtest/.keep
 create mode 100644 clang/test/Driver/aarch64-multilib-pauthabi.c

diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index 2692ddec26ff4..04ba0ef981a69 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -204,7 +204,8 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
 StringRef AArch64TargetInfo::getABI() const { return ABI; }
 
 bool AArch64TargetInfo::setABI(const std::string &Name) {
-  if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs")
+  if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs" &&
+      Name != "pauthtest")
     return false;
 
   ABI = Name;
@@ -218,6 +219,12 @@ bool AArch64TargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
     Diags.Report(diag::err_target_unsupported_abi_with_fpu) << ABI;
     return false;
   }
+  if (getTriple().getEnvironment() == llvm::Triple::PAuthTest &&
+      getTriple().getOS() != llvm::Triple::Linux) {
+    Diags.Report(diag::err_target_unsupported_abi_for_triple)
+        << getTriple().getEnvironmentName() << getTriple().getTriple();
+    return false;
+  }
   return true;
 }
 
diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp
index 7423626d7c3cb..340de5f0190d5 100644
--- a/clang/lib/Basic/Targets/ARM.cpp
+++ b/clang/lib/Basic/Targets/ARM.cpp
@@ -324,6 +324,9 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
     case llvm::Triple::GNU:
       setABI("apcs-gnu");
       break;
+    case llvm::Triple::PAuthTest:
+      setABI("pauthtest");
+      break;
     default:
       if (IsNetBSD)
         setABI("apcs-gnu");
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 08cfa694cfb81..206156f2b1682 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -147,6 +147,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) {
       return createWindowsAArch64TargetCodeGenInfo(CGM, AArch64ABIKind::Win64);
     else if (Target.getABI() == "aapcs-soft")
       Kind = AArch64ABIKind::AAPCSSoft;
+    else if (Target.getABI() == "pauthtest")
+      Kind = AArch64ABIKind::PAuthTest;
 
     return createAArch64TargetCodeGenInfo(CGM, Kind);
   }
diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h
index 0925609cc74aa..2f2138582ba1e 100644
--- a/clang/lib/CodeGen/TargetInfo.h
+++ b/clang/lib/CodeGen/TargetInfo.h
@@ -437,6 +437,7 @@ enum class AArch64ABIKind {
   DarwinPCS,
   Win64,
   AAPCSSoft,
+  PAuthTest,
 };
 
 std::unique_ptr<TargetCodeGenInfo>
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 85ae4d2a26fee..20a555afb8092 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -1031,11 +1031,12 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
   }
   case llvm::Triple::aarch64: {
     llvm::Triple Triple = getTriple();
+    tools::aarch64::setPAuthABIInTriple(getDriver(), Args, Triple);
     if (!Triple.isOSBinFormatMachO())
-      return getTripleString();
+      return Triple.getTriple();
 
     if (Triple.isArm64e())
-      return getTripleString();
+      return Triple.getTriple();
 
     // FIXME: older versions of ld64 expect the "arm64" component in the actual
     // triple string and query it to determine whether an LTO file can be
diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
index 5fbf38cdda12b..f083e40df1314 100644
--- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -449,3 +449,24 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
   if (Args.getLastArg(options::OPT_mno_bti_at_return_twice))
     Features.push_back("+no-bti-at-return-twice");
 }
+
+void aarch64::setPAuthABIInTriple(const Driver &D, const ArgList &Args,
+                                  llvm::Triple &Triple) {
+  Arg *ABIArg = Args.getLastArg(options::OPT_mabi_EQ);
+  bool HasPAuthABI =
+      ABIArg ? (StringRef(ABIArg->getValue()) == "pauthtest") : false;
+
+  switch (Triple.getEnvironment()) {
+  case llvm::Triple::UnknownEnvironment:
+    if (HasPAuthABI)
+      Triple.setEnvironment(llvm::Triple::PAuthTest);
+    break;
+  case llvm::Triple::PAuthTest:
+    break;
+  default:
+    if (HasPAuthABI)
+      D.Diag(diag::err_drv_unsupported_opt_for_target)
+          << ABIArg->getAsString(Args) << Triple.getTriple();
+    break;
+  }
+}
diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.h b/clang/lib/Driver/ToolChains/Arch/AArch64.h
index d47c402d4a42d..6d071167bd392 100644
--- a/clang/lib/Driver/ToolChains/Arch/AArch64.h
+++ b/clang/lib/Driver/ToolChains/Arch/AArch64.h
@@ -28,6 +28,9 @@ void getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple,
 std::string getAArch64TargetCPU(const llvm::opt::ArgList &Args,
                                 const llvm::Triple &Triple, llvm::opt::Arg *&A);
 
+void setPAuthABIInTriple(const Driver &D, const llvm::opt::ArgList &Args,
+                         llvm::Triple &triple);
+
 } // end namespace aarch64
 } // end namespace target
 } // end namespace driver
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 636413fae3d1d..0c1efdc59dc5f 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1487,8 +1487,7 @@ void AddUnalignedAccessWarning(ArgStringList &CmdArgs) {
 // Each combination of options here forms a signing schema, and in most cases
 // each signing schema is its own incompatible ABI. The default values of the
 // options represent the default signing schema.
-static void handlePAuthABIOption(const ArgList &DriverArgs,
-                                 ArgStringList &CC1Args) {
+static void handlePAuthABI(const ArgList &DriverArgs, ArgStringList &CC1Args) {
   if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics,
                          options::OPT_fno_ptrauth_intrinsics))
     CC1Args.push_back("-fptrauth-intrinsics");
@@ -1573,30 +1572,37 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
     if (!isAArch64 && PBP.Key == "b_key")
       D.Diag(diag::warn_unsupported_branch_protection)
           << "b-key" << A->getAsString(Args);
-    if (!isAArch64 && PBP.HasPauthABI)
-      D.Diag(diag::warn_unsupported_branch_protection)
-          << "pauthabi" << A->getAsString(Args);
     Scope = PBP.Scope;
     Key = PBP.Key;
     BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
     IndirectBranches = PBP.BranchTargetEnforcement;
     GuardedControlStack = PBP.GuardedControlStack;
-    if (isAArch64 && PBP.HasPauthABI)
-      handlePAuthABIOption(Args, CmdArgs);
   }
 
   CmdArgs.push_back(
       Args.MakeArgString(Twine("-msign-return-address=") + Scope));
-  if (Scope != "none")
+  if (Scope != "none") {
+    if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
+      D.Diag(diag::err_drv_unsupported_opt_for_target)
+          << A->getAsString(Args) << Triple.getTriple();
     CmdArgs.push_back(
         Args.MakeArgString(Twine("-msign-return-address-key=") + Key));
-  if (BranchProtectionPAuthLR)
+  }
+  if (BranchProtectionPAuthLR) {
+    if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
+      D.Diag(diag::err_drv_unsupported_opt_for_target)
+          << A->getAsString(Args) << Triple.getTriple();
     CmdArgs.push_back(
         Args.MakeArgString(Twine("-mbranch-protection-pauth-lr")));
+  }
   if (IndirectBranches)
     CmdArgs.push_back("-mbranch-target-enforce");
-  if (GuardedControlStack)
+  if (GuardedControlStack) {
+    if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
+      D.Diag(diag::err_drv_unsupported_opt_for_target)
+          << A->getAsString(Args) << Triple.getTriple();
     CmdArgs.push_back("-mguarded-control-stack");
+  }
 }
 
 void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
@@ -1740,6 +1746,8 @@ void RenderAArch64ABI(const llvm::Triple &Triple, const ArgList &Args,
     ABIName = A->getValue();
   else if (Triple.isOSDarwin())
     ABIName = "darwinpcs";
+  else if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
+    ABIName = "pauthtest";
   else
     ABIName = "aapcs";
 
@@ -1776,6 +1784,9 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
   // Enable/disable return address signing and indirect branch targets.
   CollectARMPACBTIOptions(getToolChain(), Args, CmdArgs, true /*isAArch64*/);
 
+  if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
+    handlePAuthABI(Args, CmdArgs);
+
   // Handle -msve_vector_bits=<bits>
   if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) {
     StringRef Val = A->getValue();
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index 98a878e1d764d..2265138edbffb 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -86,6 +86,9 @@ std::string Linux::getMultiarchTriple(const Driver &D,
   case llvm::Triple::aarch64:
     if (IsAndroid)
       return "aarch64-linux-android";
+    if (hasEffectiveTriple() &&
+        getEffectiveTriple().getEnvironment() == llvm::Triple::PAuthTest)
+      return "aarch64-linux-pauthtest";
     return "aarch64-linux-gnu";
   case llvm::Triple::aarch64_be:
     return "aarch64_be-linux-gnu";
diff --git a/clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-gnu/.keep b/clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-gnu/.keep
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-pauthtest/.keep b/clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-pauthtest/.keep
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/aarch64-multilib-pauthabi.c b/clang/test/Driver/aarch64-multilib-pauthabi.c
new file mode 100644
index 0000000000000..3046cb856e83c
--- /dev/null
+++ b/clang/test/Driver/aarch64-multilib-pauthabi.c
@@ -0,0 +1,4 @@
+// RUN: %clang --target=aarch64-linux-pauthtest       --sysroot=%S/Inputs/multilib_aarch64_linux_tree -### -c %s 2>&1 | FileCheck %s
+// RUN: %clang --target=aarch64-linux -mabi=pauthtest --sysroot=%S/Inputs/multilib_aarch64_linux_tree -### -c %s 2>&1 | FileCheck %s
+
+// CHECK: "-internal-externc-isystem" "{{.*}}/usr/include/aarch64-linux-pauthtest"
diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c
index 976c74b9b0ba2..d13930e8f4b37 100644
--- a/clang/test/Driver/aarch64-ptrauth.c
+++ b/clang/test/Driver/aarch64-ptrauth.c
@@ -1,5 +1,7 @@
+// REQUIRES: aarch64-registered-target
+
 // RUN: %clang -### -c --target=aarch64 %s 2>&1 | FileCheck %s --check-prefix NONE
-// NONE: "-cc1"
+// NONE:     "-cc1"
 // NONE-NOT: "-fptrauth-
 
 // RUN: %clang -### -c --target=aarch64 \
@@ -13,14 +15,21 @@
 // RUN:   %s 2>&1 | FileCheck %s --check-prefix=ALL
 // ALL: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini"
 
-// RUN: %clang -### -c --target=aarch64 -mbranch-protection=pauthabi %s 2>&1 | \
-// RUN:   FileCheck %s --check-prefix=PAUTHABI1
-// PAUTHABI1: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini"
+// RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI1
+// RUN: %clang -### -c --target=aarch64-linux-pauthtest %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI1
+// PAUTHABI1:      "-cc1"{{.*}} "-triple" "aarch64-unknown-linux-pauthtest"
+// PAUTHABI1-SAME: "-target-abi" "pauthtest"
+// PAUTHABI1-SAME: "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini"
 
-// RUN: %clang -### -c --target=aarch64 -mbranch-protection=pauthabi -fno-ptrauth-intrinsics \
+// RUN: %clang -### -c --target=aarch64 -mabi=pauthtest -fno-ptrauth-intrinsics \
 // RUN:   -fno-ptrauth-calls -fno-ptrauth-returns -fno-ptrauth-auth-traps \
 // RUN:   -fno-ptrauth-vtable-pointer-address-discrimination -fno-ptrauth-vtable-pointer-type-discrimination \
 // RUN:   -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2
+// RUN: %clang -### -c --target=aarch64-pauthtest -fno-ptrauth-intrinsics \
+// RUN:   -fno-ptrauth-calls -fno-ptrauth-returns -fno-ptrauth-auth-traps \
+// RUN:   -fno-ptrauth-vtable-pointer-address-discrimination -fno-ptrauth-vtable-pointer-type-discrimination \
+// RUN:   -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2
+// PAUTHABI2:     "-cc1"
 // PAUTHABI2-NOT: "-fptrauth-
 
 // RUN: not %clang -### -c --target=x86_64 -fptrauth-intrinsics -fptrauth-calls -fptrauth-returns -fptrauth-auth-traps \
@@ -34,16 +43,50 @@
 // ERR1-NEXT: error: unsupported option '-fptrauth-vtable-pointer-type-discrimination' for target '{{.*}}'
 // ERR1-NEXT: error: unsupported option '-fptrauth-init-fini' for target '{{.*}}'
 
-// RUN: not %clang -### -c --target=x86_64 -mbranch-protection=pauthabi %s 2>&1 | \
-// RUN:   FileCheck %s --check-prefix=ERR2
-// ERR2: error: unsupported option '-mbranch-protection=' for target 'x86_64'
+//// Only support PAuth ABI for Linux as for now.
+// RUN: not %clang -c --target=aarch64-unknown -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=ERR2
+// RUN: not %clang -c --target=aarch64-unknown-pauthtest       %s 2>&1 | FileCheck %s --check-prefix=ERR2
+// ERR2: error: ABI 'pauthtest' is not supported for 'aarch64-unknown-unknown-pauthtest'
 
-// RUN: not %clang -### -c --target=aarch64 -mbranch-protection=pauthabi+pac-ret %s 2>&1 | \
-// RUN:   FileCheck %s --check-prefix=ERR3
-// ERR3: error: unsupported argument 'pauthabi+pac-ret' to option '-mbranch-protection='
+//// PAuth ABI is encoded as environment part of the triple, so don't allow to explicitly set other environments.
+// RUN: not %clang -c --target=aarch64-linux-gnu -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=ERR3
+// ERR3: error: unsupported option '-mabi=pauthtest' for target 'aarch64-unknown-linux-gnu'
+// RUN: %clang -c --target=aarch64-linux-pauthtest -mabi=pauthtest %s
 
-// RUN: not %clang -### -c --target=aarch64 -mbranch-protection=gcs+pauthabi %s 2>&1 | \
+//// The only branch protection option compatible with PAuthABI is BTI.
+// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=pac-ret %s 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=ERR4
+// RUN: not %clang -### -c --target=aarch64-linux-pauthtest       -mbranch-protection=pac-ret %s 2>&1 | \
 // RUN:   FileCheck %s --check-prefix=ERR4
-// ERR4: error: unsupported argument 'pauthabi+gcs' to option '-mbranch-protection='
+// ERR4: error: unsupported option '-mbranch-protection=pac-ret' for target 'aarch64-unknown-linux-pauthtest'
+
+// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=gcs %s 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=ERR5
+// RUN: not %clang -### -c --target=aarch64-linux-pauthtest       -mbranch-protection=gcs %s 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=ERR5
+// ERR5: error: unsupported option '-mbranch-protection=gcs' for target 'aarch64-unknown-linux-pauthtest'
+
+// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=standard %s 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=ERR6
+// RUN: not %clang -### -c --target=aarch64-linux-pauthtest       -mbranch-protection=standard %s 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=ERR6
+// ERR6: error: unsupported option '-mbranch-protection=standard' for target 'aarch64-unknown-linux-pauthtest'
+
+// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -msign-return-address=all %s 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=ERR7
+// RUN: not %clang -### -c --target=aarch64-linux-pauthtest       -msign-return-address=all %s 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=ERR7
+// ERR7: error: unsupported option '-msign-return-address=all' for target 'aarch64-unknown-linux-pauthtest'
+
+// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -msign-return-address=non-leaf %s 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=ERR8
+// RUN: not %clang -### -c --target=aarch64-linux-pauthtest       -msign-return-address=non-leaf %s 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=ERR8
+// ERR8: error: unsupported option '-msign-return-address=non-leaf' for target 'aarch64-unknown-linux-pauthtest'
 
-// RUN: %clang -### -c --target=aarch64 -mbranch-protection=bti+pauthabi %s 2>&1
+// RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest -msign-return-address=none %s
+// RUN: %clang -### -c --target=aarch64-linux-pauthtest       -msign-return-address=none %s
+// RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=bti %s
+// RUN: %clang -### -c --target=aarch64-linux-pauthtest       -mbranch-protection=bti %s
+// RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=none %s
+// RUN: %clang -### -c --target=aarch64-linux-pauthtest       -mbranch-protection=none %s
diff --git a/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h b/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h
index ca634ed969d84..f6115718e9f5f 100644
--- a/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h
+++ b/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h
@@ -43,7 +43,6 @@ struct ParsedBranchProtection {
   bool BranchTargetEnforcement;
   bool BranchProtectionPAuthLR;
   bool GuardedControlStack;
-  bool HasPauthABI;
 };
 
 bool parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index cb2be3bbd29f7..e504128714c55 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -266,7 +266,7 @@ class Triple {
     Cygnus,
     CoreCLR,
     Simulator, // Simulator variants of other systems, e.g., Apple's iOS
-    MacABI, // Mac Catalyst variant of Apple's iOS deployment target.
+    MacABI,    // Mac Catalyst variant of Apple's iOS deployment target.
 
     // Shader Stages
     // The order of these values matters, and must be kept in sync with the
@@ -290,7 +290,9 @@ class Triple {
     OpenCL,
     OpenHOS,
 
-    LastEnvironmentType = OpenHOS
+    PAuthTest,
+
+    LastEnvironmentType = PAuthTest
   };
   enum ObjectFormatType {
     UnknownObjectFormat,
diff --git a/llvm/lib/TargetParser/ARMTargetParser.cpp b/llvm/lib/TargetParser/ARMTargetParser.cpp
index 9d9917d86a368..1d31af587745f 100644
--- a/llvm/lib/TargetParser/ARMTargetParser.cpp
+++ b/llvm/lib/TargetParser/ARMTargetParser.cpp
@@ -562,6 +562,8 @@ StringRef ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) {
   case Triple::EABIHF:
   case Triple::EABI:
     return "aapcs";
+  case Triple::PAuthTest:
+    return "pauthtest";
   default:
     if (TT.isOSNetBSD())
       return "apcs-gnu";
diff --git a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
index dcaa96be72303..d6ce6581bb1a9 100644
--- a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
+++ b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
@@ -134,14 +134,13 @@ ARM::EndianKind ARM::parseArchEndian(StringRef Arch) {
 }
 
 // Parse a branch protection specification, which has the form
-//   standard | none | [bti,pac-ret[+b-key,+leaf,+pc]*,gcs,pauthabi]
-// Note: pauthabi is allowed with bti and disallowed with pac-ret and gcs.
-// Returns true on success, with individual elements of the
-// specification returned in `PBP`. Returns false in error, with `Err`
-// containing an erroneous part of the spec.
+//   standard | none | [bti,pac-ret[+b-key,+leaf,+pc]*]
+// Returns true on success, with individual elements of the specification
+// returned in `PBP`. Returns false in error, with `Err` containing
+// an erroneous part of the spec.
 bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
                                 StringRef &Err, bool EnablePAuthLR) {
-  PBP = {"none", "a_key", false, false, false, false};
+  PBP = {"none", "a_key", false, false, false};
   if (Spec == "none")
     return true; // defaults are ok
 
@@ -161,10 +160,6 @@ bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
       PBP.BranchTargetEnforcement = true;
       continue;
     }
-    if (Opt == "pauthabi") {
-      PBP.HasPauthABI = true;
-      continue;
-    }
     if (Opt == "pac-ret") {
       PBP.Scope = "non-leaf";
       for (; I + 1 != E; ++I) {
@@ -191,17 +186,5 @@ bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
     return false;
   }
 
-  if (!PBP.HasPauthABI)
-    return true;
-
-  if (PBP.Scope != "none") {
-    Err = "pauthabi+pac-ret";
-    return false;
-  }
-  if (PBP.GuardedControlStack) {
-    Err = "pauthabi+gcs";
-    return false;
-  }
-
   return true;
 }
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index a54a02ac61d68..55911a7d71ac7 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -347,6 +347,8 @@ StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) {
   case OpenCL:
     return "opencl";
   case OpenHOS: return "ohos";
+  case PAuthTest:
+    return "pauthtest";
   }
 
   llvm_unreachable("Invalid EnvironmentType!");
@@ -719,6 +721,7 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
       .StartsWith("amplification", Triple::Amplification)
       .StartsWith("opencl", Triple::OpenCL)
       .StartsWith("ohos", Triple::OpenHOS)
+      .StartsWith("pauthtest", Triple::PAuthTest)
       .Default(Triple::UnknownEnvironment);
 }
 
diff --git a/llvm/unittests/TargetParser/TripleTest.cpp b/llvm/unittests/TargetParser/TripleTest.cpp
index f93dc3671197a..0aecfc64da208 100644
--- a/llvm/unittests/TargetParser/TripleTest.cpp
+++ b/llvm/unittests/TargetParser/TripleTest.cpp
@@ -1169,6 +1169,12 @@ TEST(TripleTest, ParsedIDs) {
   EXPECT_EQ(Triple::Serenity, T.getOS());
   EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
 
+  T = Triple("aarch64-unknown-linux-pauthtest");
+  EXPECT_EQ(Triple::aarch64, T.getArch());
+  EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+  EXPECT_EQ(Triple::Linux, T.getOS());
+  EXPECT_EQ(Triple::PAuthTest, T.getEnvironment());
+
   T = Triple("huh");
   EXPECT_EQ(Triple::UnknownArch, T.getArch());
 }

>From eae6f7c54145b19148a0ca7de639b4400db8fae9 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Tue, 16 Jul 2024 22:08:22 +0300
Subject: [PATCH 7/8] Address review comments

---
 clang/lib/Basic/Targets/ARM.cpp           | 3 ---
 llvm/lib/TargetParser/ARMTargetParser.cpp | 2 --
 2 files changed, 5 deletions(-)

diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp
index 340de5f0190d5..7423626d7c3cb 100644
--- a/clang/lib/Basic/Targets/ARM.cpp
+++ b/clang/lib/Basic/Targets/ARM.cpp
@@ -324,9 +324,6 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
     case llvm::Triple::GNU:
       setABI("apcs-gnu");
       break;
-    case llvm::Triple::PAuthTest:
-      setABI("pauthtest");
-      break;
     default:
       if (IsNetBSD)
         setABI("apcs-gnu");
diff --git a/llvm/lib/TargetParser/ARMTargetParser.cpp b/llvm/lib/TargetParser/ARMTargetParser.cpp
index 1d31af587745f..9d9917d86a368 100644
--- a/llvm/lib/TargetParser/ARMTargetParser.cpp
+++ b/llvm/lib/TargetParser/ARMTargetParser.cpp
@@ -562,8 +562,6 @@ StringRef ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) {
   case Triple::EABIHF:
   case Triple::EABI:
     return "aapcs";
-  case Triple::PAuthTest:
-    return "pauthtest";
   default:
     if (TT.isOSNetBSD())
       return "apcs-gnu";

>From 4f3da9e51338aec21b8bfe8dd08598507edcea38 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Thu, 18 Jul 2024 11:49:14 +0300
Subject: [PATCH 8/8] Add a comment regarding GCS + PAuthABI

---
 clang/lib/Driver/ToolChains/Clang.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index cd46353a2b551..21a460432a386 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1597,6 +1597,8 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
   }
   if (IndirectBranches)
     CmdArgs.push_back("-mbranch-target-enforce");
+  // GCS is currently untested with PAuthABI, but enabling this could be allowed
+  // in future after testing with a suitable system.
   if (GuardedControlStack) {
     if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
       D.Diag(diag::err_drv_unsupported_opt_for_target)



More information about the cfe-commits mailing list