Patchwork [SPARC] Fix recent and older thinkos

login
register
mail settings
Submitter Eric Botcazou
Date Sept. 30, 2012, 5:51 p.m.
Message ID <53997127.nmRJ6TYqOB@polaris>
Download mbox | patch
Permalink /patch/188178/
State New
Headers show

Comments

Eric Botcazou - Sept. 30, 2012, 5:51 p.m.
This fixes a recent thinko introduced by the double-int rewrite and 
responsible for the following failures:

FAIL: gcc.target/sparc/pdist-2.c scan-tree-dump optimized "return 475"
FAIL: gcc.target/sparc/pdist-3.c execution test

as well as an older one spotted by Bernd, whereby the compiler emits non-
canonical RTL for the stack adjustments issued for the epilogue.  The patch 
also contains a patchlet for reorg.c that performs a bit of manual CSE:
 
XVECEXP (PATTERN (insn), 0, 0)  --> delay_insn

and which makes it more obvious why you can take JUMP_LABEL (delay_insn).

Tested on SPARC/Linux, applied on the mainline.


2012-09-30  Eric Botcazou  <ebotcazou@adacore.com>

	* reorg.c (relax_delay_slots): Use delay_insn consistently.

	* config/sparc/sparc.c (gen_stack_pointer_dec): Delete.
	(sparc_expand_epilogue): Use gen_stack_pointer_inc and adjust.
	(sparc_flat_expand_epilogue): Likewise.
	(emit_and_preserve): Likewise.
	(sparc_fold_builtin): Fix thinko in latest change.

Patch

Index: reorg.c
===================================================================
--- reorg.c	(revision 191796)
+++ reorg.c	(working copy)
@@ -3432,9 +3432,8 @@  relax_delay_slots (rtx first)
 	    reorg_redirect_jump (insn, other_target);
 	}
 
-      /* Now look only at cases where we have filled a delay slot.  */
-      if (!NONJUMP_INSN_P (insn)
-	  || GET_CODE (PATTERN (insn)) != SEQUENCE)
+      /* Now look only at cases where we have a filled delay slot.  */
+      if (!NONJUMP_INSN_P (insn) || GET_CODE (PATTERN (insn)) != SEQUENCE)
 	continue;
 
       pat = PATTERN (insn);
@@ -3494,9 +3493,8 @@  relax_delay_slots (rtx first)
 	}
 
       /* Now look only at the cases where we have a filled JUMP_INSN.  */
-      if (!JUMP_P (XVECEXP (PATTERN (insn), 0, 0))
-	  || ! (condjump_p (XVECEXP (PATTERN (insn), 0, 0))
-		|| condjump_in_parallel_p (XVECEXP (PATTERN (insn), 0, 0))))
+      if (!JUMP_P (delay_insn)
+	  || !(condjump_p (delay_insn) || condjump_in_parallel_p (delay_insn)))
 	continue;
 
       target_label = JUMP_LABEL (delay_insn);
Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 191796)
+++ config/sparc/sparc.c	(working copy)
@@ -4976,18 +4976,6 @@  gen_stack_pointer_inc (rtx increment)
 				    increment));
 }
 
-/* Generate a decrement for the stack pointer.  */
-
-static rtx
-gen_stack_pointer_dec (rtx decrement)
-{
-  return gen_rtx_SET (VOIDmode,
-		      stack_pointer_rtx,
-		      gen_rtx_MINUS (Pmode,
-				     stack_pointer_rtx,
-				     decrement));
-}
-
 /* Expand the function prologue.  The prologue is responsible for reserving
    storage for the frame, saving the call-saved registers and loading the
    GOT register if needed.  */
@@ -5258,17 +5246,17 @@  sparc_expand_epilogue (bool for_eh)
   else if (sparc_leaf_function_p)
     {
       if (size <= 4096)
-	emit_insn (gen_stack_pointer_dec (GEN_INT (-size)));
+	emit_insn (gen_stack_pointer_inc (GEN_INT (size)));
       else if (size <= 8192)
 	{
-	  emit_insn (gen_stack_pointer_dec (GEN_INT (-4096)));
-	  emit_insn (gen_stack_pointer_dec (GEN_INT (4096 - size)));
+	  emit_insn (gen_stack_pointer_inc (GEN_INT (4096)));
+	  emit_insn (gen_stack_pointer_inc (GEN_INT (size - 4096)));
 	}
       else
 	{
 	  rtx reg = gen_rtx_REG (Pmode, 1);
-	  emit_move_insn (reg, GEN_INT (-size));
-	  emit_insn (gen_stack_pointer_dec (reg));
+	  emit_move_insn (reg, GEN_INT (size));
+	  emit_insn (gen_stack_pointer_inc (reg));
 	}
     }
 }
@@ -5318,17 +5306,17 @@  sparc_flat_expand_epilogue (bool for_eh)
       emit_insn (gen_blockage ());
 
       if (size <= 4096)
-	emit_insn (gen_stack_pointer_dec (GEN_INT (-size)));
+	emit_insn (gen_stack_pointer_inc (GEN_INT (size)));
       else if (size <= 8192)
 	{
-	  emit_insn (gen_stack_pointer_dec (GEN_INT (-4096)));
-	  emit_insn (gen_stack_pointer_dec (GEN_INT (4096 - size)));
+	  emit_insn (gen_stack_pointer_inc (GEN_INT (4096)));
+	  emit_insn (gen_stack_pointer_inc (GEN_INT (size - 4096)));
 	}
       else
 	{
 	  rtx reg = gen_rtx_REG (Pmode, 1);
-	  emit_move_insn (reg, GEN_INT (-size));
-	  emit_insn (gen_stack_pointer_dec (reg));
+	  emit_move_insn (reg, GEN_INT (size));
+	  emit_insn (gen_stack_pointer_inc (reg));
 	}
     }
 }
@@ -10131,7 +10119,7 @@  sparc_fold_builtin (tree fndecl, int n_a
 	  && TREE_CODE (arg2) == INTEGER_CST)
 	{
 	  bool overflow = false;
-	  double_int di_arg2 = TREE_INT_CST (arg2);
+	  double_int result = TREE_INT_CST (arg2);
 	  double_int tmp;
 	  unsigned i;
 
@@ -10147,13 +10135,13 @@  sparc_fold_builtin (tree fndecl, int n_a
 	      if (tmp.is_negative ())
 		tmp = tmp.neg_with_overflow (&neg2_ovf);
 
-	      tmp = di_arg2.add_with_sign (tmp, false, &add2_ovf);
+	      result = result.add_with_sign (tmp, false, &add2_ovf);
 	      overflow |= neg1_ovf | neg2_ovf | add1_ovf | add2_ovf;
 	    }
 
 	  gcc_assert (!overflow);
 
-	  return build_int_cst_wide (rtype, tmp.low, tmp.high);
+	  return build_int_cst_wide (rtype, result.low, result.high);
 	}
 
     default:
@@ -10454,7 +10442,7 @@  emit_and_preserve (rtx seq, rtx reg, rtx
     = gen_rtx_MEM (word_mode, plus_constant (Pmode, stack_pointer_rtx,
 					     SPARC_STACK_BIAS + offset));
 
-  emit_insn (gen_stack_pointer_dec (GEN_INT (size)));
+  emit_insn (gen_stack_pointer_inc (GEN_INT (-size)));
   emit_insn (gen_rtx_SET (VOIDmode, slot, reg));
   if (reg2)
     emit_insn (gen_rtx_SET (VOIDmode,