diff --git a/gcc/config/aarch64/aarch64-opts.h b/gcc/config/aarch64/aarch64-opts.h
index c550a74..41c14b3 100644
--- a/gcc/config/aarch64/aarch64-opts.h
+++ b/gcc/config/aarch64/aarch64-opts.h
@@ -73,4 +73,30 @@ enum aarch64_code_model {
   AARCH64_CMODEL_LARGE
 };
 
+/* AArch64 pointer authentication key indexes.  "key_array" in
+   aarch64_output_sign_auth_reg depends on the order of this enum.  */
+enum aarch64_pauth_key_index
+{
+  /* A key for instruction pointer.  */
+  AARCH64_PAUTH_IKEY_A = 0,
+  /* B key for instruction pointer.  */
+  AARCH64_PAUTH_IKEY_B,
+  /* A key for data pointer.  */
+  AARCH64_PAUTH_DKEY_A,
+  /* B key for data pointer.  */
+  AARCH64_PAUTH_DKEY_B,
+  /* A key for general pointer.  */
+  AARCH64_PAUTH_GKEY_A
+};
+
+/* Function types -msign-return-address should sign.  */
+enum aarch64_function_type {
+  /* Don't sign any function.  */
+  AARCH64_FUNCTION_NONE,
+  /* Non-leaf functions.  */
+  AARCH64_FUNCTION_NON_LEAF,
+  /* All functions.  */
+  AARCH64_FUNCTION_ALL
+};
+
 #endif
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 3cdd69b..fa6d16b 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -329,6 +329,7 @@ rtx aarch64_reverse_mask (enum machine_mode);
 bool aarch64_offset_7bit_signed_scaled_p (machine_mode, HOST_WIDE_INT);
 char *aarch64_output_scalar_simd_mov_immediate (rtx, machine_mode);
 char *aarch64_output_simd_mov_immediate (rtx, machine_mode, unsigned);
+const char *aarch64_output_sign_auth_reg (rtx *, bool, bool);
 bool aarch64_pad_arg_upward (machine_mode, const_tree);
 bool aarch64_pad_reg_upward (machine_mode, const_tree, bool);
 bool aarch64_regno_ok_for_base_p (int, bool);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 3e663eb..8401fa4 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -3204,6 +3204,13 @@ aarch64_expand_prologue (void)
   unsigned reg2 = cfun->machine->frame.wb_candidate2;
   rtx_insn *insn;
 
+  if (AARCH64_ENABLE_RETURN_ADDRESS_SIGN)
+    emit_insn (gen_sign_reg (gen_rtx_REG (Pmode, LR_REGNUM),
+			     gen_rtx_REG (Pmode, LR_REGNUM),
+			     stack_pointer_rtx,
+			     GEN_INT (aarch64_pauth_key),
+			     const0_rtx));
+
   if (flag_stack_usage_info)
     current_function_static_stack_size = frame_size;
 
@@ -3340,6 +3347,20 @@ aarch64_expand_epilogue (bool for_sibcall)
       RTX_FRAME_RELATED_P (insn) = 1;
     }
 
+  /* sibcall won't generate normally return, therefore we need to authenticate
+     at here.  TARGET_PAUTH will allow GCC to use combined authentication
+     instruction which we prefer, eh_return path can't do combined
+     authentication, as the following stack adjustment will update CFA to
+     handler's CFA while we want to use the CFA of the function which calls
+     __builtin_eh_return.  */
+  if (AARCH64_ENABLE_RETURN_ADDRESS_SIGN
+      && (for_sibcall || !TARGET_PAUTH || crtl->calls_eh_return))
+    emit_insn (gen_auth_reg (gen_rtx_REG (Pmode, LR_REGNUM),
+			     gen_rtx_REG (Pmode, LR_REGNUM),
+			     stack_pointer_rtx,
+			     GEN_INT (aarch64_pauth_key),
+			     const0_rtx));
+
   /* Stack adjustment for exception handler.  */
   if (crtl->calls_eh_return)
     {
@@ -5434,6 +5455,74 @@ aarch64_output_casesi (rtx *operands)
   return "";
 }
 
