public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Make more use of paradoxical_subreg_p
@ 2017-08-21 14:16 Richard Sandiford
  2017-08-22 11:13 ` Richard Biener
  0 siblings, 1 reply; 2+ messages in thread
From: Richard Sandiford @ 2017-08-21 14:16 UTC (permalink / raw)
  To: gcc-patches

This patch makes more use of the existing paradoxical_subreg_p
predicate and also adds a version that operates on outer and
inner modes.

Some of the affected tests were based on GET_MODE_SIZE rather than
GET_MODE_PRECISION and so the patch could change the result for modes
that have the same size but different precisions.  I think in each
case the change should be a no-op or more correct, since a mode with
precision N bits can't be expected to hold all of a mode with precision
M>N bits.

The patch changes the branch taken in simplify_subreg for modes with
equal precision, but the new form matches the commentary more closely.
Both branches should be equally good in that situation.

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

Richard


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

gcc/
	* rtl.h (paradoxical_subreg_p): Define inline, and add a version
	that takes the outer and inner modes.
	* doc/rtl.texi: Use paradoxical_subreg_p instead of a GET_MODE_SIZE
	comparison as the canonical test for a paradoxical subreg.
	* combine.c (simplify_set): Use paradoxical_subreg_p.
	(make_extraction): Likewise.
	(force_to_mode): Likewise.
	(rtx_equal_for_field_assignment_p): Likewise.
	(gen_lowpart_for_combine): Likewise.
	(simplify_comparison): Likewise.
	* cse.c (equiv_constant): Likewise.
	* expmed.c (store_bit_field_1): Likewise.
	* final.c (alter_subreg): Likewise.
	* fwprop.c (propagate_rtx): Likewise.
	(forward_propagate_subreg): Likewise.
	* ira-conflicts.c (ira_build_conflicts): Likewise.
	* lower-subreg.c (simplify_gen_subreg_concatn): Likewise.
	* lra-constraints.c (curr_insn_transform): Likewise.
	(split_reg): Likewise.
	* lra-eliminations.c (move_plus_up): Likewise.
	(lra_eliminate_regs_1): Likewise.
	* recog.c (general_operand): Likewise.
	* ree.c (combine_reaching_defs): Likewise.
	* reload.c (push_reload): Likewise.
	(find_reloads): Likewise.
	* reload1.c (elimination_effects): Likewise.
	(compute_reload_subreg_offset): Likewise.
	(choose_reload_regs): Likewise.
	* rtlanal.c (subreg_lsb_1): Likewise.
	* simplify-rtx.c (simplify_unary_operation_1): Likewise.
	(simplify_subreg): Likewise.
	* var-tracking.c (track_loc_p): Likewise.
	* emit-rtl.c (byte_lowpart_offset): Likewise.
	(paradoxical_subreg_p): Delete out-of-line definition.

Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h	2017-08-21 10:42:34.185530464 +0100
+++ gcc/rtl.h	2017-08-21 14:20:43.099964655 +0100
@@ -2784,10 +2784,28 @@ extern rtx operand_subword (rtx, unsigne
 
 /* In emit-rtl.c */
 extern rtx operand_subword_force (rtx, unsigned int, machine_mode);
-extern bool paradoxical_subreg_p (const_rtx);
 extern int subreg_lowpart_p (const_rtx);
 extern unsigned int subreg_size_lowpart_offset (unsigned int, unsigned int);
 
+/* Return true if a subreg with the given outer and inner modes is
+   paradoxical.  */
+
+inline bool
+paradoxical_subreg_p (machine_mode outermode, machine_mode innermode)
+{
+  return GET_MODE_PRECISION (outermode) > GET_MODE_PRECISION (innermode);
+}
+
+/* Return true if X is a paradoxical subreg, false otherwise.  */
+
+inline bool
+paradoxical_subreg_p (const_rtx x)
+{
+  if (GET_CODE (x) != SUBREG)
+    return false;
+  return paradoxical_subreg_p (GET_MODE (x), GET_MODE (SUBREG_REG (x)));
+}
+
 /* Return the SUBREG_BYTE for an OUTERMODE lowpart of an INNERMODE value.  */
 
 inline unsigned int
Index: gcc/doc/rtl.texi
===================================================================
--- gcc/doc/rtl.texi	2017-07-27 10:37:54.486030028 +0100
+++ gcc/doc/rtl.texi	2017-08-21 14:20:43.094947435 +0100
@@ -1872,7 +1872,7 @@ expression is called @dfn{paradoxical}.
 class of @code{subreg} is:
 
 @smallexample
-GET_MODE_SIZE (@var{m1}) > GET_MODE_SIZE (@var{m2})
+paradoxical_subreg_p (@var{m1}, @var{m2})
 @end smallexample
 
 Paradoxical @code{subreg}s can be used as both lvalues and rvalues.
Index: gcc/combine.c
===================================================================
--- gcc/combine.c	2017-08-21 10:42:34.185530464 +0100
+++ gcc/combine.c	2017-08-21 14:20:43.092940547 +0100
@@ -6809,9 +6809,7 @@ simplify_set (rtx x)
 	   / UNITS_PER_WORD)
 	  == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))
 	       + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
-      && (WORD_REGISTER_OPERATIONS
-	  || (GET_MODE_SIZE (GET_MODE (src))
-	      <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))))
+      && (WORD_REGISTER_OPERATIONS || !paradoxical_subreg_p (src))
 #ifdef CANNOT_CHANGE_MODE_CLASS
       && ! (REG_P (dest) && REGNO (dest) < FIRST_PSEUDO_REGISTER
 	    && REG_CANNOT_CHANGE_MODE_P (REGNO (dest),
@@ -7456,7 +7454,7 @@ make_extraction (machine_mode mode, rtx
 		     : BITS_PER_UNIT)) == 0
 	      /* We can't do this if we are widening INNER_MODE (it
 		 may not be aligned, for one thing).  */
-	      && GET_MODE_PRECISION (inner_mode) >= GET_MODE_PRECISION (tmode)
+	      && !paradoxical_subreg_p (tmode, inner_mode)
 	      && (inner_mode == tmode
 		  || (! mode_dependent_address_p (XEXP (inner, 0),
 						  MEM_ADDR_SPACE (inner))
@@ -7669,7 +7667,7 @@ make_extraction (machine_mode mode, rtx
       /* If bytes are big endian and we had a paradoxical SUBREG, we must
 	 adjust OFFSET to compensate.  */
       if (BYTES_BIG_ENDIAN
-	  && GET_MODE_SIZE (inner_mode) < GET_MODE_SIZE (is_mode))
+	  && paradoxical_subreg_p (is_mode, inner_mode))
 	offset -= GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (inner_mode);
 
       /* We can now move to the desired byte.  */
@@ -8529,7 +8527,7 @@ force_to_mode (rtx x, machine_mode mode,
 
   /* If X is narrower than MODE and we want all the bits in X's mode, just
      get X in the proper mode.  */
-  if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode)
+  if (paradoxical_subreg_p (mode, GET_MODE (x))
       && (GET_MODE_MASK (GET_MODE (x)) & ~mask) == 0)
     return gen_lowpart (mode, x);
 
@@ -9408,7 +9406,7 @@ rtx_equal_for_field_assignment_p (rtx x,
 {
   if (widen_x && GET_MODE (x) != GET_MODE (y))
     {
-      if (GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (y)))
+      if (paradoxical_subreg_p (GET_MODE (x), GET_MODE (y)))
 	return 0;
       if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
 	return 0;
@@ -11488,7 +11486,7 @@ gen_lowpart_for_combine (machine_mode om
       /* If we want to refer to something bigger than the original memref,
 	 generate a paradoxical subreg instead.  That will force a reload
 	 of the original memref X.  */
-      if (isize < osize)
+      if (paradoxical_subreg_p (omode, imode))
 	return gen_rtx_SUBREG (omode, x, 0);
 
       if (WORDS_BIG_ENDIAN)
@@ -12145,8 +12143,7 @@ simplify_comparison (enum rtx_code code,
 
 	  /* If the inner mode is narrower and we are extracting the low part,
 	     we can treat the SUBREG as if it were a ZERO_EXTEND.  */
-	  if (subreg_lowpart_p (op0)
-	      && GET_MODE_PRECISION (GET_MODE (SUBREG_REG (op0))) < mode_width)
+	  if (paradoxical_subreg_p (op0))
 	    ;
 	  else if (subreg_lowpart_p (op0)
 		   && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
Index: gcc/cse.c
===================================================================
--- gcc/cse.c	2017-08-21 10:42:34.185530464 +0100
+++ gcc/cse.c	2017-08-21 14:20:43.093943991 +0100
@@ -3802,7 +3802,7 @@ equiv_constant (rtx x)
 	 the subreg.  Note that the upper bits of paradoxical subregs
 	 are undefined, so they cannot be said to equal anything.  */
       if (REG_P (SUBREG_REG (x))
-	  && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (imode)
+	  && !paradoxical_subreg_p (x)
 	  && (new_rtx = equiv_constant (SUBREG_REG (x))) != 0)
         return simplify_subreg (mode, new_rtx, imode, SUBREG_BYTE (x));
 
Index: gcc/expmed.c
===================================================================
--- gcc/expmed.c	2017-08-21 10:42:34.185530464 +0100
+++ gcc/expmed.c	2017-08-21 14:20:43.095950879 +0100
@@ -736,7 +736,7 @@ store_bit_field_1 (rtx str_rtx, unsigned
       int byte_offset = 0;
 
       /* Paradoxical subregs need special handling on big-endian machines.  */
-      if (SUBREG_BYTE (op0) == 0 && inner_mode_size < outer_mode_size)
+      if (paradoxical_subreg_p (op0))
 	{
 	  int difference = inner_mode_size - outer_mode_size;
 
Index: gcc/final.c
===================================================================
--- gcc/final.c	2017-08-21 12:09:48.440614101 +0100
+++ gcc/final.c	2017-08-21 14:20:43.095950879 +0100
@@ -3205,8 +3205,7 @@ alter_subreg (rtx *xp, bool final_p)
 
       /* For paradoxical subregs on big-endian machines, SUBREG_BYTE
 	 contains 0 instead of the proper offset.  See simplify_subreg.  */
-      if (offset == 0
-	  && GET_MODE_SIZE (GET_MODE (y)) < GET_MODE_SIZE (GET_MODE (x)))
+      if (paradoxical_subreg_p (x))
         {
           int difference = GET_MODE_SIZE (GET_MODE (y))
 			   - GET_MODE_SIZE (GET_MODE (x));
Index: gcc/fwprop.c
===================================================================
--- gcc/fwprop.c	2017-07-13 09:25:12.152288651 +0100
+++ gcc/fwprop.c	2017-08-21 14:20:43.095950879 +0100
@@ -680,8 +680,7 @@ propagate_rtx (rtx x, machine_mode mode,
       || CONSTANT_P (new_rtx)
       || (GET_CODE (new_rtx) == SUBREG
 	  && REG_P (SUBREG_REG (new_rtx))
-	  && (GET_MODE_SIZE (mode)
-	      <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (new_rtx))))))
+	  && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (new_rtx)))))
     flags |= PR_CAN_APPEAR;
   if (!varying_mem_p (new_rtx))
     flags |= PR_HANDLE_MEM;
@@ -1103,9 +1102,7 @@ forward_propagate_subreg (df_ref use, rt
       || !REG_P (SET_DEST (def_set)))
     return false;
 
-  /* If this is a paradoxical SUBREG...  */
-  if (GET_MODE_SIZE (use_mode)
-      > GET_MODE_SIZE (GET_MODE (SUBREG_REG (use_reg))))
+  if (paradoxical_subreg_p (use_reg))
     {
       /* If this is a paradoxical SUBREG, we have no idea what value the
 	 extra bits would have.  However, if the operand is equivalent to
Index: gcc/ira-conflicts.c
===================================================================
--- gcc/ira-conflicts.c	2017-02-23 19:54:03.000000000 +0000
+++ gcc/ira-conflicts.c	2017-08-21 14:20:43.095950879 +0100
@@ -775,7 +775,7 @@ ira_build_conflicts (void)
 	     cannot be accessed in the widest mode.  */
 	  machine_mode outer_mode = ALLOCNO_WMODE (a);
 	  machine_mode inner_mode = ALLOCNO_MODE (a);
-	  if (GET_MODE_SIZE (outer_mode) > GET_MODE_SIZE (inner_mode))
+	  if (paradoxical_subreg_p (outer_mode, inner_mode))
 	    {
 	      enum reg_class aclass = ALLOCNO_CLASS (a);
 	      for (int j = ira_class_hard_regs_num[aclass] - 1; j >= 0; --j)
Index: gcc/lower-subreg.c
===================================================================
--- gcc/lower-subreg.c	2017-07-13 09:25:13.387236070 +0100
+++ gcc/lower-subreg.c	2017-08-21 14:20:43.096954323 +0100
@@ -661,10 +661,8 @@ simplify_gen_subreg_concatn (machine_mod
       if (op2 == NULL_RTX)
 	{
 	  /* We don't handle paradoxical subregs here.  */
-	  gcc_assert (GET_MODE_SIZE (outermode)
-		      <= GET_MODE_SIZE (GET_MODE (op)));
-	  gcc_assert (GET_MODE_SIZE (GET_MODE (op))
-		      <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))));
+	  gcc_assert (!paradoxical_subreg_p (outermode, GET_MODE (op)));
+	  gcc_assert (!paradoxical_subreg_p (op));
 	  op2 = simplify_subreg_concatn (outermode, SUBREG_REG (op),
 					 byte + SUBREG_BYTE (op));
 	  gcc_assert (op2 != NULL_RTX);
@@ -685,10 +683,7 @@ simplify_gen_subreg_concatn (machine_mod
      resolve_simple_move will ask for the high part of the paradoxical
      subreg, which does not have a value.  Just return a zero.  */
   if (ret == NULL_RTX
-      && GET_CODE (op) == SUBREG
-      && SUBREG_BYTE (op) == 0
-      && (GET_MODE_SIZE (innermode)
-	  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))))
+      && paradoxical_subreg_p (op))
     return CONST0_RTX (outermode);
 
   gcc_assert (ret != NULL_RTX);
Index: gcc/lra-constraints.c
===================================================================
--- gcc/lra-constraints.c	2017-08-21 10:42:34.185530464 +0100
+++ gcc/lra-constraints.c	2017-08-21 14:20:43.096954323 +0100
@@ -4225,8 +4225,7 @@ curr_insn_transform (bool check_only_p)
 		  /* Strict_low_part requires reload the register not
 		     the sub-register.	*/
 		  && (curr_static_id->operand[i].strict_low
-		      || (GET_MODE_SIZE (mode)
-			  <= GET_MODE_SIZE (GET_MODE (reg))
+		      || (!paradoxical_subreg_p (mode, GET_MODE (reg))
 			  && (hard_regno
 			      = get_try_hard_regno (REGNO (reg))) >= 0
 			  && (simplify_subreg_regno
@@ -5465,7 +5464,7 @@ split_reg (bool before_p, int original_r
 	 mode was larger than a register, just use the reg_rtx.  Otherwise,
 	 limit the size to that of the biggest access in the function.  */
       if (mode == VOIDmode
-	  || GET_MODE_SIZE (mode) > GET_MODE_SIZE (reg_rtx_mode))
+	  || paradoxical_subreg_p (mode, reg_rtx_mode))
 	{
 	  original_reg = regno_reg_rtx[hard_regno];
 	  mode = reg_rtx_mode;
Index: gcc/lra-eliminations.c
===================================================================
--- gcc/lra-eliminations.c	2017-07-05 16:29:19.599861904 +0100
+++ gcc/lra-eliminations.c	2017-08-21 14:20:43.097957767 +0100
@@ -286,8 +286,8 @@ move_plus_up (rtx x)
   subreg_reg = SUBREG_REG (x);
   x_mode = GET_MODE (x);
   subreg_reg_mode = GET_MODE (subreg_reg);
-  if (GET_CODE (x) == SUBREG && GET_CODE (subreg_reg) == PLUS
-      && GET_MODE_SIZE (x_mode) <= GET_MODE_SIZE (subreg_reg_mode)
+  if (!paradoxical_subreg_p (x)
+      && GET_CODE (subreg_reg) == PLUS
       && CONSTANT_P (XEXP (subreg_reg, 1))
       && GET_MODE_CLASS (x_mode) == MODE_INT
       && GET_MODE_CLASS (subreg_reg_mode) == MODE_INT)
@@ -605,10 +605,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rt
 
       if (new_rtx != SUBREG_REG (x))
 	{
-	  int x_size = GET_MODE_SIZE (GET_MODE (x));
-	  int new_size = GET_MODE_SIZE (GET_MODE (new_rtx));
-
-	  if (MEM_P (new_rtx) && x_size <= new_size)
+	  if (MEM_P (new_rtx) && !paradoxical_subreg_p (x))
 	    {
 	      SUBREG_REG (x) = new_rtx;
 	      alter_subreg (&x, false);
Index: gcc/recog.c
===================================================================
--- gcc/recog.c	2017-07-13 09:25:12.152288651 +0100
+++ gcc/recog.c	2017-08-21 14:20:43.097957767 +0100
@@ -1002,7 +1002,7 @@ general_operand (rtx op, machine_mode mo
 	 However, we must allow them after reload so that they can
 	 get cleaned up by cleanup_subreg_operands.  */
       if (!reload_completed && MEM_P (sub)
-	  && GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (sub)))
+	  && paradoxical_subreg_p (op))
 	return 0;
 #endif
       /* Avoid memories with nonzero SUBREG_BYTE, as offsetting the memory
@@ -1037,7 +1037,7 @@ general_operand (rtx op, machine_mode mo
 	     size of floating point mode can be less than the integer
 	     mode.  */
 	  && ! lra_in_progress 
-	  && GET_MODE_SIZE (GET_MODE (op)) > GET_MODE_SIZE (GET_MODE (sub)))
+	  && paradoxical_subreg_p (op))
 	return 0;
 
       op = sub;
Index: gcc/ree.c
===================================================================
--- gcc/ree.c	2017-02-23 19:54:20.000000000 +0000
+++ gcc/ree.c	2017-08-21 14:20:43.097957767 +0100
@@ -869,7 +869,8 @@ combine_reaching_defs (ext_cand *cand, c
 	    return false;
 
 	  for (df_link *use = uses; use; use = use->next)
-	    if (GET_MODE_PRECISION (GET_MODE (*DF_REF_LOC (use->ref))) > prec)
+	    if (paradoxical_subreg_p (GET_MODE (*DF_REF_LOC (use->ref)),
+				      GET_MODE (SET_DEST (*dest_sub_rtx))))
 	      return false;
 	}
 
Index: gcc/reload.c
===================================================================
--- gcc/reload.c	2017-08-21 10:42:34.185530464 +0100
+++ gcc/reload.c	2017-08-21 14:20:43.098961211 +0100
@@ -1062,13 +1062,12 @@ push_reload (rtx in, rtx out, rtx *inloc
 	  || (((REG_P (SUBREG_REG (in))
 		&& REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
 	       || MEM_P (SUBREG_REG (in)))
-	      && ((GET_MODE_PRECISION (inmode)
-		   > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
+	      && (paradoxical_subreg_p (inmode, GET_MODE (SUBREG_REG (in)))
 		  || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
 		      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
 			  <= UNITS_PER_WORD)
-		      && (GET_MODE_PRECISION (inmode)
-			  > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
+		      && paradoxical_subreg_p (inmode,
+					       GET_MODE (SUBREG_REG (in)))
 		      && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
 		      && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != UNKNOWN)
 		  || (WORD_REGISTER_OPERATIONS
@@ -1170,8 +1169,7 @@ push_reload (rtx in, rtx out, rtx *inloc
 	  || (((REG_P (SUBREG_REG (out))
 		&& REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
 	       || MEM_P (SUBREG_REG (out)))
-	      && ((GET_MODE_PRECISION (outmode)
-		   > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out))))
+	      && (paradoxical_subreg_p (outmode, GET_MODE (SUBREG_REG (out)))
 		  || (WORD_REGISTER_OPERATIONS
 		      && (GET_MODE_PRECISION (outmode)
 			  < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out))))
@@ -1299,7 +1297,7 @@ push_reload (rtx in, rtx out, rtx *inloc
   if (this_insn_is_asm)
     {
       machine_mode mode;
-      if (GET_MODE_SIZE (inmode) > GET_MODE_SIZE (outmode))
+      if (paradoxical_subreg_p (inmode, outmode))
 	mode = inmode;
       else
 	mode = outmode;
@@ -3137,15 +3135,15 @@ find_reloads (rtx_insn *insn, int replac
 			  && (WORD_REGISTER_OPERATIONS
 			      || ((GET_MODE_BITSIZE (GET_MODE (operand))
 				   < BIGGEST_ALIGNMENT)
-				 && (GET_MODE_SIZE (operand_mode[i])
-				     > GET_MODE_SIZE (GET_MODE (operand))))
+				  && paradoxical_subreg_p (operand_mode[i],
+							   GET_MODE (operand)))
 			      || BYTES_BIG_ENDIAN
 			      || ((GET_MODE_SIZE (operand_mode[i])
 				   <= UNITS_PER_WORD)
 				  && (GET_MODE_SIZE (GET_MODE (operand))
 				      <= UNITS_PER_WORD)
-				  && (GET_MODE_SIZE (operand_mode[i])
-				      > GET_MODE_SIZE (GET_MODE (operand)))
+				  && paradoxical_subreg_p (operand_mode[i],
+							   GET_MODE (operand))
 				  && INTEGRAL_MODE_P (GET_MODE (operand))
 				  && LOAD_EXTEND_OP (GET_MODE (operand))
 				     != UNKNOWN)))
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c	2017-08-21 10:42:34.185530464 +0100
+++ gcc/reload1.c	2017-08-21 14:20:43.099964655 +0100
@@ -3042,8 +3042,7 @@ elimination_effects (rtx x, machine_mode
 
     case SUBREG:
       if (REG_P (SUBREG_REG (x))
-	  && (GET_MODE_SIZE (GET_MODE (x))
-	      <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+	  && !paradoxical_subreg_p (x)
 	  && reg_equivs
 	  && reg_equiv_memory_loc (REGNO (SUBREG_REG (x))) != 0)
 	return;
@@ -6373,8 +6372,7 @@ compute_reload_subreg_offset (machine_mo
   /* If SUBREG is paradoxical then return the normal lowpart offset
      for OUTERMODE and INNERMODE.  Our caller has already checked
      that OUTERMODE fits in INNERMODE.  */
-  if (outer_offset == 0
-      && GET_MODE_SIZE (outermode) > GET_MODE_SIZE (middlemode))
+  if (paradoxical_subreg_p (outermode, middlemode))
     return subreg_lowpart_offset (outermode, innermode);
 
   /* SUBREG is normal, but may not be lowpart; return OUTER_OFFSET
@@ -6664,8 +6662,7 @@ choose_reload_regs (struct insn_chain *c
 				  && rld[r].out)
 			      /* Don't really use the inherited spill reg
 				 if we need it wider than we've got it.  */
-			      || (GET_MODE_SIZE (rld[r].mode)
-				  > GET_MODE_SIZE (mode))
+			      || paradoxical_subreg_p (rld[r].mode, mode)
 			      || bad_for_class
 
 			      /* If find_reloads chose reload_out as reload
Index: gcc/rtlanal.c
===================================================================
--- gcc/rtlanal.c	2017-07-13 09:25:13.516230596 +0100
+++ gcc/rtlanal.c	2017-08-21 14:20:43.101971543 +0100
@@ -3530,7 +3530,7 @@ subreg_lsb_1 (machine_mode outer_mode,
   unsigned int word;
 
   /* A paradoxical subreg begins at bit position 0.  */
-  if (GET_MODE_PRECISION (outer_mode) > GET_MODE_PRECISION (inner_mode))
+  if (paradoxical_subreg_p (outer_mode, inner_mode))
     return 0;
 
   if (WORDS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
Index: gcc/simplify-rtx.c
===================================================================
--- gcc/simplify-rtx.c	2017-08-21 10:42:34.185530464 +0100
+++ gcc/simplify-rtx.c	2017-08-21 14:20:43.102974987 +0100
@@ -1465,7 +1465,7 @@ simplify_unary_operation_1 (enum rtx_cod
       if (GET_CODE (op) == SUBREG
 	  && SUBREG_PROMOTED_VAR_P (op)
 	  && SUBREG_PROMOTED_SIGNED_P (op)
-	  && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
+	  && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
 	{
 	  temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
 	  if (temp)
@@ -1547,7 +1547,7 @@ simplify_unary_operation_1 (enum rtx_cod
       if (GET_CODE (op) == SUBREG
 	  && SUBREG_PROMOTED_VAR_P (op)
 	  && SUBREG_PROMOTED_UNSIGNED_P (op)
-	  && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
+	  && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
 	{
 	  temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
 	  if (temp)
@@ -6080,7 +6080,7 @@ simplify_subreg (machine_mode outermode,
 	}
 
       /* See whether resulting subreg will be paradoxical.  */
-      if (GET_MODE_SIZE (innermostmode) > GET_MODE_SIZE (outermode))
+      if (!paradoxical_subreg_p (outermode, innermostmode))
 	{
 	  /* In nonparadoxical subregs we can't handle negative offsets.  */
 	  if (final_offset < 0)
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c	2017-07-13 09:25:13.516230596 +0100
+++ gcc/var-tracking.c	2017-08-21 14:20:43.105985318 +0100
@@ -5295,7 +5295,7 @@ track_loc_p (rtx loc, tree expr, HOST_WI
       machine_mode pseudo_mode;
 
       pseudo_mode = PSEUDO_REGNO_MODE (ORIGINAL_REGNO (loc));
-      if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (pseudo_mode))
+      if (paradoxical_subreg_p (mode, pseudo_mode))
 	{
 	  offset += byte_lowpart_offset (pseudo_mode, mode);
 	  mode = pseudo_mode;
@@ -5309,7 +5309,7 @@ track_loc_p (rtx loc, tree expr, HOST_WI
      because the real and imaginary parts are represented as separate
      pseudo registers, even if the whole complex value fits into one
      hard register.  */
-  if ((GET_MODE_SIZE (mode) > GET_MODE_SIZE (DECL_MODE (expr))
+  if ((paradoxical_subreg_p (mode, DECL_MODE (expr))
        || (store_reg_p
 	   && !COMPLEX_MODE_P (DECL_MODE (expr))
 	   && hard_regno_nregs[REGNO (loc)][DECL_MODE (expr)] == 1))
Index: gcc/emit-rtl.c
===================================================================
--- gcc/emit-rtl.c	2017-08-03 10:40:55.518043414 +0100
+++ gcc/emit-rtl.c	2017-08-21 14:20:43.094947435 +0100
@@ -1008,10 +1008,10 @@ gen_rtvec_v (int n, rtx_insn **argp)
 byte_lowpart_offset (machine_mode outer_mode,
 		     machine_mode inner_mode)
 {
-  if (GET_MODE_SIZE (outer_mode) < GET_MODE_SIZE (inner_mode))
-    return subreg_lowpart_offset (outer_mode, inner_mode);
-  else
+  if (paradoxical_subreg_p (outer_mode, inner_mode))
     return -subreg_lowpart_offset (inner_mode, outer_mode);
+  else
+    return subreg_lowpart_offset (outer_mode, inner_mode);
 }
 \f
 /* Generate a REG rtx for a new pseudo register of mode MODE.
@@ -1552,16 +1552,6 @@ subreg_lowpart_p (const_rtx x)
   return (subreg_lowpart_offset (GET_MODE (x), GET_MODE (SUBREG_REG (x)))
 	  == SUBREG_BYTE (x));
 }
-
-/* Return true if X is a paradoxical subreg, false otherwise.  */
-bool
-paradoxical_subreg_p (const_rtx x)
-{
-  if (GET_CODE (x) != SUBREG)
-    return false;
-  return (GET_MODE_PRECISION (GET_MODE (x))
-	  > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (x))));
-}
 \f
 /* Return subword OFFSET of operand OP.
    The word number, OFFSET, is interpreted as the word number starting

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Make more use of paradoxical_subreg_p
  2017-08-21 14:16 Make more use of paradoxical_subreg_p Richard Sandiford
@ 2017-08-22 11:13 ` Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2017-08-22 11:13 UTC (permalink / raw)
  To: GCC Patches, Richard Sandiford

