Alpha is one of the last targets still forcing TARGET_LRA_P to false, and
reload is slated for removal (PR113932).  Add a transitional -mlra option,
following the hppa pattern (r16-5534), so that -mno-lra remains available as
an escape hatch until reload is deleted.

LRA is enabled by default only on BWX targets.  On non-BWX targets a QImode or
HImode pseudo that has to be spilled reaches the target's reload_in<mode> /
reload_out<mode> secondary-reload path, which LRA does not yet drive correctly
(PR117185: LRA either loops generating reload insns or passes a pseudo where
get_unaligned_address expects a MEM).  BWX has real byte/word memory
instructions and does not need that path, so it is unaffected.  Gating the
default on TARGET_BWX enables LRA where it is known good and leaves non-BWX on
reload until PR117185 is resolved.  -mlra / -mno-lra override the default in
either direction.

The default is resolved in alpha_option_override once TARGET_BWX is final, so
it tracks -mcpu (e.g. -mcpu=ev4 selects reload, -mcpu=ev56 selects LRA) rather
than only the configured default CPU.

Tested with an alpha-linux-gnu cross (both ev4/non-BWX and --with-cpu=ev56/BWX,
--enable-checking=yes,rtl): libgcc, libgomp and libstdc++ build cleanly under
LRA, and gcc.c-torture/execute under qemu-alpha at -O0 and -O2 gives identical
results with -mlra and -mno-lra on both configurations (3380 results each, no
differences).  A native ev56 bootstrap with c,c++,m2 completes and, comparing a
full make check-gcc/check-g++ at the default (LRA) against --target_board
unix/-mno-lra (reload), LRA shows no correctness regressions: gcc unexpected
failures drop from 626 to 541 and g++ from 57 to 56, with the only LRA-only
differences being debug-info-quality (gcc.dg/guality) shifts in LRA's favor.
The prerequisite middle-end fix for the BWX m2 miscompile is PR117184.

input_operand accepts an arbitrary integer constant only once register
allocation is under way, since before that a constant that needs more than one
instruction has to stay in its unsplit form.  It tested reload_in_progress,
which LRA never sets, so under LRA the predicate fell back to add_operand and
rejected constants that only the post-allocation splitter can handle.  LRA
re-materializing an invariant (lra_undo_inheritance) then emitted an
unrecognizable (set (reg:DI) (const_int 0xffffffff00000000)) and tripped the
USE/CLOBBER/ASM_INPUT assertion in lra_set_insn_recog_data.  Test for
lra_in_progress as well; the constant is split as before, into
lda + sll here.  Seen compiling glibc's nss/nss_module.c at -O2 -mcpu=ev67.

gcc/
        * config/alpha/alpha.opt (mlra): New option.
        * config/alpha/alpha.opt.urls: Regenerate.
        * config/alpha/alpha.cc (alpha_option_override): Default alpha_lra_p
        to TARGET_BWX when not set explicitly.
        (alpha_use_lra_p): New function.
        (TARGET_LRA_P): Define to it instead of hook_bool_void_false.
        * config/alpha/predicates.md (input_operand): Test lra_in_progress
        in the CONST_INT and CONST_VECTOR cases.
---

v2:
 - Test lra_in_progress as well as reload_in_progress and reload_completed
   in input_operand.  Without it the predicate fell back to add_operand
   during LRA and rejected constants that only the post-allocation splitter
   can handle, so LRA re-materializing an invariant emitted an
   unrecognizable (set (reg:DI) (const_int 0xffffffff00000000)) and tripped
   the USE/CLOBBER/ASM_INPUT assertion in lra_set_insn_recog_data.  Found
   building glibc's nss/nss_module.c at -O2 -mcpu=ev67.
 - Regenerate alpha.opt.urls for the new option.

 gcc/config/alpha/alpha.cc       | 18 +++++++++++++++++-
 gcc/config/alpha/alpha.opt      |  4 ++++
 gcc/config/alpha/alpha.opt.urls |  2 ++
 gcc/config/alpha/predicates.md  |  4 ++--
 4 files changed, 25 insertions(+), 3 deletions(-)

