Make more use of subreg_lowpart_offset

Message ID 871so2v9ov.fsf@linaro.org
State New
Headers show

Commit Message

Richard Sandiford Aug. 23, 2017, 10:51 a.m.
This patch uses subreg_lowpart_offset in places that open-coded
the calculation.  It also uses it in regcprop.c to test whether,
after a mode change, the first register in a multi-register group
is still the right one.

Tested on aarch64-linux-gnu and x86_64-linux-gnu, and by making sure
that there were no differences in testsuite assembly output for one
target per CPU.  OK to install?

Richard


2017-08-23  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* calls.c (expand_call): Use subreg_lowpart_offset.
	* cse.c (cse_insn): Likewise.
	* regcprop.c (copy_value): Likewise.
	(copyprop_hardreg_forward_1): Likewise.

Patch

Index: gcc/calls.c
===================================================================
--- gcc/calls.c	2017-08-21 15:49:31.653164829 +0100
+++ gcc/calls.c	2017-08-23 10:46:06.552151584 +0100
@@ -4128,7 +4128,6 @@  expand_call (tree exp, rtx target, int i
 	{
 	  tree type = rettype;
 	  int unsignedp = TYPE_UNSIGNED (type);
-	  int offset = 0;
 	  machine_mode pmode;
 
 	  /* Ensure we promote as expected, and get the new unsignedness.  */
@@ -4136,18 +4135,8 @@  expand_call (tree exp, rtx target, int i
 					 funtype, 1);
 	  gcc_assert (GET_MODE (target) == pmode);
 
-	  if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN)
-	      && (GET_MODE_SIZE (GET_MODE (target))
-		  > GET_MODE_SIZE (TYPE_MODE (type))))
-	    {
-	      offset = GET_MODE_SIZE (GET_MODE (target))
-	        - GET_MODE_SIZE (TYPE_MODE (type));
-	      if (! BYTES_BIG_ENDIAN)
-	        offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD;
-	      else if (! WORDS_BIG_ENDIAN)
-	        offset %= UNITS_PER_WORD;
-	    }
-
+	  unsigned int offset = subreg_lowpart_offset (TYPE_MODE (type),
+						       GET_MODE (target));
 	  target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset);
 	  SUBREG_PROMOTED_VAR_P (target) = 1;
 	  SUBREG_PROMOTED_SET (target, unsignedp);
Index: gcc/cse.c
===================================================================
--- gcc/cse.c	2017-08-22 17:14:30.334912144 +0100
+++ gcc/cse.c	2017-08-23 10:46:06.552151584 +0100
@@ -5964,7 +5964,6 @@  cse_insn (rtx_insn *insn)
 		rtx new_src = 0;
 		unsigned src_hash;
 		struct table_elt *src_elt;
-		int byte = 0;
 
 		/* Ignore invalid entries.  */
 		if (!REG_P (elt->exp)
@@ -5977,13 +5976,8 @@  cse_insn (rtx_insn *insn)
 		  new_src = elt->exp;
 		else
 		  {
-		    /* Calculate big endian correction for the SUBREG_BYTE.
-		       We have already checked that M1 (GET_MODE (dest))
-		       is not narrower than M2 (new_mode).  */
-		    if (BYTES_BIG_ENDIAN)
-		      byte = (GET_MODE_SIZE (GET_MODE (dest))
-			      - GET_MODE_SIZE (new_mode));
-
+		    unsigned int byte
+		      = subreg_lowpart_offset (new_mode, GET_MODE (dest));
 		    new_src = simplify_gen_subreg (new_mode, elt->exp,
 					           GET_MODE (dest), byte);
 		  }
Index: gcc/regcprop.c
===================================================================
--- gcc/regcprop.c	2017-08-21 15:49:31.652164829 +0100
+++ gcc/regcprop.c	2017-08-23 10:46:06.553156355 +0100
@@ -344,8 +344,7 @@  copy_value (rtx dest, rtx src, struct va
      We can't properly represent the latter case in our tables, so don't
      record anything then.  */
   else if (sn < (unsigned int) hard_regno_nregs[sr][vd->e[sr].mode]
-	   && (GET_MODE_SIZE (vd->e[sr].mode) > UNITS_PER_WORD
-	       ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
+	   && subreg_lowpart_offset (GET_MODE (dest), vd->e[sr].mode) != 0)
     return;
 
   /* If SRC had been assigned a mode narrower than the copy, we can't
@@ -878,8 +877,7 @@  copyprop_hardreg_forward_1 (basic_block
 		 is also invalid.  */
 	      if (hard_regno_nregs[regno][mode]
 		  < hard_regno_nregs[regno][vd->e[regno].mode]
-		  && (GET_MODE_SIZE (vd->e[regno].mode) > UNITS_PER_WORD
-		      ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
+		  && subreg_lowpart_offset (mode, vd->e[regno].mode) != 0)
 		goto no_move_special_case;
 	    }