On Mon, Aug 21, 2017 at 3:31 PM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> This patch makes more use of the existing paradoxical_subreg_p
> predicate and also adds a version that operates on outer and
> inner modes.
>
> Some of the affected tests were based on GET_MODE_SIZE rather than
> GET_MODE_PRECISION and so the patch could change the result for modes
> that have the same size but different precisions.  I think in each
> case the change should be a no-op or more correct, since a mode with
> precision N bits can't be expected to hold all of a mode with precision
> M>N bits.
>
> The patch changes the branch taken in simplify_subreg for modes with
> equal precision, but the new form matches the commentary more closely.
> Both branches should be equally good in that situation.
>
> Tested on aarch64-linux-gnu and x86_64-linux-gnu, and by checking that
> there were no changes in the testsuite assembly output for one target
> per CPU.  OK to install?

Ok.

Thanks
Richard.

> Richard
>
>
> 2017-08-21  Richard Sandiford  <richard.sandiford@linaro.org>
>             Alan Hayward  <alan.hayward@arm.com>
>             David Sherwood  <david.sherwood@arm.com>
>
> gcc/
>         * rtl.h (paradoxical_subreg_p): Define inline, and add a version
>         that takes the outer and inner modes.
>         * doc/rtl.texi: Use paradoxical_subreg_p instead of a GET_MODE_SIZE
>         comparison as the canonical test for a paradoxical subreg.
>         * combine.c (simplify_set): Use paradoxical_subreg_p.
>         (make_extraction): Likewise.
>         (force_to_mode): Likewise.
>         (rtx_equal_for_field_assignment_p): Likewise.
>         (gen_lowpart_for_combine): Likewise.
>         (simplify_comparison): Likewise.
>         * cse.c (equiv_constant): Likewise.
>         * expmed.c (store_bit_field_1): Likewise.
>         * final.c (alter_subreg): Likewise.
>         * fwprop.c (propagate_rtx): Likewise.
>         (forward_propagate_subreg): Likewise.
>         * ira-conflicts.c (ira_build_conflicts): Likewise.
>         * lower-subreg.c (simplify_gen_subreg_concatn): Likewise.
>         * lra-constraints.c (curr_insn_transform): Likewise.
>         (split_reg): Likewise.
>         * lra-eliminations.c (move_plus_up): Likewise.
>         (lra_eliminate_regs_1): Likewise.
>         * recog.c (general_operand): Likewise.
>         * ree.c (combine_reaching_defs): Likewise.
>         * reload.c (push_reload): Likewise.
>         (find_reloads): Likewise.
>         * reload1.c (elimination_effects): Likewise.
>         (compute_reload_subreg_offset): Likewise.
>         (choose_reload_regs): Likewise.
>         * rtlanal.c (subreg_lsb_1): Likewise.
>         * simplify-rtx.c (simplify_unary_operation_1): Likewise.
>         (simplify_subreg): Likewise.
>         * var-tracking.c (track_loc_p): Likewise.
>         * emit-rtl.c (byte_lowpart_offset): Likewise.
>         (paradoxical_subreg_p): Delete out-of-line definition.
>
> Index: gcc/rtl.h
> ===================================================================
> --- gcc/rtl.h   2017-08-21 10:42:34.185530464 +0100
> +++ gcc/rtl.h   2017-08-21 14:20:43.099964655 +0100
> @@ -2784,10 +2784,28 @@ extern rtx operand_subword (rtx, unsigne
>
>  /* In emit-rtl.c */
>  extern rtx operand_subword_force (rtx, unsigned int, machine_mode);
> -extern bool paradoxical_subreg_p (const_rtx);
>  extern int subreg_lowpart_p (const_rtx);
>  extern unsigned int subreg_size_lowpart_offset (unsigned int, unsigned int);
>
> +/* Return true if a subreg with the given outer and inner modes is
> +   paradoxical.  */
> +
> +inline bool
> +paradoxical_subreg_p (machine_mode outermode, machine_mode innermode)
> +{
> +  return GET_MODE_PRECISION (outermode) > GET_MODE_PRECISION (innermode);
> +}
> +
> +/* Return true if X is a paradoxical subreg, false otherwise.  */
> +
> +inline bool
> +paradoxical_subreg_p (const_rtx x)
> +{
> +  if (GET_CODE (x) != SUBREG)
> +    return false;
> +  return paradoxical_subreg_p (GET_MODE (x), GET_MODE (SUBREG_REG (x)));
> +}
> +
>  /* Return the SUBREG_BYTE for an OUTERMODE lowpart of an INNERMODE value.  */
>
>  inline unsigned int
> Index: gcc/doc/rtl.texi
> ===================================================================
> --- gcc/doc/rtl.texi    2017-07-27 10:37:54.486030028 +0100
> +++ gcc/doc/rtl.texi    2017-08-21 14:20:43.094947435 +0100
> @@ -1872,7 +1872,7 @@ expression is called @dfn{paradoxical}.
>  class of @code{subreg} is:
>
>  @smallexample
> -GET_MODE_SIZE (@var{m1}) > GET_MODE_SIZE (@var{m2})
> +paradoxical_subreg_p (@var{m1}, @var{m2})
>  @end smallexample
>
>  Paradoxical @code{subreg}s can be used as both lvalues and rvalues.
> Index: gcc/combine.c
> ===================================================================
> --- gcc/combine.c       2017-08-21 10:42:34.185530464 +0100
> +++ gcc/combine.c       2017-08-21 14:20:43.092940547 +0100
> @@ -6809,9 +6809,7 @@ simplify_set (rtx x)
>            / UNITS_PER_WORD)
>           == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))
>                + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
> -      && (WORD_REGISTER_OPERATIONS
> -         || (GET_MODE_SIZE (GET_MODE (src))
> -             <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))))
> +      && (WORD_REGISTER_OPERATIONS || !paradoxical_subreg_p (src))
>  #ifdef CANNOT_CHANGE_MODE_CLASS
>        && ! (REG_P (dest) && REGNO (dest) < FIRST_PSEUDO_REGISTER
>             && REG_CANNOT_CHANGE_MODE_P (REGNO (dest),
> @@ -7456,7 +7454,7 @@ make_extraction (machine_mode mode, rtx
>                      : BITS_PER_UNIT)) == 0
>               /* We can't do this if we are widening INNER_MODE (it
>                  may not be aligned, for one thing).  */
> -             && GET_MODE_PRECISION (inner_mode) >= GET_MODE_PRECISION (tmode)
> +             && !paradoxical_subreg_p (tmode, inner_mode)
>               && (inner_mode == tmode
>                   || (! mode_dependent_address_p (XEXP (inner, 0),
>                                                   MEM_ADDR_SPACE (inner))
> @@ -7669,7 +7667,7 @@ make_extraction (machine_mode mode, rtx
>        /* If bytes are big endian and we had a paradoxical SUBREG, we must
>          adjust OFFSET to compensate.  */
>        if (BYTES_BIG_ENDIAN
> -         && GET_MODE_SIZE (inner_mode) < GET_MODE_SIZE (is_mode))
> +         && paradoxical_subreg_p (is_mode, inner_mode))
>         offset -= GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (inner_mode);
>
>        /* We can now move to the desired byte.  */
> @@ -8529,7 +8527,7 @@ force_to_mode (rtx x, machine_mode mode,
>
>    /* If X is narrower than MODE and we want all the bits in X's mode, just
>       get X in the proper mode.  */
> -  if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode)
> +  if (paradoxical_subreg_p (mode, GET_MODE (x))
>        && (GET_MODE_MASK (GET_MODE (x)) & ~mask) == 0)
>      return gen_lowpart (mode, x);
>
> @@ -9408,7 +9406,7 @@ rtx_equal_for_field_assignment_p (rtx x,
>  {
>    if (widen_x && GET_MODE (x) != GET_MODE (y))
>      {
> -      if (GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (y)))
> +      if (paradoxical_subreg_p (GET_MODE (x), GET_MODE (y)))
>         return 0;
>        if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
>         return 0;
> @@ -11488,7 +11486,7 @@ gen_lowpart_for_combine (machine_mode om
>        /* If we want to refer to something bigger than the original memref,
>          generate a paradoxical subreg instead.  That will force a reload
>          of the original memref X.  */
> -      if (isize < osize)
> +      if (paradoxical_subreg_p (omode, imode))
>         return gen_rtx_SUBREG (omode, x, 0);
>
>        if (WORDS_BIG_ENDIAN)
> @@ -12145,8 +12143,7 @@ simplify_comparison (enum rtx_code code,
>
>           /* If the inner mode is narrower and we are extracting the low part,
>              we can treat the SUBREG as if it were a ZERO_EXTEND.  */
> -         if (subreg_lowpart_p (op0)
> -             && GET_MODE_PRECISION (GET_MODE (SUBREG_REG (op0))) < mode_width)
> +         if (paradoxical_subreg_p (op0))
>             ;
>           else if (subreg_lowpart_p (op0)
>                    && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
> Index: gcc/cse.c
> ===================================================================
> --- gcc/cse.c   2017-08-21 10:42:34.185530464 +0100
> +++ gcc/cse.c   2017-08-21 14:20:43.093943991 +0100
> @@ -3802,7 +3802,7 @@ equiv_constant (rtx x)
>          the subreg.  Note that the upper bits of paradoxical subregs
>          are undefined, so they cannot be said to equal anything.  */
>        if (REG_P (SUBREG_REG (x))
> -         && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (imode)
> +         && !paradoxical_subreg_p (x)
>           && (new_rtx = equiv_constant (SUBREG_REG (x))) != 0)
>          return simplify_subreg (mode, new_rtx, imode, SUBREG_BYTE (x));
>
> Index: gcc/expmed.c
> ===================================================================
> --- gcc/expmed.c        2017-08-21 10:42:34.185530464 +0100
> +++ gcc/expmed.c        2017-08-21 14:20:43.095950879 +0100
> @@ -736,7 +736,7 @@ store_bit_field_1 (rtx str_rtx, unsigned
>        int byte_offset = 0;
>
>        /* Paradoxical subregs need special handling on big-endian machines.  */
> -      if (SUBREG_BYTE (op0) == 0 && inner_mode_size < outer_mode_size)
> +      if (paradoxical_subreg_p (op0))
>         {
>           int difference = inner_mode_size - outer_mode_size;
>
> Index: gcc/final.c
> ===================================================================
> --- gcc/final.c 2017-08-21 12:09:48.440614101 +0100
> +++ gcc/final.c 2017-08-21 14:20:43.095950879 +0100
> @@ -3205,8 +3205,7 @@ alter_subreg (rtx *xp, bool final_p)
>
>        /* For paradoxical subregs on big-endian machines, SUBREG_BYTE
>          contains 0 instead of the proper offset.  See simplify_subreg.  */
> -      if (offset == 0
> -         && GET_MODE_SIZE (GET_MODE (y)) < GET_MODE_SIZE (GET_MODE (x)))
> +      if (paradoxical_subreg_p (x))
>          {
>            int difference = GET_MODE_SIZE (GET_MODE (y))
>                            - GET_MODE_SIZE (GET_MODE (x));
> Index: gcc/fwprop.c
> ===================================================================
> --- gcc/fwprop.c        2017-07-13 09:25:12.152288651 +0100
> +++ gcc/fwprop.c        2017-08-21 14:20:43.095950879 +0100
> @@ -680,8 +680,7 @@ propagate_rtx (rtx x, machine_mode mode,
>        || CONSTANT_P (new_rtx)
>        || (GET_CODE (new_rtx) == SUBREG
>           && REG_P (SUBREG_REG (new_rtx))
> -         && (GET_MODE_SIZE (mode)
> -             <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (new_rtx))))))
> +         && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (new_rtx)))))
>      flags |= PR_CAN_APPEAR;
>    if (!varying_mem_p (new_rtx))
>      flags |= PR_HANDLE_MEM;
> @@ -1103,9 +1102,7 @@ forward_propagate_subreg (df_ref use, rt
>        || !REG_P (SET_DEST (def_set)))
>      return false;
>
> -  /* If this is a paradoxical SUBREG...  */
> -  if (GET_MODE_SIZE (use_mode)
> -      > GET_MODE_SIZE (GET_MODE (SUBREG_REG (use_reg))))
> +  if (paradoxical_subreg_p (use_reg))
>      {
>        /* If this is a paradoxical SUBREG, we have no idea what value the
>          extra bits would have.  However, if the operand is equivalent to
> Index: gcc/ira-conflicts.c
> ===================================================================
> --- gcc/ira-conflicts.c 2017-02-23 19:54:03.000000000 +0000
> +++ gcc/ira-conflicts.c 2017-08-21 14:20:43.095950879 +0100
> @@ -775,7 +775,7 @@ ira_build_conflicts (void)
>              cannot be accessed in the widest mode.  */
>           machine_mode outer_mode = ALLOCNO_WMODE (a);
>           machine_mode inner_mode = ALLOCNO_MODE (a);
> -         if (GET_MODE_SIZE (outer_mode) > GET_MODE_SIZE (inner_mode))
> +         if (paradoxical_subreg_p (outer_mode, inner_mode))
>             {
>               enum reg_class aclass = ALLOCNO_CLASS (a);
>               for (int j = ira_class_hard_regs_num[aclass] - 1; j >= 0; --j)
> Index: gcc/lower-subreg.c
> ===================================================================
> --- gcc/lower-subreg.c  2017-07-13 09:25:13.387236070 +0100
> +++ gcc/lower-subreg.c  2017-08-21 14:20:43.096954323 +0100
> @@ -661,10 +661,8 @@ simplify_gen_subreg_concatn (machine_mod
>        if (op2 == NULL_RTX)
>         {
>           /* We don't handle paradoxical subregs here.  */
> -         gcc_assert (GET_MODE_SIZE (outermode)
> -                     <= GET_MODE_SIZE (GET_MODE (op)));
> -         gcc_assert (GET_MODE_SIZE (GET_MODE (op))
> -                     <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))));
> +         gcc_assert (!paradoxical_subreg_p (outermode, GET_MODE (op)));
> +         gcc_assert (!paradoxical_subreg_p (op));
>           op2 = simplify_subreg_concatn (outermode, SUBREG_REG (op),
>                                          byte + SUBREG_BYTE (op));
>           gcc_assert (op2 != NULL_RTX);
> @@ -685,10 +683,7 @@ simplify_gen_subreg_concatn (machine_mod
>       resolve_simple_move will ask for the high part of the paradoxical
>       subreg, which does not have a value.  Just return a zero.  */
>    if (ret == NULL_RTX
> -      && GET_CODE (op) == SUBREG
> -      && SUBREG_BYTE (op) == 0
> -      && (GET_MODE_SIZE (innermode)
> -         > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))))
> +      && paradoxical_subreg_p (op))
>      return CONST0_RTX (outermode);
>
>    gcc_assert (ret != NULL_RTX);
> Index: gcc/lra-constraints.c
> ===================================================================
> --- gcc/lra-constraints.c       2017-08-21 10:42:34.185530464 +0100
> +++ gcc/lra-constraints.c       2017-08-21 14:20:43.096954323 +0100
> @@ -4225,8 +4225,7 @@ curr_insn_transform (bool check_only_p)
>                   /* Strict_low_part requires reload the register not
>                      the sub-register.  */
>                   && (curr_static_id->operand[i].strict_low
> -                     || (GET_MODE_SIZE (mode)
> -                         <= GET_MODE_SIZE (GET_MODE (reg))
> +                     || (!paradoxical_subreg_p (mode, GET_MODE (reg))
>                           && (hard_regno
>                               = get_try_hard_regno (REGNO (reg))) >= 0
>                           && (simplify_subreg_regno
> @@ -5465,7 +5464,7 @@ split_reg (bool before_p, int original_r
>          mode was larger than a register, just use the reg_rtx.  Otherwise,
>          limit the size to that of the biggest access in the function.  */
>        if (mode == VOIDmode
> -         || GET_MODE_SIZE (mode) > GET_MODE_SIZE (reg_rtx_mode))
> +         || paradoxical_subreg_p (mode, reg_rtx_mode))
>         {
>           original_reg = regno_reg_rtx[hard_regno];
>           mode = reg_rtx_mode;
> Index: gcc/lra-eliminations.c
> ===================================================================
> --- gcc/lra-eliminations.c      2017-07-05 16:29:19.599861904 +0100
> +++ gcc/lra-eliminations.c      2017-08-21 14:20:43.097957767 +0100
> @@ -286,8 +286,8 @@ move_plus_up (rtx x)
>    subreg_reg = SUBREG_REG (x);
>    x_mode = GET_MODE (x);
>    subreg_reg_mode = GET_MODE (subreg_reg);
> -  if (GET_CODE (x) == SUBREG && GET_CODE (subreg_reg) == PLUS
> -      && GET_MODE_SIZE (x_mode) <= GET_MODE_SIZE (subreg_reg_mode)
> +  if (!paradoxical_subreg_p (x)
> +      && GET_CODE (subreg_reg) == PLUS
>        && CONSTANT_P (XEXP (subreg_reg, 1))
>        && GET_MODE_CLASS (x_mode) == MODE_INT
>        && GET_MODE_CLASS (subreg_reg_mode) == MODE_INT)
> @@ -605,10 +605,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rt
>
>        if (new_rtx != SUBREG_REG (x))
>         {
> -         int x_size = GET_MODE_SIZE (GET_MODE (x));
> -         int new_size = GET_MODE_SIZE (GET_MODE (new_rtx));
> -
> -         if (MEM_P (new_rtx) && x_size <= new_size)
> +         if (MEM_P (new_rtx) && !paradoxical_subreg_p (x))
>             {
>               SUBREG_REG (x) = new_rtx;
>               alter_subreg (&x, false);
> Index: gcc/recog.c
> ===================================================================
> --- gcc/recog.c 2017-07-13 09:25:12.152288651 +0100
> +++ gcc/recog.c 2017-08-21 14:20:43.097957767 +0100
> @@ -1002,7 +1002,7 @@ general_operand (rtx op, machine_mode mo
>          However, we must allow them after reload so that they can
>          get cleaned up by cleanup_subreg_operands.  */
>        if (!reload_completed && MEM_P (sub)
> -         && GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (sub)))
> +         && paradoxical_subreg_p (op))
>         return 0;
>  #endif
>        /* Avoid memories with nonzero SUBREG_BYTE, as offsetting the memory
> @@ -1037,7 +1037,7 @@ general_operand (rtx op, machine_mode mo
>              size of floating point mode can be less than the integer
>              mode.  */
>           && ! lra_in_progress
> -         && GET_MODE_SIZE (GET_MODE (op)) > GET_MODE_SIZE (GET_MODE (sub)))
> +         && paradoxical_subreg_p (op))
>         return 0;
>
>        op = sub;
> Index: gcc/ree.c
> ===================================================================
> --- gcc/ree.c   2017-02-23 19:54:20.000000000 +0000
> +++ gcc/ree.c   2017-08-21 14:20:43.097957767 +0100
> @@ -869,7 +869,8 @@ combine_reaching_defs (ext_cand *cand, c
>             return false;
>
>           for (df_link *use = uses; use; use = use->next)
> -           if (GET_MODE_PRECISION (GET_MODE (*DF_REF_LOC (use->ref))) > prec)
> +           if (paradoxical_subreg_p (GET_MODE (*DF_REF_LOC (use->ref)),
> +                                     GET_MODE (SET_DEST (*dest_sub_rtx))))
>               return false;
>         }
>
> Index: gcc/reload.c
> ===================================================================
> --- gcc/reload.c        2017-08-21 10:42:34.185530464 +0100
> +++ gcc/reload.c        2017-08-21 14:20:43.098961211 +0100
> @@ -1062,13 +1062,12 @@ push_reload (rtx in, rtx out, rtx *inloc
>           || (((REG_P (SUBREG_REG (in))
>                 && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
>                || MEM_P (SUBREG_REG (in)))
> -             && ((GET_MODE_PRECISION (inmode)
> -                  > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
> +             && (paradoxical_subreg_p (inmode, GET_MODE (SUBREG_REG (in)))
>                   || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
>                       && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
>                           <= UNITS_PER_WORD)
> -                     && (GET_MODE_PRECISION (inmode)
> -                         > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
> +                     && paradoxical_subreg_p (inmode,
> +                                              GET_MODE (SUBREG_REG (in)))
>                       && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
>                       && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != UNKNOWN)
>                   || (WORD_REGISTER_OPERATIONS
> @@ -1170,8 +1169,7 @@ push_reload (rtx in, rtx out, rtx *inloc
>           || (((REG_P (SUBREG_REG (out))
>                 && REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
>                || MEM_P (SUBREG_REG (out)))
> -             && ((GET_MODE_PRECISION (outmode)
> -                  > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out))))
> +             && (paradoxical_subreg_p (outmode, GET_MODE (SUBREG_REG (out)))
>                   || (WORD_REGISTER_OPERATIONS
>                       && (GET_MODE_PRECISION (outmode)
>                           < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out))))
> @@ -1299,7 +1297,7 @@ push_reload (rtx in, rtx out, rtx *inloc
>    if (this_insn_is_asm)
>      {
>        machine_mode mode;
> -      if (GET_MODE_SIZE (inmode) > GET_MODE_SIZE (outmode))
> +      if (paradoxical_subreg_p (inmode, outmode))
>         mode = inmode;
>        else
>         mode = outmode;
> @@ -3137,15 +3135,15 @@ find_reloads (rtx_insn *insn, int replac
>                           && (WORD_REGISTER_OPERATIONS
>                               || ((GET_MODE_BITSIZE (GET_MODE (operand))
>                                    < BIGGEST_ALIGNMENT)
> -                                && (GET_MODE_SIZE (operand_mode[i])
> -                                    > GET_MODE_SIZE (GET_MODE (operand))))
> +                                 && paradoxical_subreg_p (operand_mode[i],
> +                                                          GET_MODE (operand)))
>                               || BYTES_BIG_ENDIAN
>                               || ((GET_MODE_SIZE (operand_mode[i])
>                                    <= UNITS_PER_WORD)
>                                   && (GET_MODE_SIZE (GET_MODE (operand))
>                                       <= UNITS_PER_WORD)
> -                                 && (GET_MODE_SIZE (operand_mode[i])
> -                                     > GET_MODE_SIZE (GET_MODE (operand)))
> +                                 && paradoxical_subreg_p (operand_mode[i],
> +                                                          GET_MODE (operand))
>                                   && INTEGRAL_MODE_P (GET_MODE (operand))
>                                   && LOAD_EXTEND_OP (GET_MODE (operand))
>                                      != UNKNOWN)))
> Index: gcc/reload1.c
> ===================================================================
> --- gcc/reload1.c       2017-08-21 10:42:34.185530464 +0100
> +++ gcc/reload1.c       2017-08-21 14:20:43.099964655 +0100
> @@ -3042,8 +3042,7 @@ elimination_effects (rtx x, machine_mode
>
>      case SUBREG:
>        if (REG_P (SUBREG_REG (x))
> -         && (GET_MODE_SIZE (GET_MODE (x))
> -             <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
> +         && !paradoxical_subreg_p (x)
>           && reg_equivs
>           && reg_equiv_memory_loc (REGNO (SUBREG_REG (x))) != 0)
>         return;
> @@ -6373,8 +6372,7 @@ compute_reload_subreg_offset (machine_mo
>    /* If SUBREG is paradoxical then return the normal lowpart offset
>       for OUTERMODE and INNERMODE.  Our caller has already checked
>       that OUTERMODE fits in INNERMODE.  */
> -  if (outer_offset == 0
> -      && GET_MODE_SIZE (outermode) > GET_MODE_SIZE (middlemode))
> +  if (paradoxical_subreg_p (outermode, middlemode))
>      return subreg_lowpart_offset (outermode, innermode);
>
>    /* SUBREG is normal, but may not be lowpart; return OUTER_OFFSET
> @@ -6664,8 +6662,7 @@ choose_reload_regs (struct insn_chain *c
>                                   && rld[r].out)
>                               /* Don't really use the inherited spill reg
>                                  if we need it wider than we've got it.  */
> -                             || (GET_MODE_SIZE (rld[r].mode)
> -                                 > GET_MODE_SIZE (mode))
> +                             || paradoxical_subreg_p (rld[r].mode, mode)
>                               || bad_for_class
>
>                               /* If find_reloads chose reload_out as reload
> Index: gcc/rtlanal.c
> ===================================================================
> --- gcc/rtlanal.c       2017-07-13 09:25:13.516230596 +0100
> +++ gcc/rtlanal.c       2017-08-21 14:20:43.101971543 +0100
> @@ -3530,7 +3530,7 @@ subreg_lsb_1 (machine_mode outer_mode,
>    unsigned int word;
>
>    /* A paradoxical subreg begins at bit position 0.  */
> -  if (GET_MODE_PRECISION (outer_mode) > GET_MODE_PRECISION (inner_mode))
> +  if (paradoxical_subreg_p (outer_mode, inner_mode))
>      return 0;
>
>    if (WORDS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
> Index: gcc/simplify-rtx.c
> ===================================================================
> --- gcc/simplify-rtx.c  2017-08-21 10:42:34.185530464 +0100
> +++ gcc/simplify-rtx.c  2017-08-21 14:20:43.102974987 +0100
> @@ -1465,7 +1465,7 @@ simplify_unary_operation_1 (enum rtx_cod
>        if (GET_CODE (op) == SUBREG
>           && SUBREG_PROMOTED_VAR_P (op)
>           && SUBREG_PROMOTED_SIGNED_P (op)
> -         && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
> +         && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
>         {
>           temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
>           if (temp)
> @@ -1547,7 +1547,7 @@ simplify_unary_operation_1 (enum rtx_cod
>        if (GET_CODE (op) == SUBREG
>           && SUBREG_PROMOTED_VAR_P (op)
>           && SUBREG_PROMOTED_UNSIGNED_P (op)
> -         && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
> +         && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
>         {
>           temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
>           if (temp)
> @@ -6080,7 +6080,7 @@ simplify_subreg (machine_mode outermode,
>         }
>
>        /* See whether resulting subreg will be paradoxical.  */
> -      if (GET_MODE_SIZE (innermostmode) > GET_MODE_SIZE (outermode))
> +      if (!paradoxical_subreg_p (outermode, innermostmode))
>         {
>           /* In nonparadoxical subregs we can't handle negative offsets.  */
>           if (final_offset < 0)
> Index: gcc/var-tracking.c
> ===================================================================
> --- gcc/var-tracking.c  2017-07-13 09:25:13.516230596 +0100
> +++ gcc/var-tracking.c  2017-08-21 14:20:43.105985318 +0100
> @@ -5295,7 +5295,7 @@ track_loc_p (rtx loc, tree expr, HOST_WI
>        machine_mode pseudo_mode;
>
>        pseudo_mode = PSEUDO_REGNO_MODE (ORIGINAL_REGNO (loc));
> -      if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (pseudo_mode))
> +      if (paradoxical_subreg_p (mode, pseudo_mode))
>         {
>           offset += byte_lowpart_offset (pseudo_mode, mode);
>           mode = pseudo_mode;
> @@ -5309,7 +5309,7 @@ track_loc_p (rtx loc, tree expr, HOST_WI
>       because the real and imaginary parts are represented as separate
>       pseudo registers, even if the whole complex value fits into one
>       hard register.  */
> -  if ((GET_MODE_SIZE (mode) > GET_MODE_SIZE (DECL_MODE (expr))
> +  if ((paradoxical_subreg_p (mode, DECL_MODE (expr))
>         || (store_reg_p
>            && !COMPLEX_MODE_P (DECL_MODE (expr))
>            && hard_regno_nregs[REGNO (loc)][DECL_MODE (expr)] == 1))
> Index: gcc/emit-rtl.c
> ===================================================================
> --- gcc/emit-rtl.c      2017-08-03 10:40:55.518043414 +0100
> +++ gcc/emit-rtl.c      2017-08-21 14:20:43.094947435 +0100
> @@ -1008,10 +1008,10 @@ gen_rtvec_v (int n, rtx_insn **argp)
>  byte_lowpart_offset (machine_mode outer_mode,
>                      machine_mode inner_mode)
>  {
> -  if (GET_MODE_SIZE (outer_mode) < GET_MODE_SIZE (inner_mode))
> -    return subreg_lowpart_offset (outer_mode, inner_mode);
> -  else
> +  if (paradoxical_subreg_p (outer_mode, inner_mode))
>      return -subreg_lowpart_offset (inner_mode, outer_mode);
> +  else
> +    return subreg_lowpart_offset (outer_mode, inner_mode);
>  }
>
>  /* Generate a REG rtx for a new pseudo register of mode MODE.
> @@ -1552,16 +1552,6 @@ subreg_lowpart_p (const_rtx x)
>    return (subreg_lowpart_offset (GET_MODE (x), GET_MODE (SUBREG_REG (x)))
>           == SUBREG_BYTE (x));
>  }
> -
> -/* Return true if X is a paradoxical subreg, false otherwise.  */
> -bool
> -paradoxical_subreg_p (const_rtx x)
> -{
> -  if (GET_CODE (x) != SUBREG)
> -    return false;
> -  return (GET_MODE_PRECISION (GET_MODE (x))
> -         > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (x))));
> -}
>
>  /* Return subword OFFSET of operand OP.
>     The word number, OFFSET, is interpreted as the word number starting

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2017-08-22 10:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-21 14:16 Make more use of paradoxical_subreg_p Richard Sandiford
2017-08-22 11:13 ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).