public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-1586] Add RTX codes for BITREVERSE and COPYSIGN.
@ 2023-06-06 23:34 Roger Sayle
  0 siblings, 0 replies; only message in thread
From: Roger Sayle @ 2023-06-06 23:34 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:6160572f8d243cb613ee0290fdc8580f1761d805

commit r14-1586-g6160572f8d243cb613ee0290fdc8580f1761d805
Author: Roger Sayle <roger@nextmovesoftware.com>
Date:   Wed Jun 7 00:32:51 2023 +0100

    Add RTX codes for BITREVERSE and COPYSIGN.
    
    An analysis of backend UNSPECs reveals that two of the most common UNSPECs
    across target backends are for copysign and bit reversal.  This patch
    adds RTX codes for these expressions to allow their representation to
    be standardized, and them to optimized by the middle-end RTL optimizers.
    
    2023-06-07  Roger Sayle  <roger@nextmovesoftware.com>
    
    gcc/ChangeLog
            * doc/rtl.texi (bitreverse, copysign): Document new RTX codes.
            * rtl.def (BITREVERSE, COPYSIGN): Define new RTX codes.
            * simplify-rtx.cc (simplify_unary_operation_1): Optimize
            NOT (BITREVERSE x) as BITREVERSE (NOT x).
            Optimize POPCOUNT (BITREVERSE x) as POPCOUNT x.
            Optimize PARITY (BITREVERSE x) as PARITY x.
            Optimize BITREVERSE (BITREVERSE x) as x.
            (simplify_const_unary_operation) <case BITREVERSE>: Evaluate
            BITREVERSE of a constant integer at compile-time.
            (simplify_binary_operation_1) <case COPYSIGN>:  Optimize
            COPY_SIGN (x, x) as x.  Optimize COPYSIGN (x, C) as ABS x
            or NEG (ABS x) for constant C.  Optimize COPYSIGN (ABS x, y)
            and COPYSIGN (NEG x, y) as COPYSIGN (x, y).
            Optimize COPYSIGN (x, ABS y) as ABS x.
            Optimize COPYSIGN (COPYSIGN (x, y), z) as COPYSIGN (x, z).
            Optimize COPYSIGN (x, COPYSIGN (y, z)) as COPYSIGN (x, z).
            (simplify_const_binary_operation): Evaluate COPYSIGN of constant
            arguments at compile-time.

Diff:
---
 gcc/doc/rtl.texi    | 11 +++++++++++
 gcc/rtl.def         |  6 ++++++
 gcc/simplify-rtx.cc | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index 1de24943c2e..76aeafb8f15 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -2742,6 +2742,17 @@ integer of mode @var{m}.  The mode of @var{x} must be @var{m} or
 Represents the value @var{x} with the order of bytes reversed, carried out
 in mode @var{m}, which must be a fixed-point machine mode.
 The mode of @var{x} must be @var{m} or @code{VOIDmode}.
+
+@findex bitreverse
+@item (bitreverse:@var{m} @var{x})
+Represents the value @var{x} with the order of bits reversed, carried out
+in mode @var{m}, which must be a fixed-point machine mode.
+The mode of @var{x} must be @var{m} or @code{VOIDmode}.
+
+@findex copysign
+@item (copysign:@var{m} @var{x} @var{y})
+Represents the value @var{x} with the sign of @var{y}.
+Both @var{x} and @var{y} must have floating point machine mode @var{m}.
 @end table
 
 @node Comparisons
diff --git a/gcc/rtl.def b/gcc/rtl.def
index 6ddbce380dc..88e2b198503 100644
--- a/gcc/rtl.def
+++ b/gcc/rtl.def
@@ -664,6 +664,9 @@ DEF_RTL_EXPR(POPCOUNT, "popcount", "e", RTX_UNARY)
 /* Population parity (number of 1 bits modulo 2).  */
 DEF_RTL_EXPR(PARITY, "parity", "e", RTX_UNARY)
 
+/* Reverse bits.  */
+DEF_RTL_EXPR(BITREVERSE, "bitreverse", "e", RTX_UNARY)
+
 /* Reference to a signed bit-field of specified size and position.
    Operand 0 is the memory unit (usually SImode or QImode) which
    contains the field's first bit.  Operand 1 is the width, in bits.
@@ -753,6 +756,9 @@ DEF_RTL_EXPR(US_TRUNCATE, "us_truncate", "e", RTX_UNARY)
 /* Floating point multiply/add combined instruction.  */
 DEF_RTL_EXPR(FMA, "fma", "eee", RTX_TERNARY)
 
