[gcc(refs/vendors/ARM/heads/morello)] morello: Fix unwinding regression for AArch64 Linux

Matthew Malcomson matmal01@gcc.gnu.org
Wed Apr 6 09:58:27 GMT 2022


https://gcc.gnu.org/g:80de9ec5a83f24e3f77a909812bdd28016b9a2b9

commit 80de9ec5a83f24e3f77a909812bdd28016b9a2b9
Author: Stam Markianos-Wright <stam.markianos-wright@arm.com>
Date:   Tue Mar 8 03:26:26 2022 +0000

    morello: Fix unwinding regression for AArch64 Linux
    
    Recent commit f30724eac73 introduced some regressions relating to C++
    exceptions and unwinding in non-capability A64 compilation for the
    aarch64-none-linux-gnu target.
    
    This has been tracked down to a strange case of CADImode being injected
    into an AArch64 non-capability compilation through `init_reg_modes_target`
    to `aarch64_hard_regno_mode_ok` for registers 0 to 30.
    This now rejects CADImode if TARGET_CAPABILITY_ANY.
    
    This would then get picked up by hook `targetm.dwarf_frame_reg_mode` and
    the 198 register number offset was incorrectly being applied to `rnum`
    and it was not being removed by DWARF_REG_TO_UNWIND_COLUMN, which is
    triggered on TARGET_CAPABILITY_PURE.
    
    This is also expected to be a complication for Hybrid, where we do expect
    CADImode to be valid, but we only intend to ever store x registers in the
    unwind tables. This thankfully can be easily addressed using the
    TARGET_DWARF_FRAME_REG_MODE target hook.

Diff:
---
 gcc/config/aarch64/aarch64.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 1d07c4fc66d..051c0bac378 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -2650,7 +2650,7 @@ static bool
 aarch64_hard_regno_mode_ok (unsigned regno, machine_mode mode)
 {
   if (mode == CADImode)
-    return aarch64_regno_ok_for_base_p (regno, true);
+    return TARGET_CAPABILITY_ANY && aarch64_regno_ok_for_base_p (regno, true);
 
   if (GET_MODE_CLASS (mode) == MODE_CC)
     return regno == CC_REGNUM;
@@ -24757,6 +24757,19 @@ aarch64_capabilities_in_hardware (void)
     return false;
 }
 
+/* Implement the TARGET_DWARF_FRAME_REG_MODE target hook. This only has an
+   impact in Hybrid Capability Morello compilation, where the default
+   raw_reg_mode returned would still be CADImode, but we want to use DImode
+   to only save x registers in the unwind tables.  */
+machine_mode
+aarch64_dwarf_frame_reg_mode (int regno)
+{
+  if (TARGET_CAPABILITY_HYBRID)
+    return noncapability_mode (default_dwarf_frame_reg_mode (regno));
+  else
+    return default_dwarf_frame_reg_mode (regno);
+}
+
 /* Target-specific selftests.  */
 
 #if CHECKING_P
@@ -25370,6 +25383,9 @@ aarch64_libgcc_floating_mode_supported_p
 #undef TARGET_CAPABILITY_MODE
 #define TARGET_CAPABILITY_MODE aarch64_target_capability_mode
 
+#undef TARGET_DWARF_FRAME_REG_MODE
+#define TARGET_DWARF_FRAME_REG_MODE aarch64_dwarf_frame_reg_mode
+
 #undef TARGET_CODE_ADDRESS_FROM_POINTER
 #define TARGET_CODE_ADDRESS_FROM_POINTER aarch64_code_address_from_pointer


More information about the Gcc-cvs mailing list