diff --git ./gcc/config/alpha/alpha.cc ./gcc/config/alpha/alpha.cc
index 90e4c21dd11..a6aceb1b21b 100644
--- ./gcc/config/alpha/alpha.cc
+++ ./gcc/config/alpha/alpha.cc
@@ -209,6 +209,7 @@ static rtx alpha_emit_xfloating_compare (enum rtx_code *, 
rtx, rtx);
 static void alpha_handle_trap_shadows (void);
 static void alpha_align_insns (void);
 static void alpha_override_options_after_change (void);
+static bool alpha_use_lra_p (void);
 
 #if TARGET_ABI_OPEN_VMS
 static void alpha_write_linkage (FILE *, const char *);
@@ -585,6 +586,13 @@ alpha_option_override (void)
   else if (flag_pic == 2)
     target_flags &= ~MASK_SMALL_DATA;
 
+  /* Default to LRA on BWX targets, where it has been validated.  On non-BWX
+     targets QImode and HImode reloads still rely on the reload-only secondary
+     reload path that LRA does not yet drive (PR117185), so keep those on
+     reload until that is fixed.  An explicit -mlra/-mno-lra overrides this.  
*/
+  if (alpha_lra_p < 0)
+    alpha_lra_p = TARGET_BWX;
+
   alpha_override_options_after_change ();
 
   /* Register variables and functions with the garbage collector.  */
@@ -625,6 +633,14 @@ alpha_override_options_after_change (void)
     str_align_functions = "16";
 }
 
+/* Implement TARGET_LRA_P.  */
+
+static bool
+alpha_use_lra_p (void)
+{
+  return alpha_lra_p;
+}
+
 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones.  */
 
 int
@@ -10817,7 +10833,7 @@ alpha_c_mode_for_floating_type (enum tree_index ti)
 #endif
 
 #undef TARGET_LRA_P
-#define TARGET_LRA_P hook_bool_void_false
+#define TARGET_LRA_P alpha_use_lra_p
 
 #undef TARGET_LEGITIMATE_ADDRESS_P
 #define TARGET_LEGITIMATE_ADDRESS_P alpha_legitimate_address_p
diff --git ./gcc/config/alpha/alpha.opt ./gcc/config/alpha/alpha.opt
index 1c1fbbb69f1..c97c31a865d 100644
--- ./gcc/config/alpha/alpha.opt
+++ ./gcc/config/alpha/alpha.opt
@@ -136,3 +136,7 @@ Tune expected memory latency.
 mtls-size=
 Target RejectNegative Joined UInteger Var(alpha_tls_size) Init(32)
 Specify bit size of immediate TLS offsets.
+
+mlra
+Target Var(alpha_lra_p) Init(-1) Undocumented
+Use LRA instead of reload (transitional).
diff --git ./gcc/config/alpha/alpha.opt.urls ./gcc/config/alpha/alpha.opt.urls
index e925a2b1ff6..b038f4f43e5 100644
--- ./gcc/config/alpha/alpha.opt.urls
+++ ./gcc/config/alpha/alpha.opt.urls
@@ -89,3 +89,5 @@ UrlSuffix(gcc/DEC-Alpha-Options.html#index-mmemory-latency)
 mtls-size=
 UrlSuffix(gcc/DEC-Alpha-Options.html#index-mtls-size-1)
 
+; skipping UrlSuffix for 'mlra' due to finding no URLs
+
diff --git ./gcc/config/alpha/predicates.md ./gcc/config/alpha/predicates.md
index 68e3ac69f2a..7ca3a6075d2 100644
--- ./gcc/config/alpha/predicates.md
+++ ./gcc/config/alpha/predicates.md
@@ -201,14 +201,14 @@
       return op == CONST0_RTX (mode);
 
     case CONST_VECTOR:
-      if (reload_in_progress || reload_completed)
+      if (lra_in_progress || reload_in_progress || reload_completed)
        return alpha_legitimate_constant_p (mode, op);
       return op == CONST0_RTX (mode);
 
     case CONST_INT:
       if (mode == QImode || mode == HImode)
        return true;
-      if (reload_in_progress || reload_completed)
+      if (lra_in_progress || reload_in_progress || reload_completed)
        return alpha_legitimate_constant_p (mode, op);
       return add_operand (op, mode);
 
-- 
2.54.0

Reply via email to