https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124041
--- Comment #14 from Robin Dapp <rdapp at gcc dot gnu.org> ---
Just for the record, this is what I tried (and what causes miscompiles):
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 8c8c9d69a96..a7ef1402267 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -4369,11 +4369,19 @@ curr_insn_transform (bool check_only_p)
continue;
old = op = *curr_id->operand_loc[i];
+ machine_mode outer_mode = GET_MODE (old);
+ bool subreg_p = false;
if (GET_CODE (old) == SUBREG)
- old = SUBREG_REG (old);
+ {
+ old = SUBREG_REG (old);
+ subreg_p = true;
+ }
subst = get_equiv_with_elimination (old, curr_insn);
original_subreg_reg_mode[i] = VOIDmode;
equiv_substition_p[i] = false;
+ if (subreg_p && HARD_REGISTER_P (subst)
+ && !targetm.hard_regno_mode_ok (REGNO (subst), outer_mode))
+ continue;
if (subst != old)
{
equiv_substition_p[i] = true;