+/* Output ARMv8.3-A pointer sign instructions when SIGN_P be TRUE or
+   authentication instructions when it's FALSE.  X1716_P is TRUE if this
+   function is called from fixed register patterns, i.e sign_reg1716 or
+   auth_reg1716.  */
+
+const char*
+aarch64_output_sign_auth_reg (rtx *operands, bool sign_p, bool x1716_p)
+{
+  char buf[64];
+  const char *action = sign_p ? "pac" : "aut";
+  /* Assembler suffix for key, this array should be synced with
+     "enum aarch64_pauth_key_index" in aarch64-opts.h.  */
+  const char key_array[5] = {'a', 'b', 'a', 'b', 'a'};
+  char key_char
+    = key_array[x1716_p ? INTVAL (operands[0]) : INTVAL (operands[3])];
+  char type
+    = (x1716_p ? INTVAL (operands[1]) : INTVAL (operands[4])) ? 'd' : 'i';
+  unsigned FM = ((sign_p ? 0 : 1) << 2 /* F bit.  */
+		 | ((key_char  == 'a' ? 0 : 1) << 1)); /* M bit.  */
+
+  if (x1716_p
+      || (REGNO (operands[0]) == R17_REGNUM
+	  && REG_P (operands[2]) && REGNO (operands[2]) == R16_REGNUM))
+    {
+      /* PAC*1716/AUT*1716 only support code pointer.  */
+      gcc_assert (type == 'i');
+      unsigned CRm = 0x1;
+      unsigned FMS = (FM /* F and M bits.  */
+		      | 0); /* S bit.  */
+      snprintf (buf, sizeof (buf), "hint\t%d %s%s%c1716", (CRm << 3) | FMS,
+		ASM_COMMENT_START, action, key_char);
+    }
+  else if (REGNO (operands[0]) == LR_REGNUM
+	   && REG_P (operands[2]) && REGNO (operands[2]) == SP_REGNUM)
+    {
+      /* PAC*SP/AUT*SP only support code pointer.  */
+      gcc_assert (type == 'i');
+      unsigned CRm = 0x3;
+      unsigned FMS = (FM /* F and M bits.  */
+		      | 1); /* S bit.  */
+      snprintf (buf, sizeof (buf), "hint\t%d %s%si%csp", (CRm << 3) | FMS,
+		ASM_COMMENT_START, action, key_char);
+    }
+  else if (REGNO (operands[0]) == LR_REGNUM && operands[2] == const0_rtx)
+    {
+      /* PAC*Z/AUT*Z only support code pointer.  */
+      gcc_assert (type == 'i');
+      unsigned CRm = 0x3;
+      unsigned FMS = (FM /* F and M bits.  */
+		      | 0); /* S bit.  */
+      snprintf (buf, sizeof (buf), "hint\t%d %s%si%cz", (CRm << 3) | FMS,
+		ASM_COMMENT_START, action, key_char);
+    }
+  else if (operands[2] == const0_rtx)
+    {
+      /* General format PAC* Xd, Xn/AUT* Xd, Xn.  */
+      snprintf (buf, sizeof (buf), "%s%cz%c %%0", action, type, key_char);
+    }
+  else
+    {
+      /* General format PAC*Z* Xd, Xn/AUT*Z* Xd, Xn.  */
+      snprintf (buf, sizeof (buf), "%s%c%c %%0, %%2", action, type, key_char);
+    }
+
+  output_asm_insn (buf, operands);
+
+  return "";
+}
 
 /* Return size in bits of an arithmetic operand which is shifted/scaled and
    masked such that it is suitable for a UXTB, UXTH, or UXTW extend
@@ -8466,6 +8555,9 @@ aarch64_override_options (void)
     error ("Assembler does not support -mabi=ilp32");
 #endif
 
+  if (aarch64_ra_sign_scope != AARCH64_FUNCTION_NONE && TARGET_ILP32)
+    error ("Return address signing is only supported on LP64");
+
   /* Make sure we properly set up the explicit options.  */
   if ((aarch64_cpu_string && valid_cpu)
        || (aarch64_tune_string && valid_tune))
