Patchwork [lra] patch to fix some LRA failures of GCC tests on PA-RISC

login
register
mail settings
Submitter Vladimir Makarov
Date April 25, 2012, 7:57 p.m.
Message ID <4F985732.1080209@redhat.com>
Download mbox | patch
Permalink /patch/155089/
State New
Headers show

Comments

Vladimir Makarov - April 25, 2012, 7:57 p.m.
The following patch fixes some testsuite regressions of LRA in 
comparison with reload on PA-RISC.  There are still few regressions 
which I'll work on later.

The patch was bootstrapped on x86/x86-64.

Committed as rev. 186823.

2012-04-25  Vladimir Makarov <vmakarov@redhat.com>

         * lra-constraints.c (get_op_mode): Take mode from operand first
         for asm.
         (match_reload): Use gen_lowpart_SUBREG for scalar int modes.
         (curr_insn_transform): Unshare subregs for inout operands.

Patch

Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 186357)
+++ lra-constraints.c	(working copy)
@@ -797,16 +797,19 @@  static inline enum machine_mode
 get_op_mode (int nop)
 {
   rtx *loc;
-  enum machine_mode mode = curr_static_id->operand[nop].mode;
+  enum machine_mode mode;
+  bool md_first_p = asm_noperands (PATTERN (curr_insn)) < 0;
 
   /* Take mode from the machine description first.  */
-  if (mode != VOIDmode)
+  if (md_first_p && (mode = curr_static_id->operand[nop].mode) != VOIDmode)
     return mode;
   loc = curr_id->operand_loc[nop];
   /* Take mode from the operand second.  */
   mode = GET_MODE (*loc);
   if (mode != VOIDmode)
     return mode;
+  if (! md_first_p && (mode = curr_static_id->operand[nop].mode) != VOIDmode)
+    return mode;
   /* Here is a very rare case.  Take mode from the context.  */
   return find_mode (&PATTERN (curr_insn), VOIDmode, loc);
 }
@@ -858,14 +861,20 @@  match_reload (signed char out, signed ch
 	  reg = new_in_reg
 	    = lra_create_new_reg_with_unique_value (inmode, in_rtx,
 						    goal_class, "");
-	  new_out_reg = gen_lowpart_SUBREG (outmode, reg);
+	  if (SCALAR_INT_MODE_P (inmode))
+	    new_out_reg = gen_lowpart_SUBREG (outmode, reg);
+	  else
+	    new_out_reg = gen_rtx_SUBREG (outmode, reg, 0);
 	}
       else
 	{
 	  reg = new_out_reg
 	    = lra_create_new_reg_with_unique_value (outmode, out_rtx,
 						    goal_class, "");
-	  new_in_reg = gen_lowpart_SUBREG (inmode, new_out_reg);
+	  if (SCALAR_INT_MODE_P (outmode))
+	    new_in_reg = gen_lowpart_SUBREG (inmode, new_out_reg);
+	  else
+	    new_in_reg = gen_rtx_SUBREG (inmode, new_out_reg, 0);
 	}
       bitmap_set_bit (&lra_matched_pseudos, REGNO (reg));
       bitmap_set_bit (&lra_bound_pseudos, REGNO (reg));
@@ -3247,7 +3256,7 @@  curr_insn_transform (void)
 	      && type != OP_OUT)
 	    {
 	      push_to_sequence (before);
-	      lra_emit_move (new_reg, *loc);
+	      lra_emit_move (new_reg, old);
 	      before = get_insns ();
 	      end_sequence ();
 	    }
@@ -3257,7 +3266,12 @@  curr_insn_transform (void)
 	      if (find_reg_note (curr_insn, REG_UNUSED, old) == NULL_RTX)
 		{
 		  start_sequence ();
-		  lra_emit_move (old, new_reg);
+		  /* We don't want sharing subregs as the pseudo can
+		     get a memory and the memory can be processed
+		     several times for eliminations.  */
+		  lra_emit_move (GET_CODE (old) == SUBREG && type == OP_INOUT
+				 ? copy_rtx (old) : old,
+				 new_reg);
 		  emit_insn (after);
 		  after = get_insns ();
 		  end_sequence ();