]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
lra: Reallow reloading user hard registers if the insn is not asm [PR 120983] master trunk
authorXi Ruoyao <xry111@xry111.site>
Tue, 8 Jul 2025 06:39:11 +0000 (14:39 +0800)
committerXi Ruoyao <xry111@xry111.site>
Sat, 12 Jul 2025 08:45:20 +0000 (16:45 +0800)
The PR 87600 fix has disallowed reloading user hard registers to resolve
earlyclobber-induced conflict.

However before reload, recog completely ignores the constraints of
insns, so the RTL passes may produce insns where some user hard
registers violate an earlyclobber.  Then we'll get an ICE without
reloading them, like what we are recently encountering in LoongArch test
suite.

IIUC "recog does not look at constraints until reload" has been a
well-established rule in GCC for years and I don't have enough skill to
challange it.  So reallow reloading user hard registers (but still
disallow doing so for asm) to fix the ICE.

gcc/ChangeLog:

PR rtl-optimization/120983
* lra-constraints.cc (process_alt_operands): Allow reloading
user hard registers unless the insn is an asm.

gcc/lra-constraints.cc

index 274b52cd617672337d63bd33f12844d4d076dad2..c941d2f33e24ae870fbc468cc432795afe89c076 100644 (file)
@@ -2416,14 +2416,15 @@ process_alt_operands (int only_alternative)
                        if (curr_static_id->operand[nop].type == OP_INOUT
                            || curr_static_id->operand[m].type == OP_INOUT)
                          break;
                        if (curr_static_id->operand[nop].type == OP_INOUT
                            || curr_static_id->operand[m].type == OP_INOUT)
                          break;
-                       /* Operands don't match.  If the operands are
-                          different user defined explicit hard
+                       /* Operands don't match.  For asm if the operands
+                          are different user defined explicit hard
                           registers, then we cannot make them match
                           when one is early clobber operand.  */
                        if ((REG_P (*curr_id->operand_loc[nop])
                             || SUBREG_P (*curr_id->operand_loc[nop]))
                            && (REG_P (*curr_id->operand_loc[m])
                           registers, then we cannot make them match
                           when one is early clobber operand.  */
                        if ((REG_P (*curr_id->operand_loc[nop])
                             || SUBREG_P (*curr_id->operand_loc[nop]))
                            && (REG_P (*curr_id->operand_loc[m])
-                               || SUBREG_P (*curr_id->operand_loc[m])))
+                               || SUBREG_P (*curr_id->operand_loc[m]))
+                           && INSN_CODE (curr_insn) < 0)
                          {
                            rtx nop_reg = *curr_id->operand_loc[nop];
                            if (SUBREG_P (nop_reg))
                          {
                            rtx nop_reg = *curr_id->operand_loc[nop];
                            if (SUBREG_P (nop_reg))
@@ -3328,19 +3329,15 @@ process_alt_operands (int only_alternative)
                  first_conflict_j = j;
                last_conflict_j = j;
                /* Both the earlyclobber operand and conflicting operand
                  first_conflict_j = j;
                last_conflict_j = j;
                /* Both the earlyclobber operand and conflicting operand
-                  cannot both be user defined hard registers.  */
+                  cannot both be user defined hard registers for asm.
+                  Let curr_insn_transform diagnose it.  */
                if (HARD_REGISTER_P (operand_reg[i])
                    && REG_USERVAR_P (operand_reg[i])
                    && operand_reg[j] != NULL_RTX
                    && HARD_REGISTER_P (operand_reg[j])
                if (HARD_REGISTER_P (operand_reg[i])
                    && REG_USERVAR_P (operand_reg[i])
                    && operand_reg[j] != NULL_RTX
                    && HARD_REGISTER_P (operand_reg[j])
-                   && REG_USERVAR_P (operand_reg[j]))
-                 {
-                   /* For asm, let curr_insn_transform diagnose it.  */
-                   if (INSN_CODE (curr_insn) < 0)
+                   && REG_USERVAR_P (operand_reg[j])
+                   && INSN_CODE (curr_insn) < 0)
                      return false;
                      return false;
-                   fatal_insn ("unable to generate reloads for "
-                               "impossible constraints:", curr_insn);
-                 }
              }
          if (last_conflict_j < 0)
            continue;
              }
          if (last_conflict_j < 0)
            continue;