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