[Bug target/91102] [9/10 Regression] aarch64 ICE on Linux kernel with -Os starting with r270266

vmakarov at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sun Jul 7 22:07:00 GMT 2019


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91102

--- Comment #5 from Vladimir Makarov <vmakarov at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #1)
> 
> Vlad, could you please have a look?

The culprit patch is actually 

https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=265942 

Prohibiting reload for any user defined registers which should be matched is
too harsh.  We still can reload operands using the match if no one is an
earlier clobber operand.

The following patch should solve the problem:

Index: ../../gcc/gcc/lra-constraints.c
===================================================================
--- ../../gcc/gcc/lra-constraints.c     (revision 273177)
+++ ../../gcc/gcc/lra-constraints.c     (working copy)
@@ -2172,8 +2172,9 @@
                    else
                      {
                        /* Operands don't match.  If the operands are
-                          different user defined explicit hard registers,
-                          then we cannot make them match.  */
+                          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])
@@ -2191,10 +2192,14 @@
                                && REG_USERVAR_P (nop_reg)
                                && REG_P (m_reg)
                                && HARD_REGISTER_P (m_reg)
-                               && REG_USERVAR_P (m_reg))
-                             break;
+                               && REG_USERVAR_P (m_reg)) {
+                             for (int i = 0; i < early_clobbered_regs_num;
i++)
+                               if (m == early_clobbered_nops[i])
+                                 break;
+                             if (i < early_clobbered_regs_num ||
early_clobber_p)
+                               break;
+                           }
                          }
-
                        /* Both operands must allow a reload register,
                           otherwise we cannot make them match.  */
                        if (curr_alt[m] == NO_REGS)

Although I'll take some time to think about the solution before submitting it
into the trunk.


More information about the Gcc-bugs mailing list