@@ -8849,6 +8941,10 @@ static const struct aarch64_attribute_info aarch64_attributes[] =
   { "cpu", aarch64_attr_custom, false, aarch64_handle_attr_cpu, OPT_mcpu_ },
   { "tune", aarch64_attr_custom, false, aarch64_handle_attr_tune,
      OPT_mtune_ },
+  { "sign-return-address", aarch64_attr_enum, false, NULL,
+     OPT_msign_return_address_ },
+  { "pauth-key", aarch64_attr_enum, false, NULL,
+    OPT_mpauth_key_ },
   { NULL, aarch64_attr_custom, false, NULL, OPT____ }
 };
 
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 70efbe9..4bfadb5 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -963,4 +963,11 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 extern tree aarch64_fp16_type_node;
 extern tree aarch64_fp16_ptr_type_node;
 
+/* Return address signing is enabled for AARCH64_FUNCTION_ALL, or for
+   AARCH64_FUNCTION_NON_LEAF.  */
+#define AARCH64_ENABLE_RETURN_ADDRESS_SIGN \
+	(aarch64_ra_sign_scope == AARCH64_FUNCTION_ALL \
+	     || (aarch64_ra_sign_scope == AARCH64_FUNCTION_NON_LEAF \
+		 && cfun->machine->frame.reg_offset[LR_REGNUM] >= 0))
+
 #endif /* GCC_AARCH64_H */
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index c95258b..754ea00 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -66,6 +66,8 @@
 )
 
 (define_c_enum "unspec" [
+    UNSPEC_AUTH_REG
+    UNSPEC_AUTH_REG1716
     UNSPEC_CASESI
     UNSPEC_CRC32B
     UNSPEC_CRC32CB
@@ -108,6 +110,8 @@
     UNSPEC_PRLG_STK
     UNSPEC_RBIT
     UNSPEC_SCVTF
+    UNSPEC_SIGN_REG
+    UNSPEC_SIGN_REG1716
     UNSPEC_SISD_NEG
     UNSPEC_SISD_SSHL
     UNSPEC_SISD_USHL
@@ -119,6 +123,8 @@
     UNSPEC_ST2_LANE
     UNSPEC_ST3_LANE
     UNSPEC_ST4_LANE
+    UNSPEC_STRIP_REG_SIGN
+    UNSPEC_STRIP_X30_SIGN
     UNSPEC_TLS
     UNSPEC_TLSDESC
     UNSPEC_TLSLE12
@@ -574,7 +580,21 @@
 (define_insn "*do_return"
   [(return)]
   ""
-  "ret"
+  {
+    if (AARCH64_ENABLE_RETURN_ADDRESS_SIGN
+	&& TARGET_PAUTH
+	&& !crtl->calls_eh_return)
+      {
+	if (aarch64_pauth_key == AARCH64_PAUTH_IKEY_A)
+	  return "retaa";
+	else if (aarch64_pauth_key == AARCH64_PAUTH_IKEY_B)
+	  return "retab";
+
+	gcc_unreachable ();
+      }
+
+    return "ret";
+  }
   [(set_attr "type" "branch")]
 )
 
@@ -5210,6 +5230,114 @@
   [(set_attr "length" "0")]
 )
 
+;; ARMv8.3-A pointer authentication support
+;; OPERANDS[0] - Result.
+;; OPERANDS[1] - The value we want to sign or authenticate.
+;; OPERANDS[2] - The salt used for signing or authentication.
+;; OPERANDS[3] - Key index. See aarch64_pauth_key_type in aarch64-opts.h.
+;; OPERANDS[4] - Pointer type.  0 for code, 1 for data.
+;;
+;; These patterns are available for all architectures.  For architectures
+;; without TARGET_PAUTH, they will become nop, this let the user write portable
+;; software which can get pointer authentication on new hardware while still
+;; runs OK on old hardware.
+
+(define_insn "sign_reg"
+  [(set (match_operand:DI 0 "register_operand" "=rk")
+	(unspec:DI [(match_operand:DI 1 "register_operand" "0")
+		    (match_operand:DI 2 "aarch64_reg_or_zero" "rkZ")
+		    (match_operand:DI 3 "aarch64_const0_const1" "i")
+		    (match_operand:DI 4 "aarch64_const0_const1" "i")]
+	 UNSPEC_SIGN_REG))]
+  ""
+  {
+    return aarch64_output_sign_auth_reg (operands, /* sign_p */true,
+					 /* x1716_p */false);
+  }
+)
+
+(define_insn "sign_reg1716"
+  [(set (reg:DI R17_REGNUM)
+	(unspec:DI [(reg:DI R17_REGNUM)
+		    (reg:DI R16_REGNUM)
+		    (match_operand:DI 0 "aarch64_const0_const1" "i")
+		    (match_operand:DI 1 "aarch64_const0_const1" "i")]
+	 UNSPEC_SIGN_REG1716))]
+  ""
+  {
+    return aarch64_output_sign_auth_reg (operands, /* sign_p */true,
+					 /* x1716_p */true);
+  }
+)
+
+(define_insn "auth_reg"
+  [(set (match_operand:DI 0 "register_operand" "=rk")
+	(unspec:DI [(match_operand:DI 1 "register_operand" "0")
+		    (match_operand:DI 2 "aarch64_reg_or_zero" "rkZ")
+		    (match_operand:DI 3 "aarch64_const0_const1" "i")
+		    (match_operand:DI 4 "aarch64_const0_const1" "i")]
+	 UNSPEC_AUTH_REG))]
+  ""
+  {
+    return aarch64_output_sign_auth_reg (operands, /* sign_p */false,
+					 /* x1716_p */false);
+  }
+)
+
+(define_insn "auth_reg1716"
+  [(set (reg:DI R17_REGNUM)
+	(unspec:DI [(reg:DI R17_REGNUM)
+		    (reg:DI R16_REGNUM)
+		    (match_operand:DI 0 "aarch64_const0_const1" "i")
+		    (match_operand:DI 1 "aarch64_const0_const1" "i")]
+	 UNSPEC_AUTH_REG1716))]
+  ""
+  {
+    return aarch64_output_sign_auth_reg (operands, /* sign_p */false,
+					 /* x1716_p */true);
+  }
+)
+
+(define_insn "strip_reg_sign"
+  [(set (match_operand:DI 0 "register_operand" "=rk")
+	(unspec:DI [(match_operand:DI 1 "register_operand" "0")
+		    (match_operand:DI 2 "immediate_operand" "i")]
+	 UNSPEC_STRIP_REG_SIGN))]
+  ""
+  {
+    if (REGNO (operands[1]) == LR_REGNUM)
+      {
+	if (INTVAL (operands[2]) == 0)
+	  return "xpaclri";
+	else
+	  /* LR can't be used for data strip.  */
+	  gcc_unreachable ();
+      }
+    else
+      {
+	if (INTVAL (operands[2]) == 0)
+	  return "xpaci\t%0";
+	else
+	  return "xpacd\t%0";
+      }
+  }
+)
+
+(define_insn "strip_lr_sign"
+  [(set (reg:DI R30_REGNUM)
+	(unspec:DI [(reg:DI R30_REGNUM)
+		    (match_operand:DI 0 "immediate_operand" "i")]
+	 UNSPEC_STRIP_X30_SIGN))]
+  ""
+  {
+    if (INTVAL (operands[0]) == 0)
+      return "xpaclri";
+    else
+      /* LR can't be used for data strip.  */
+      gcc_unreachable ();
+  }
+)
+
 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
 ;; all of memory.  This blocks insns from being moved across this point.
 
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index 82e9f5b..15fac36 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch64/aarch64.opt
@@ -149,6 +149,37 @@ mpc-relative-literal-loads
 Target Report Save Var(pcrelative_literal_loads) Init(2) Save
 PC relative literal loads.
 
+msign-return-address=
+Target RejectNegative Report Joined Enum(aarch64_ra_sign_scope_t) Var(aarch64_ra_sign_scope) Init(AARCH64_FUNCTION_NONE) Save
+Select return address signing scope
+
+Enum
+Name(aarch64_ra_sign_scope_t) Type(enum aarch64_function_type)
+Supported AArch64 return address signing scope (for use with -msign-return-address= option):
+
+EnumValue
+Enum(aarch64_ra_sign_scope_t) String(none) Value(AARCH64_FUNCTION_NONE)
+
+EnumValue
+Enum(aarch64_ra_sign_scope_t) String(non-leaf) Value(AARCH64_FUNCTION_NON_LEAF)
+
+EnumValue
+Enum(aarch64_ra_sign_scope_t) String(all) Value(AARCH64_FUNCTION_ALL)
+
+mpauth-key=
+Target RejectNegative Report Joined Enum(aarch64_pauth_key_t) Var(aarch64_pauth_key) Init(AARCH64_PAUTH_IKEY_A) Save
+Select pointer authentication key
+
+Enum
+Name(aarch64_pauth_key_t) Type(enum aarch64_pauth_key_index)
+Known AArch64 pointer authentication keys (for use with the -mpauth-key= option):
+
+EnumValue
+Enum(aarch64_pauth_key_t) String(a_key) Value(AARCH64_PAUTH_IKEY_A)
+
+EnumValue
+Enum(aarch64_pauth_key_t) String(b_key) Value(AARCH64_PAUTH_IKEY_B)
+
 mlow-precision-recip-sqrt
 Common Var(flag_mrecip_low_precision_sqrt) Optimization
 Enable the reciprocal square root approximation.  Enabling this reduces
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index ebda6d8..73a66d5 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -35,6 +35,10 @@
   (and (match_code "const_int")
        (match_test "op == CONST0_RTX (mode)")))
 
