[pushed,PR113354,LRA] : Fixing LRA failure on building MIPS GCC

Message ID 2719a083-baca-3671-7a49-e7796d68adfb@redhat.com
State New
Headers
Series [pushed,PR113354,LRA] : Fixing LRA failure on building MIPS GCC |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 warning Patch is already merged
linaro-tcwg-bot/tcwg_gcc_build--master-arm warning Patch is already merged

Commit Message

Vladimir Makarov Jan. 15, 2024, 3:26 p.m. UTC
  The following patch fixes

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

The patch was tested on building MIPS target.

The patch was successfully tested and bootstrapped on x86-64, ppc64le, 
aarch64.
  

Patch

commit 5f662bce28618ea5417f68a17d5c2d34b052ecb2
Author: Vladimir N. Makarov <vmakarov@redhat.com>
Date:   Mon Jan 15 10:19:39 2024 -0500

    [PR113354][LRA]: Fixing LRA failure on building MIPS GCC
    
    My recent patch for PR112918 triggered a hidden bug in LRA on MIPS.  A
    pseudo is matched to a register constraint and assigned to a hard
    registers at the first constraint sub-pass but later it is matched to
    X constraint.  Keeping this pseudo in the register (MD0) prevents to
    use the same register for another pseudo in the insn and this results
    in LRA failure.  The patch fixes this by spilling the pseudo at the
    constraint subpass when the chosen alternative constraint not require
    hard register anymore.
    
    gcc/ChangeLog:
    
            PR middle-end/113354
            * lra-constraints.cc (curr_insn_transform): Spill pseudo only used
            in the insn if the corresponding operand does not require hard
            register anymore.

diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index dc41bc3d6c6..3379b88ff22 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -4491,23 +4491,18 @@  curr_insn_transform (bool check_only_p)
 	{
 	  if (goal_alt[i] == NO_REGS
 	      && REG_P (op)
-	      /* When we assign NO_REGS it means that we will not
-		 assign a hard register to the scratch pseudo by
-		 assigment pass and the scratch pseudo will be
-		 spilled.  Spilled scratch pseudos are transformed
-		 back to scratches at the LRA end.  */
-	      && ira_former_scratch_operand_p (curr_insn, i)
-	      && ira_former_scratch_p (REGNO (op)))
+	      && (regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER
+	      /* We assigned a hard register to the pseudo in the past but now
+		 decided to spill it for the insn.  If the pseudo is used only
+		 in this insn, it is better to spill it here as we free hard
+		 registers for other pseudos referenced in the insn.  The most
+		 common case of this is a scratch register which will be
+		 transformed to scratch back at the end of LRA.  */
+	      && lra_get_regno_hard_regno (regno) >= 0
+	      && bitmap_single_bit_set_p (&lra_reg_info[regno].insn_bitmap))
 	    {
-	      int regno = REGNO (op);
 	      lra_change_class (regno, NO_REGS, "      Change to", true);
-	      if (lra_get_regno_hard_regno (regno) >= 0)
-		/* We don't have to mark all insn affected by the
-		   spilled pseudo as there is only one such insn, the
-		   current one.  */
-		reg_renumber[regno] = -1;
-	      lra_assert (bitmap_single_bit_set_p
-			  (&lra_reg_info[REGNO (op)].insn_bitmap));
+	      reg_renumber[regno] = -1;
 	    }
 	  /* We can do an optional reload.  If the pseudo got a hard
 	     reg, we might improve the code through inheritance.  If