+/* Floating point copysign.  Operand 0 with the sign of operand 1.  */
+DEF_RTL_EXPR(COPYSIGN, "copysign", "ee", RTX_BIN_ARITH)
+
 /* Information about the variable and its location.  */
 DEF_RTL_EXPR(VAR_LOCATION, "var_location", "te", RTX_EXTRA)
 
diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index 4e20a341977..276be67aa67 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -1040,10 +1040,10 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
 	}
 
       /* (not (bswap x)) -> (bswap (not x)).  */
-      if (GET_CODE (op) == BSWAP)
+      if (GET_CODE (op) == BSWAP || GET_CODE (op) == BITREVERSE)
 	{
 	  rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
-	  return simplify_gen_unary (BSWAP, mode, x, mode);
+	  return simplify_gen_unary (GET_CODE (op), mode, x, mode);
 	}
       break;
 
@@ -1419,6 +1419,7 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
       switch (GET_CODE (op))
 	{
 	case BSWAP:
+	case BITREVERSE:
 	  /* (popcount (bswap <X>)) = (popcount <X>).  */
 	  return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
 				     GET_MODE (XEXP (op, 0)));
@@ -1448,6 +1449,7 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
 	{
 	case NOT:
 	case BSWAP:
+	case BITREVERSE:
 	  return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
 				     GET_MODE (XEXP (op, 0)));
 
@@ -1481,6 +1483,12 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
 	return XEXP (op, 0);
       break;
 
+    case BITREVERSE:
+      /* (bitreverse (bitreverse x)) -> x.  */
+      if (GET_CODE (op) == BITREVERSE)
+	return XEXP (op, 0);
+      break;
+
     case FLOAT:
       /* (float (sign_extend <X>)) = (float <X>).  */
       if (GET_CODE (op) == SIGN_EXTEND)
@@ -2114,6 +2122,10 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
 	  result = wi::bswap (op0);
 	  break;
 
+	case BITREVERSE:
+	  result = wi::bitreverse (op0);
+	  break;
+
 	case TRUNCATE:
 	case ZERO_EXTEND:
 	  result = wide_int::from (op0, width, UNSIGNED);
@@ -4356,6 +4368,31 @@ simplify_ashift:
 	return op0;
       return 0;
 
+    case COPYSIGN:
+      if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
+	return op0;
+      if (CONST_DOUBLE_AS_FLOAT_P (trueop1))
+	{
+	  REAL_VALUE_TYPE f1;
+	  real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (trueop1));
+	  rtx tmp = simplify_gen_unary (ABS, mode, op0, mode);
+	  if (REAL_VALUE_NEGATIVE (f1))
+	    tmp = simplify_gen_unary (NEG, mode, op0, mode);
+	  return tmp;
+	}
+      if (GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
+	return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
+      if (GET_CODE (op1) == ABS
+	  && ! side_effects_p (op1))
+	return simplify_gen_unary (ABS, mode, op0, mode);
+      if (GET_CODE (op0) == COPYSIGN
+	  && ! side_effects_p (XEXP (op0, 1)))
+	return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
+      if (GET_CODE (op1) == COPYSIGN
+	  && ! side_effects_p (XEXP (op1, 0)))
+	return simplify_gen_binary (COPYSIGN, mode, op0, XEXP (op1, 1));
+      return 0;
+
     case VEC_SERIES:
       if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
 	return gen_vec_duplicate (mode, op0);
@@ -4996,6 +5033,14 @@ simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
 	   real_from_target (&r, tmp0, mode);
 	   return const_double_from_real_value (r, mode);
 	}
+      else if (code == COPYSIGN)
+	{
+	  REAL_VALUE_TYPE f0, f1;
+	  real_convert (&f0, mode, CONST_DOUBLE_REAL_VALUE (op0));
+	  real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (op1));
+	  real_copysign (&f0, &f1);
+	  return const_double_from_real_value (f0, mode);
+	}
       else
 	{
 	  REAL_VALUE_TYPE f0, f1, value, result;

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

only message in thread, other threads:[~2023-06-06 23:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-06 23:34 [gcc r14-1586] Add RTX codes for BITREVERSE and COPYSIGN 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).