+(define_predicate "aarch64_const0_const1"
+  (ior (match_test "op == const0_rtx")
+       (match_test "op == const1_rtx")))
+
 (define_predicate "aarch64_ccmp_immediate"
   (and (match_code "const_int")
        (match_test "IN_RANGE (INTVAL (op), -31, 31)")))
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 8cb93ab..204cf45 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -3509,6 +3509,18 @@ Specifies the core for which to tune the performance of this function and also
 whose architectural features to use.  The behavior and valid arguments are the
 same as for the @option{-mcpu=} command-line option.
 
+@item sign-return-address
+@cindex @code{sign-return-address} function attribute, AArch64
+Select the function scope we want to do return address signing on.  The behavior
+and permissible arguments are the same as for the command-line option
+@option{-msign-return-address=}.  The default value is @code{none}
+
+@item pauth-key
+@cindex @code{pauth-key} function attribute, AArch64
+Specify the key used for return address signing for this function.  The behavior
+and permissible arguments are the same as for the command-line option
+@option{-mpauth-key=}.  The default key is @code{a_key}.
+
 @end table
 
 The above target attributes can be specified as follows:
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 18ab6d9..e7f842f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -13344,6 +13344,19 @@ accessed using a single instruction and emitted after each function.  This
 limits the maximum size of functions to 1MB.  This is enabled by default for
 @option{-mcmodel=tiny}.
 
