public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-3252] Preserve SUBREG_PROMOTED_VAR_P on (extend:HI (subreg/s:QI (reg:SI))).
@ 2021-08-31 10:46 Roger Sayle
  0 siblings, 0 replies; only message in thread
From: Roger Sayle @ 2021-08-31 10:46 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:cad36f38576a6a781e3c62ab061c68f5b8dab13a

commit r12-3252-gcad36f38576a6a781e3c62ab061c68f5b8dab13a
Author: Roger Sayle <roger@nextmovesoftware.com>
Date:   Tue Aug 31 11:45:07 2021 +0100

    Preserve SUBREG_PROMOTED_VAR_P on (extend:HI (subreg/s:QI (reg:SI))).
    
    SUBREG_PROMOTED_VAR_P is a mechanism for tracking that a partial subreg
    is correctly zero-extended or sign-extended in the parent register.  For
    example, the RTL (subreg/s/v:QI (reg/v:SI 23 [ x ]) 0) indicates that the
    byte x is zero extended in reg:SI 23, which is useful for optimization.
    An example is that zero extending the above QImode value to HImode can
    simply use a wider subreg, i.e. (subreg:HI (reg/v:SI 23 [ x ]) 0).
    
    This patch addresses the oversight/missed optimization opportunity that
    the new HImode subreg above should retain its SUBREG_PROMOTED_VAR_P
    annotation as its value is guaranteed to be correctly extended in the
    SImode parent.  The code below to preserve SUBREG_PROMOTED_VAR_P is already
    present in the middle-end (e.g. simplify-rtx.c:7232-7242) but missing
    from one or two (precisely three) places that (accidentally) strip it.
    
    Whilst there I also added another optimization.  If we need to extend
    the above QImode value beyond the SImode register holding it, say to
    DImode, we can eliminate the SUBREG and simply extend from the SImode
    register to DImode.
    
    2021-08-31  Roger Sayle  <roger@nextmovesoftware.com>
    
    gcc/ChangeLog
            * expr.c (convert_modes): Preserve SUBREG_PROMOTED_VAR_P when
            creating a (wider) partial subreg from a SUBREG_PROMOTED_VAR_P
            subreg.
            * simplify-rtx.c (simplify_unary_operation_1) [SIGN_EXTEND]:
            Likewise, preserve SUBREG_PROMOTED_VAR_P when creating a (wider)
            partial subreg from a SUBREG_PROMOTED_VAR_P subreg.  Generate
            SIGN_EXTEND of the SUBREG_REG when a subreg would be paradoxical.
            [ZERO_EXTEND]: Likewise, preserve SUBREG_PROMOTED_VAR_P when
            creating a (wider) partial subreg from a SUBREG_PROMOTED_VAR_P
            subreg.  Generate ZERO_EXTEND of the SUBREG_REG when a subreg
            would be paradoxical.

Diff:
---
 gcc/expr.c         | 19 ++++++++++++++++++-
 gcc/simplify-rtx.c | 52 ++++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/gcc/expr.c b/gcc/expr.c
index 096c0315ecc..5dd98a9bccc 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -688,7 +688,24 @@ convert_modes (machine_mode mode, machine_mode oldmode, rtx x, int unsignedp)
       && (GET_MODE_PRECISION (subreg_promoted_mode (x))
 	  >= GET_MODE_PRECISION (int_mode))
       && SUBREG_CHECK_PROMOTED_SIGN (x, unsignedp))
-    x = gen_lowpart (int_mode, SUBREG_REG (x));
+    {
+      scalar_int_mode int_orig_mode;
+      machine_mode orig_mode = GET_MODE (x);
+      x = gen_lowpart (int_mode, SUBREG_REG (x));
+
+      /* Preserve SUBREG_PROMOTED_VAR_P if the new mode is wider than
+	 the original mode, but narrower than the inner mode.  */
+      if (GET_CODE (x) == SUBREG
+	  && GET_MODE_PRECISION (subreg_promoted_mode (x))
+	     > GET_MODE_PRECISION (int_mode)
+	  && is_a <scalar_int_mode> (orig_mode, &int_orig_mode)
+	  && GET_MODE_PRECISION (int_mode)
+	     > GET_MODE_PRECISION (int_orig_mode))
+	{
+	  SUBREG_PROMOTED_VAR_P (x) = 1;
+	  SUBREG_PROMOTED_SET (x, unsignedp);
+	}
+    }
 
   if (GET_MODE (x) != VOIDmode)
     oldmode = GET_MODE (x);
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index e431e0c19d7..ebad5cb5a79 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -1512,12 +1512,28 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
 	 target mode is the same as the variable's promotion.  */
       if (GET_CODE (op) == SUBREG
 	  && SUBREG_PROMOTED_VAR_P (op)
-	  && SUBREG_PROMOTED_SIGNED_P (op)
-	  && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
+	  && SUBREG_PROMOTED_SIGNED_P (op))
 	{
-	  temp = rtl_hooks.gen_lowpart_no_emit (mode, SUBREG_REG (op));
-	  if (temp)
-	    return temp;
+	  rtx subreg = SUBREG_REG (op);
+	  machine_mode subreg_mode = GET_MODE (subreg);
+	  if (!paradoxical_subreg_p (mode, subreg_mode))
+	    {
+	      temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
+	      if (temp)
+		{
+		  /* Preserve SUBREG_PROMOTED_VAR_P.  */
+		  if (partial_subreg_p (temp))
+		    {
+		      SUBREG_PROMOTED_VAR_P (temp) = 1;
+		      SUBREG_PROMOTED_SET (temp, 1);
+		    }
+		  return temp;
+		}
+	    }
+	  else
+	    /* Sign-extending a sign-extended subreg.  */
+	    return simplify_gen_unary (SIGN_EXTEND, mode,
+				       subreg, subreg_mode);
 	}
 
       /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
@@ -1631,12 +1647,28 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
 	 target mode is the same as the variable's promotion.  */
       if (GET_CODE (op) == SUBREG
 	  && SUBREG_PROMOTED_VAR_P (op)
-	  && SUBREG_PROMOTED_UNSIGNED_P (op)
-	  && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
+	  && SUBREG_PROMOTED_UNSIGNED_P (op))
 	{
-	  temp = rtl_hooks.gen_lowpart_no_emit (mode, SUBREG_REG (op));
-	  if (temp)
-	    return temp;
+	  rtx subreg = SUBREG_REG (op);
+	  machine_mode subreg_mode = GET_MODE (subreg);
+	  if (!paradoxical_subreg_p (mode, subreg_mode))
+	    {
+	      temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
+	      if (temp)
+		{
+		  /* Preserve SUBREG_PROMOTED_VAR_P.  */
+		  if (partial_subreg_p (temp))
+		    {
+		      SUBREG_PROMOTED_VAR_P (temp) = 1;
+		      SUBREG_PROMOTED_SET (temp, 0);
+		    }
+		  return temp;
+		}
+	    }
+	  else
+	    /* Zero-extending a zero-extended subreg.  */
+	    return simplify_gen_unary (ZERO_EXTEND, mode,
+				       subreg, subreg_mode);
 	}
 
       /* Extending a widening multiplication should be canonicalized to


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-08-31 10:46 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-31 10:46 [gcc r12-3252] Preserve SUBREG_PROMOTED_VAR_P on (extend:HI (subreg/s:QI (reg:SI))) Roger Sayle

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).