+@item -msign-return-address=@var{scope}
+@opindex msign-return-address
+Select the function scope we want to do return address signing on.  Permissible
+values are @samp{none}, @samp{none-leaf} and @samp{all}.  @samp{none} means
+return address signing is disabled.  @samp{non-leaf} enables it for non-leaf
+functions.  @samp{all} for all functions and is the default value.
+
+@item -mpauth-key=@var{key_name}
+@opindex mpauth-key
+Select the key used for return address signing.  Permissible values are
+@samp{a_key} for A key and @samp{b_key} for B key.  @samp{a_key} is the default
+value.
+
 @end table
 
 @subsubsection @option{-march} and @option{-mcpu} Feature Modifiers
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
new file mode 100644
index 0000000..b786b09
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
@@ -0,0 +1,57 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msign-return-address=all" } */
+
+int foo (int);
+int bar (int, int);
+
+/* sibcall only.  */
+int __attribute__ ((target ("arch=armv8.3-a")))
+func1 (int a, int b)
+{
+  /* paciasp */
+  return foo (a + b);
+  /* autiasp */
+}
+
+/* non-leaf function with sibcall.  */
+int __attribute__ ((target ("arch=armv8.3-a")))
+func2 (int a, int b)
+{
+  /* paciasp */
+  if (a < b)
+    return b;
+
+  a = foo (b);
+
+  return foo (a);
+  /* autiasp */
+}
+
+/* non-leaf function, legacy arch.  */
+int __attribute__ ((target ("arch=armv8.2-a")))
+func3 (int a, int b, int c)
+{
+  /* paciasp */
+  return a + foo (b) + c;
+  /* autiasp */
+}
+
+/* non-leaf function.  */
+int __attribute__ ((target ("arch=armv8.3-a, pauth-key=b_key")))
+func4 (int a, int b, int c)
+{
+  /* paciasp */
+  return a + foo (b) + c;
+  /* retab */
+}
+
+int __attribute__ ((target ("arch=armv8.3-a, sign-return-address=none")))
+func4_disable (int a, int b, int c, int d)
+{
+  return c + bar (a, b) + d;
+}
+
+/* { dg-final { scan-assembler-times "autiasp" 3 } } */
+/* { dg-final { scan-assembler-times "paciasp" 3 } } */
+/* { dg-final { scan-assembler-times "pacibsp" 1 } } */
+/* { dg-final { scan-assembler-times "retab" 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_scope_1.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_scope_1.c
new file mode 100644
index 0000000..f44644d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_scope_1.c
@@ -0,0 +1,57 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msign-return-address=non-leaf" } */
+
+int foo (int);
+int bar (int, int);
+
+/* sibcall only.  */
+int __attribute__ ((target ("arch=armv8.3-a")))
+func1 (int a, int b)
+{
+  /* No authentication.  */
+  return foo (a + b);
+}
+
+/* non-leaf function with sibcall.  */
+int __attribute__ ((target ("arch=armv8.3-a")))
+func2 (int a, int b)
+{
+  /* paciasp */
+  if (a < b)
+    return b;
+
+  a = foo (b);
+
+  return foo (a);
+  /* autiasp */
+}
+
+/* non-leaf function, legacy arch.  */
+int __attribute__ ((target ("arch=armv8.2-a, pauth-key=b_key")))
+func3 (int a, int b, int c)
+{
+  /* pacibsp */
+  return a + foo (b) + c;
+  /* autibsp */
+}
+
+/* non-leaf function.  */
+int __attribute__ ((target ("arch=armv8.3-a, pauth-key=b_key")))
+func4 (int a, int b, int c)
+{
+  /* pacibsp */
+  return a + foo (b) + c;
+  /* retab */
+}
+
+int __attribute__ ((target ("arch=armv8.3-a, sign-return-address=none")))
+func4_disable (int a, int b, int c, int d)
+{
+  return c + bar (a, b) + d;
+}
+
+/* { dg-final { scan-assembler-times "paciasp" 1 } } */
+/* { dg-final { scan-assembler-times "autiasp" 1 } } */
+/* { dg-final { scan-assembler-times "pacibsp" 2 } } */
+/* { dg-final { scan-assembler-times "autibsp" 1 } } */
+/* { dg-final { scan-assembler-times "retab" 1 } } */

