public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/6] Getting rid of some zero_ext* patterns
@ 2015-05-10 16:14 Segher Boessenkool
  2015-05-10 16:14 ` [PATCH 1/6] combine: undo_to_marker Segher Boessenkool
                   ` (6 more replies)
  0 siblings, 7 replies; 20+ messages in thread
From: Segher Boessenkool @ 2015-05-10 16:14 UTC (permalink / raw)
  To: gcc-patches; +Cc: dje.gcc, Segher Boessenkool

This series teaches combine to behave a bit better, and then takes
advantage of that in the rs6000 backend.

I'll test the combine patches on x86_64-linux before committing,
and will wait a bit for comments anyway.


Segher


 gcc/combine.c               |  146 +++-
 gcc/config/rs6000/rs6000.c  |    4 +-
 gcc/config/rs6000/rs6000.md | 1606 ++++---------------------------------------
 3 files changed, 281 insertions(+), 1475 deletions(-)

-- 
1.8.1.4

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

* [PATCH 1/6] combine: undo_to_marker
  2015-05-10 16:14 [PATCH 0/6] Getting rid of some zero_ext* patterns Segher Boessenkool
@ 2015-05-10 16:14 ` Segher Boessenkool
  2015-05-11  4:10   ` Jeff Law
  2015-05-10 16:15 ` [PATCH 3/6] rs6000: Don't use zero_extract in the bswap:HI splitter Segher Boessenkool
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Segher Boessenkool @ 2015-05-10 16:14 UTC (permalink / raw)
  To: gcc-patches; +Cc: dje.gcc, Segher Boessenkool

This generalises undo_all to allow undoing only the last some SUBSTs.
This is used by the next patch, but is more generally useful.

Comments?


Segher


2015-05-10  Segher Boessenkool  <segher@kernel.crashing.org>

	* combine.c (get_undo_marker): New function.
	(undo_to_marker): New function, largely factored out from ...
	(undo_all): ... this.  Adjust.

---
 gcc/combine.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/gcc/combine.c b/gcc/combine.c
index b806959..1e4d65e 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -4643,15 +4643,25 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
     return newi2pat ? i2 : i3;
 }
 \f
-/* Undo all the modifications recorded in undobuf.  */
+/* Get a marker for undoing to the current state.  */
+
+static void *
+get_undo_marker (void)
+{
+  return undobuf.undos;
+}
+
+/* Undo the modifications up to the marker.  */
 
 static void
-undo_all (void)
+undo_to_marker (void *marker)
 {
   struct undo *undo, *next;
 
-  for (undo = undobuf.undos; undo; undo = next)
+  for (undo = undobuf.undos; undo != marker; undo = next)
     {
+      gcc_assert (undo);
+
       next = undo->next;
       switch (undo->kind)
 	{
@@ -4675,7 +4685,15 @@ undo_all (void)
       undobuf.frees = undo;
     }
 
-  undobuf.undos = 0;
+  undobuf.undos = (struct undo *) marker;
+}
+
+/* Undo all the modifications recorded in undobuf.  */
+
+static void
+undo_all (void)
+{
+  undo_to_marker (0);
 }
 
 /* We've committed to accepting the changes we made.  Move all
-- 
1.8.1.4

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

* [PATCH 3/6] rs6000: Don't use zero_extract in the bswap:HI splitter
  2015-05-10 16:14 [PATCH 0/6] Getting rid of some zero_ext* patterns Segher Boessenkool
  2015-05-10 16:14 ` [PATCH 1/6] combine: undo_to_marker Segher Boessenkool
@ 2015-05-10 16:15 ` Segher Boessenkool
  2015-05-11 15:32   ` David Edelsohn
  2015-05-10 16:15 ` [PATCH 2/6] combine: If recog fails, try again with zero_ext{ract,end} simplified Segher Boessenkool
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Segher Boessenkool @ 2015-05-10 16:15 UTC (permalink / raw)
  To: gcc-patches; +Cc: dje.gcc, Segher Boessenkool

The next patch removes the zero_extract insn this splits to.  Write
it as (and (lshiftrt ... instead.

Okay for trunk?


Segher


2015-05-10  Segher Boessenkool  <segher@kernel.crashing.org>

	* config/rs6000/rs6000.md (define_split for bswaphi): Don't use
	zero_extract.

---
 gcc/config/rs6000/rs6000.md | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index acf890c..4bd16ee 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -2184,17 +2184,15 @@ (define_insn "bswaphi2_internal"
   [(set_attr "length" "4,4,12")
    (set_attr "type" "load,store,*")])
 
-;; We are always BITS_BIG_ENDIAN, so the (const_int 16) below is
-;; correct for -mlittle as well as -mbig.
 (define_split
   [(set (match_operand:HI 0 "gpc_reg_operand" "")
 	(bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
   "reload_completed"
   [(set (match_dup 3)
-	(zero_extract:SI (match_dup 4)
-			 (const_int 8)
-			 (const_int 16)))
+	(and:SI (lshiftrt:SI (match_dup 4)
+			     (const_int 8))
+		(const_int 255)))
    (set (match_dup 2)
 	(and:SI (ashift:SI (match_dup 4)
 			   (const_int 8))
-- 
1.8.1.4

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

* [PATCH 2/6] combine: If recog fails, try again with zero_ext{ract,end} simplified
  2015-05-10 16:14 [PATCH 0/6] Getting rid of some zero_ext* patterns Segher Boessenkool
  2015-05-10 16:14 ` [PATCH 1/6] combine: undo_to_marker Segher Boessenkool
  2015-05-10 16:15 ` [PATCH 3/6] rs6000: Don't use zero_extract in the bswap:HI splitter Segher Boessenkool
@ 2015-05-10 16:15 ` Segher Boessenkool
  2015-05-11  4:15   ` Jeff Law
  2015-05-12  8:25   ` Kyrill Tkachov
  2015-05-10 16:16 ` [PATCH 6/6] rs6000: Clean up the various rlwinm patterns Segher Boessenkool
                   ` (3 subsequent siblings)
  6 siblings, 2 replies; 20+ messages in thread
From: Segher Boessenkool @ 2015-05-10 16:15 UTC (permalink / raw)
  To: gcc-patches; +Cc: dje.gcc, Segher Boessenkool

Combine has its own ideas of what is "canonical" RTL, forcing all
backends to have special patterns in their machine description for the
"more simplified" patterns combine often creates, even though the
backend already has patterns for a more general form.  Backends that
do not implement those patterns get less well optimised code.

This patch lifts that burden for two cases: combine often converts
an AND (with, say, 0xff) to a ZERO_EXTEND of a SUBREG; and an LSHIFTRT
followed by an AND to a ZERO_EXTRACT.  This is perfectly helpful for
e.g. MEMs, but not nice if you have instructions to do more generic
masking (like PowerPC rlwinm, and similar on some other archs).

With this patch, if recog_for_combine fails, and there are any
ZERO_EXT* in the pattern to be matched, it tries again with those
expressed as AND etc.  If that also fails it rolls back the changes,
because it might still match after e.g. splitting, and we want to
try the ZERO_EXT* for that as well.

Tested on powerpc-linux, before and after removing many patterns
from the machine description, and checked that the only changes in
the bootstrapped compiler are new and removed functions.

I'll also test on x86_64-linux before committing.


Segher


2015-05-10  Segher Boessenkool   <segher@kernel.crashing.org>

	* combine.c (recog_for_combine_1): New function, factored out
	from recog_for_combine.
	(change_zero_ext): New function.
	(recog_for_combine): If recog fails, try again with the pattern
	modified by change_zero_ext; if that still fails, restore the
	pattern.

---
 gcc/combine.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 107 insertions(+), 13 deletions(-)

diff --git a/gcc/combine.c b/gcc/combine.c
index 1e4d65e..896d9d2 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -10849,21 +10849,11 @@ simplify_shift_const (rtx x, enum rtx_code code, machine_mode result_mode,
 }
 
 \f
-/* Like recog, but we receive the address of a pointer to a new pattern.
-   We try to match the rtx that the pointer points to.
-   If that fails, we may try to modify or replace the pattern,
-   storing the replacement into the same pointer object.
-
-   Modifications include deletion or addition of CLOBBERs.
-
-   PNOTES is a pointer to a location where any REG_UNUSED notes added for
-   the CLOBBERs are placed.
-
-   The value is the final insn code from the pattern ultimately matched,
-   or -1.  */
+/* A subroutine of recog_for_combine.  See there for arguments and
+   return value.  */
 
 static int
-recog_for_combine (rtx *pnewpat, rtx_insn *insn, rtx *pnotes)
+recog_for_combine_1 (rtx *pnewpat, rtx_insn *insn, rtx *pnotes)
 {
   rtx pat = *pnewpat;
   rtx pat_without_clobbers;
@@ -11010,6 +11000,110 @@ recog_for_combine (rtx *pnewpat, rtx_insn *insn, rtx *pnotes)
 
   return insn_code_number;
 }
+
+/* Change every ZERO_EXTRACT and ZERO_EXTEND of a SUBREG that can be
+   expressed as an AND and maybe an LSHIFTRT, to that formulation.
+   Return whether anything was so changed.  */
+
+static bool
+change_zero_ext (rtx *src)
+{
+  bool changed = false;
+
+  subrtx_ptr_iterator::array_type array;
+  FOR_EACH_SUBRTX_PTR (iter, array, src, NONCONST)
+    {
+      rtx x = **iter;
+      machine_mode mode = GET_MODE (x);
+      int size;
+
+      if (GET_CODE (x) == ZERO_EXTRACT
+	  && CONST_INT_P (XEXP (x, 1))
+	  && CONST_INT_P (XEXP (x, 2))
+	  && GET_MODE (XEXP (x, 0)) == mode)
+	{
+	  size = INTVAL (XEXP (x, 1));
+
+	  int start = INTVAL (XEXP (x, 2));
+	  if (BITS_BIG_ENDIAN)
+	    start = GET_MODE_PRECISION (mode) - size - start;
+
+	  x = gen_rtx_LSHIFTRT (mode, XEXP (x, 0), GEN_INT (start));
+	}
+      else if (GET_CODE (x) == ZERO_EXTEND
+	       && GET_CODE (XEXP (x, 0)) == SUBREG
+	       && GET_MODE (SUBREG_REG (XEXP (x, 0))) == mode
+	       && subreg_lowpart_p (XEXP (x, 0)))
+	{
+	  size = GET_MODE_PRECISION (GET_MODE (XEXP (x, 0)));
+	  x = SUBREG_REG (XEXP (x, 0));
+	}
+      else
+	continue;
+
+      unsigned HOST_WIDE_INT mask = 1;
+      mask <<= size;
+      mask--;
+
+      x = gen_rtx_AND (mode, x, GEN_INT (mask));
+
+      SUBST (**iter, x);
+      changed = true;
+    }
+
+  return changed;
+}
+
+/* Like recog, but we receive the address of a pointer to a new pattern.
+   We try to match the rtx that the pointer points to.
+   If that fails, we may try to modify or replace the pattern,
+   storing the replacement into the same pointer object.
+
+   Modifications include deletion or addition of CLOBBERs.  If the
+   instruction will still not match, we change ZERO_EXTEND and ZERO_EXTRACT
+   to the equivalent AND and perhaps LSHIFTRT patterns, and try with that
+   (and undo if that fails).
+
+   PNOTES is a pointer to a location where any REG_UNUSED notes added for
+   the CLOBBERs are placed.
+
+   The value is the final insn code from the pattern ultimately matched,
+   or -1.  */
+
+static int
+recog_for_combine (rtx *pnewpat, rtx_insn *insn, rtx *pnotes)
+{
+  rtx pat = PATTERN (insn);
+  int insn_code_number = recog_for_combine_1 (pnewpat, insn, pnotes);
+  if (insn_code_number >= 0 || check_asm_operands (pat))
+    return insn_code_number;
+
+  void *marker = get_undo_marker ();
+  bool changed = false;
+
+  if (GET_CODE (pat) == SET)
+    changed = change_zero_ext (&SET_SRC (pat));
+  else if (GET_CODE (pat) == PARALLEL)
+    {
+      int i;
+      for (i = 0; i < XVECLEN (pat, 0); i++)
+	{
+	  rtx set = XVECEXP (pat, 0, i);
+	  if (GET_CODE (set) == SET)
+	    changed |= change_zero_ext (&SET_SRC (set));
+	}
+    }
+
+  if (changed)
+    {
+      insn_code_number = recog_for_combine_1 (pnewpat, insn, pnotes);
+
+      if (insn_code_number < 0)
+	undo_to_marker (marker);
+    }
+
+  return insn_code_number;
+}
 \f
 /* Like gen_lowpart_general but for use by combine.  In combine it
    is not possible to create any new pseudoregs.  However, it is
-- 
1.8.1.4

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

* [PATCH 5/6] rs6000: Don't use gen_rlwinm
  2015-05-10 16:14 [PATCH 0/6] Getting rid of some zero_ext* patterns Segher Boessenkool
                   ` (4 preceding siblings ...)
  2015-05-10 16:16 ` [PATCH 4/6] rs6000: Delete some now-superfluous zero_ext{end,ract} patterns Segher Boessenkool
@ 2015-05-10 16:16 ` Segher Boessenkool
  2015-05-11 15:30   ` David Edelsohn
  2015-05-12 14:01 ` [PATCH 0/6] Getting rid of some zero_ext* patterns Segher Boessenkool
  6 siblings, 1 reply; 20+ messages in thread
From: Segher Boessenkool @ 2015-05-10 16:16 UTC (permalink / raw)
  To: gcc-patches; +Cc: dje.gcc, Segher Boessenkool

The next patch will rename the "rlwinm" pattern (as well as the other patterns
that implement rlwinm, now unnamed).  The only place that uses gen_rlwinm
(an expander) is better off expanding the separate operations separately.
Do so.

Okay for trunk?


Segher


2015-05-10  Segher Boessenkool  <segher@kernel.crashing.org>

	* config/rs6000/rs6000.md (rs6000_adjust_atomic_subword): Use
	gen_ashlsi3 and gen_andsi3 instead of gen_rlwinm.

---
 gcc/config/rs6000/rs6000.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 7c59ac8..e5b8edd 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -20577,7 +20577,9 @@ rs6000_adjust_atomic_subword (rtx orig_mem, rtx *pshift, rtx *pmask)
   /* Shift amount for subword relative to aligned word.  */
   shift = gen_reg_rtx (SImode);
   addr = gen_lowpart (SImode, addr);
-  emit_insn (gen_rlwinm (shift, addr, GEN_INT (3), GEN_INT (shift_mask)));
+  rtx tmp = gen_reg_rtx (SImode);
+  emit_insn (gen_ashlsi3 (tmp, addr, GEN_INT (3)));
+  emit_insn (gen_andsi3 (shift, tmp, GEN_INT (shift_mask)));
   if (BYTES_BIG_ENDIAN)
     shift = expand_simple_binop (SImode, XOR, shift, GEN_INT (shift_mask),
 			         shift, 1, OPTAB_LIB_WIDEN);
-- 
1.8.1.4

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

* [PATCH 4/6] rs6000: Delete some now-superfluous zero_ext{end,ract} patterns
  2015-05-10 16:14 [PATCH 0/6] Getting rid of some zero_ext* patterns Segher Boessenkool
                   ` (3 preceding siblings ...)
  2015-05-10 16:16 ` [PATCH 6/6] rs6000: Clean up the various rlwinm patterns Segher Boessenkool
@ 2015-05-10 16:16 ` Segher Boessenkool
  2015-05-11 15:29   ` David Edelsohn
  2015-05-10 16:16 ` [PATCH 5/6] rs6000: Don't use gen_rlwinm Segher Boessenkool
  2015-05-12 14:01 ` [PATCH 0/6] Getting rid of some zero_ext* patterns Segher Boessenkool
  6 siblings, 1 reply; 20+ messages in thread
From: Segher Boessenkool @ 2015-05-10 16:16 UTC (permalink / raw)
  To: gcc-patches; +Cc: dje.gcc, Segher Boessenkool

After the change to combine, we no longer need all the special-case
patterns.

Tested on powerpc64-linux, as usual.  As mentioned with the combine
patch, there are no differences to generated code in cc1.

This does not delete DImode lshiftrt patterns, because those do not
exist (yet).

Is this okay for trunk?


Segher

[ Save the planet!  Delete 11% of your machine descriptions! ]


2015-05-10  Segher Boessenkool  <segher@kernel.crashing.org>

	* config/rs6000/rs6000.md (extzv): FAIL for SImode.
	(extzvsi_internal, *extzvsi_internal1, *extzvsi_internal2,
	*rotlsi3_internal7le, *rotlsi3_internal7be, *rotlsi3_internal8le,
	*rotlsi3_internal8be, *rotlsi3_internal9le, *rotlsi3_internal9be,
	*rotlsi3_internal10le, *rotlsi3_internal10be, *rotlsi3_internal11le,
	*rotlsi3_internal11be, *rotlsi3_internal12le, *rotlsi3_internal12be,
	*lshiftrt_internal1le, *lshiftrt_internal1be, *lshiftrt_internal2le,
	*lshiftrt_internal2be, *lshiftrt_internal3le, *lshiftrt_internal3be,
	*lshiftrt_internal4le, *lshiftrt_internal4be, *lshiftrt_internal5le,
	*lshiftrt_internal5be, *lshiftrt_internal5le, *lshiftrt_internal5be,
	*rotldi3_internal7le, *rotldi3_internal7be, *rotldi3_internal8le,
	*rotldi3_internal8be, *rotldi3_internal9le, *rotldi3_internal9be,
	*rotldi3_internal10le, *rotldi3_internal10be, *rotldi3_internal11le,
	*rotldi3_internal11be, *rotldi3_internal12le, *rotldi3_internal12be,
	*rotldi3_internal13le, *rotldi3_internal13be, *rotldi3_internal14le,
	*rotldi3_internal14be, *rotldi3_internal15le, *rotldi3_internal15be,
	and 30 corresponding splitters): Delete.

---
 gcc/config/rs6000/rs6000.md | 1285 +------------------------------------------
 1 file changed, 6 insertions(+), 1279 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 4bd16ee..d3b1a7a 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -3604,141 +3604,11 @@ (define_expand "extzv"
     emit_insn (gen_extzvdi_internal (operands[0], operands[1], operands[2],
 				     operands[3]));
   else
-    emit_insn (gen_extzvsi_internal (operands[0], operands[1], operands[2],
-				     operands[3]));
+    FAIL;
+
   DONE;
 }")
 
-(define_insn "extzvsi_internal"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-			 (match_operand:SI 2 "const_int_operand" "i")
-			 (match_operand:SI 3 "const_int_operand" "i")))]
-  ""
-  "*
-{
-  int start = INTVAL (operands[3]) & 31;
-  int size = INTVAL (operands[2]) & 31;
-
-  if (start + size >= 32)
-    operands[3] = const0_rtx;
-  else
-    operands[3] = GEN_INT (start + size);
-  return \"rlwinm %0,%1,%3,%s2,31\";
-}"
-  [(set_attr "type" "shift")])
-
-(define_insn "*extzvsi_internal1"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-			 (match_operand:SI 2 "const_int_operand" "i,i")
-			 (match_operand:SI 3 "const_int_operand" "i,i"))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 4 "=r,r"))]
-  ""
-  "*
-{
-  int start = INTVAL (operands[3]) & 31;
-  int size = INTVAL (operands[2]) & 31;
-
-  /* Force split for non-cc0 compare.  */
-  if (which_alternative == 1)
-     return \"#\";
-
-  /* If the bit-field being tested fits in the upper or lower half of a
-     word, it is possible to use andiu. or andil. to test it.  This is
-     useful because the condition register set-use delay is smaller for
-     andi[ul]. than for rlinm.  This doesn't work when the starting bit
-     position is 0 because the LT and GT bits may be set wrong.  */
-
-  if ((start > 0 && start + size <= 16) || start >= 16)
-    {
-      operands[3] = GEN_INT (((1 << (16 - (start & 15)))
-			      - (1 << (16 - (start & 15) - size))));
-      if (start < 16)
-	return \"andis. %4,%1,%3\";
-      else
-	return \"andi. %4,%1,%3\";
-    }
-
-  if (start + size >= 32)
-    operands[3] = const0_rtx;
-  else
-    operands[3] = GEN_INT (start + size);
-  return \"rlwinm. %4,%1,%3,%s2,31\";
-}"
-  [(set_attr "type" "shift")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
-			 (match_operand:SI 2 "const_int_operand" "")
-			 (match_operand:SI 3 "const_int_operand" ""))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 4 ""))]
-  "reload_completed"
-  [(set (match_dup 4)
-	(zero_extract:SI (match_dup 1) (match_dup 2)
-			 (match_dup 3)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 4)
-		    (const_int 0)))]
-  "")
-
-(define_insn "*extzvsi_internal2"
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-			 (match_operand:SI 2 "const_int_operand" "i,i")
-			 (match_operand:SI 3 "const_int_operand" "i,i"))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
-  ""
-  "*
-{
-  int start = INTVAL (operands[3]) & 31;
-  int size = INTVAL (operands[2]) & 31;
-
-  /* Force split for non-cc0 compare.  */
-  if (which_alternative == 1)
-     return \"#\";
-
-  /* Since we are using the output value, we can't ignore any need for
-     a shift.  The bit-field must end at the LSB.  */
-  if (start >= 16 && start + size == 32)
-    {
-      operands[3] = GEN_INT ((1 << size) - 1);
-      return \"andi. %0,%1,%3\";
-    }
-
-  if (start + size >= 32)
-    operands[3] = const0_rtx;
-  else
-    operands[3] = GEN_INT (start + size);
-  return \"rlwinm. %0,%1,%3,%s2,31\";
-}"
-  [(set_attr "type" "shift")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
-			 (match_operand:SI 2 "const_int_operand" "")
-			 (match_operand:SI 3 "const_int_operand" ""))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
-  "reload_completed"
-  [(set (match_dup 0)
-	(zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))
-   (set (match_dup 4)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
-
 (define_insn "extzvdi_internal"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
 	(zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
@@ -3955,336 +3825,6 @@ (define_split
 		    (const_int 0)))]
   "")
 
-(define_insn "*rotlsi3_internal7le"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(zero_extend:SI
-	 (subreg:QI
-	  (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-		     (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
-  "!BYTES_BIG_ENDIAN"
-  "rlw%I2nm %0,%1,%h2,0xff"
-  [(set (attr "cell_micro")
-     (if_then_else (match_operand:SI 2 "const_int_operand" "")
-	(const_string "not")
-	(const_string "always")))
-   (set_attr "type" "shift")])
-
-(define_insn "*rotlsi3_internal7be"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(zero_extend:SI
-	 (subreg:QI
-	  (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-		     (match_operand:SI 2 "reg_or_cint_operand" "ri")) 3)))]
-  "BYTES_BIG_ENDIAN"
-  "rlw%I2nm %0,%1,%h2,0xff"
-  [(set (attr "cell_micro")
-     (if_then_else (match_operand:SI 2 "const_int_operand" "")
-	(const_string "not")
-	(const_string "always")))
-   (set_attr "type" "shift")])
-
-(define_insn "*rotlsi3_internal8le"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:SI
-		     (subreg:QI
-		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))]
-  "!BYTES_BIG_ENDIAN"
-  "@
-   rlw%I2nm. %3,%1,%h2,0xff
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_insn "*rotlsi3_internal8be"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:SI
-		     (subreg:QI
-		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 3))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))]
-  "BYTES_BIG_ENDIAN"
-  "@
-   rlw%I2nm. %3,%1,%h2,0xff
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:SI
-		     (subreg:QI
-		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
-				 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 3 ""))]
-  "!BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 3)
-	(zero_extend:SI (subreg:QI
-		      (rotate:SI (match_dup 1)
-				 (match_dup 2)) 0)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 3)
-		    (const_int 0)))]
-  "")
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:SI
-		     (subreg:QI
-		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
-				 (match_operand:SI 2 "reg_or_cint_operand" "")) 3))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 3 ""))]
-  "BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 3)
-	(zero_extend:SI (subreg:QI
-		      (rotate:SI (match_dup 1)
-				 (match_dup 2)) 3)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 3)
-		    (const_int 0)))]
-  "")
-
-(define_insn "*rotlsi3_internal9le"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:SI
-		     (subreg:QI
-		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
-  "!BYTES_BIG_ENDIAN"
-  "@
-   rlw%I2nm. %0,%1,%h2,0xff
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_insn "*rotlsi3_internal9be"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:SI
-		     (subreg:QI
-		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 3))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))]
-  "BYTES_BIG_ENDIAN"
-  "@
-   rlw%I2nm. %0,%1,%h2,0xff
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:SI
-		     (subreg:QI
-		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
-				 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
-  "!BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 0)
-	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
-   (set (match_dup 3)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:SI
-		     (subreg:QI
-		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
-				 (match_operand:SI 2 "reg_or_cint_operand" "")) 3))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))]
-  "BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 0)
-	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))
-   (set (match_dup 3)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
-
-(define_insn "*rotlsi3_internal10le"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(zero_extend:SI
-	 (subreg:HI
-	  (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-		     (match_operand:SI 2 "reg_or_cint_operand" "rn")) 0)))]
-  "!BYTES_BIG_ENDIAN"
-  "rlw%I2nm %0,%1,%h2,0xffff"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")])
-
-(define_insn "*rotlsi3_internal10be"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(zero_extend:SI
-	 (subreg:HI
-	  (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-		     (match_operand:SI 2 "reg_or_cint_operand" "rn")) 2)))]
-  "BYTES_BIG_ENDIAN"
-  "rlw%I2nm %0,%1,%h2,0xffff"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")])
-
-(define_insn "*rotlsi3_internal11le"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:SI
-		     (subreg:HI
-		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))]
-  "!BYTES_BIG_ENDIAN"
-  "@
-   rlw%I2nm. %3,%1,%h2,0xffff
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_insn "*rotlsi3_internal11be"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:SI
-		     (subreg:HI
-		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 2))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))]
-  "BYTES_BIG_ENDIAN"
-  "@
-   rlw%I2nm. %3,%1,%h2,0xffff
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:SI
-		     (subreg:HI
-		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
-				 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 3 ""))]
-  "!BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 3)
-	(zero_extend:SI (subreg:HI
-		      (rotate:SI (match_dup 1)
-				 (match_dup 2)) 0)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 3)
-		    (const_int 0)))]
-  "")
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:SI
-		     (subreg:HI
-		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
-				 (match_operand:SI 2 "reg_or_cint_operand" "")) 2))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 3 ""))]
-  "BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 3)
-	(zero_extend:SI (subreg:HI
-		      (rotate:SI (match_dup 1)
-				 (match_dup 2)) 2)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 3)
-		    (const_int 0)))]
-  "")
-
-(define_insn "*rotlsi3_internal12le"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:SI
-		     (subreg:HI
-		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
-  "!BYTES_BIG_ENDIAN"
-  "@
-   rlw%I2nm. %0,%1,%h2,0xffff
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_insn "*rotlsi3_internal12be"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:SI
-		     (subreg:HI
-		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 2))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))]
-  "BYTES_BIG_ENDIAN"
-  "@
-   rlw%I2nm. %0,%1,%h2,0xffff
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:SI
-		     (subreg:HI
-		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
-				 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
-  "!BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 0)
-	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
-   (set (match_dup 3)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:SI
-		     (subreg:HI
-		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
-				 (match_operand:SI 2 "reg_or_cint_operand" "")) 2))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))]
-  "BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 0)
-	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))
-   (set (match_dup 3)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
-
 
 (define_insn "ashl<mode>3"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
@@ -4566,339 +4106,11 @@ (define_split
 		 (match_operand:SI 3 "mask_operand" ""))
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  "includes_rshift_p (operands[2], operands[3]) && reload_completed"
-  [(set (match_dup 0)
-	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
-   (set (match_dup 4)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
-
-(define_insn "*lshiftrt_internal1le"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(zero_extend:SI
-	 (subreg:QI
-	  (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-		       (match_operand:SI 2 "const_int_operand" "i")) 0)))]
-  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
-  "rlwinm %0,%1,%s2,0xff"
-  [(set_attr "type" "shift")])
-
-(define_insn "*lshiftrt_internal1be"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(zero_extend:SI
-	 (subreg:QI
-	  (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-		       (match_operand:SI 2 "const_int_operand" "i")) 3)))]
-  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
-  "rlwinm %0,%1,%s2,0xff"
-  [(set_attr "type" "shift")])
-
-(define_insn "*lshiftrt_internal2le"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC
-	 (zero_extend:SI
-	  (subreg:QI
-	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-			(match_operand:SI 2 "const_int_operand" "i,i")) 0))
-	 (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))]
-  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
-  "@
-   rlwinm. %3,%1,%s2,0xff
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_insn "*lshiftrt_internal2be"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC
-	 (zero_extend:SI
-	  (subreg:QI
-	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-			(match_operand:SI 2 "const_int_operand" "i,i")) 3))
-	 (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))]
-  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
-  "@
-   rlwinm. %3,%1,%s2,0xff
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC
-	 (zero_extend:SI
-	  (subreg:QI
-	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
-			(match_operand:SI 2 "const_int_operand" "")) 0))
-	 (const_int 0)))
-   (clobber (match_scratch:SI 3 ""))]
-  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
-  [(set (match_dup 3)
-	(zero_extend:SI (subreg:QI
-	   (lshiftrt:SI (match_dup 1)
-			(match_dup 2)) 0)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 3)
-		    (const_int 0)))]
-  "")
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC
-	 (zero_extend:SI
-	  (subreg:QI
-	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
-			(match_operand:SI 2 "const_int_operand" "")) 3))
-	 (const_int 0)))
-   (clobber (match_scratch:SI 3 ""))]
-  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
-  [(set (match_dup 3)
-	(zero_extend:SI (subreg:QI
-	   (lshiftrt:SI (match_dup 1)
-			(match_dup 2)) 3)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 3)
-		    (const_int 0)))]
-  "")
-
-(define_insn "*lshiftrt_internal3le"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC
-	 (zero_extend:SI
-	  (subreg:QI
-	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-			(match_operand:SI 2 "const_int_operand" "i,i")) 0))
-	 (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
-  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
-  "@
-   rlwinm. %0,%1,%s2,0xff
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_insn "*lshiftrt_internal3be"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC
-	 (zero_extend:SI
-	  (subreg:QI
-	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-			(match_operand:SI 2 "const_int_operand" "i,i")) 3))
-	 (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))]
-  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
-  "@
-   rlwinm. %0,%1,%s2,0xff
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC
-	 (zero_extend:SI
-	  (subreg:QI
-	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
-			(match_operand:SI 2 "const_int_operand" "")) 0))
-	 (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
-  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
-  [(set (match_dup 0)
-	(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
-   (set (match_dup 3)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC
-	 (zero_extend:SI
-	  (subreg:QI
-	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
-			(match_operand:SI 2 "const_int_operand" "")) 3))
-	 (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))]
-  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
-  [(set (match_dup 0)
-	(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))
-   (set (match_dup 3)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
-
-(define_insn "*lshiftrt_internal4le"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(zero_extend:SI
-	 (subreg:HI
-	  (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-		       (match_operand:SI 2 "const_int_operand" "i")) 0)))]
-  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
-  "rlwinm %0,%1,%s2,0xffff"
-  [(set_attr "type" "shift")])
-
-(define_insn "*lshiftrt_internal4be"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(zero_extend:SI
-	 (subreg:HI
-	  (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-		       (match_operand:SI 2 "const_int_operand" "i")) 2)))]
-  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
-  "rlwinm %0,%1,%s2,0xffff"
-  [(set_attr "type" "shift")])
-
-(define_insn "*lshiftrt_internal5le"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC
-	 (zero_extend:SI
-	  (subreg:HI
-	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-			(match_operand:SI 2 "const_int_operand" "i,i")) 0))
-	 (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))]
-  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
-  "@
-   rlwinm. %3,%1,%s2,0xffff
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_insn "*lshiftrt_internal5be"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC
-	 (zero_extend:SI
-	  (subreg:HI
-	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-			(match_operand:SI 2 "const_int_operand" "i,i")) 2))
-	 (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))]
-  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
-  "@
-   rlwinm. %3,%1,%s2,0xffff
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC
-	 (zero_extend:SI
-	  (subreg:HI
-	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
-			(match_operand:SI 2 "const_int_operand" "")) 0))
-	 (const_int 0)))
-   (clobber (match_scratch:SI 3 ""))]
-  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
-  [(set (match_dup 3)
-	(zero_extend:SI (subreg:HI
-	   (lshiftrt:SI (match_dup 1)
-			(match_dup 2)) 0)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 3)
-		    (const_int 0)))]
-  "")
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC
-	 (zero_extend:SI
-	  (subreg:HI
-	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
-			(match_operand:SI 2 "const_int_operand" "")) 2))
-	 (const_int 0)))
-   (clobber (match_scratch:SI 3 ""))]
-  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
-  [(set (match_dup 3)
-	(zero_extend:SI (subreg:HI
-	   (lshiftrt:SI (match_dup 1)
-			(match_dup 2)) 2)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 3)
-		    (const_int 0)))]
-  "")
-
-(define_insn "*lshiftrt_internal5le"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC
-	 (zero_extend:SI
-	  (subreg:HI
-	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-			(match_operand:SI 2 "const_int_operand" "i,i")) 0))
-	 (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
-  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
-  "@
-   rlwinm. %0,%1,%s2,0xffff
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_insn "*lshiftrt_internal5be"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC
-	 (zero_extend:SI
-	  (subreg:HI
-	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-			(match_operand:SI 2 "const_int_operand" "i,i")) 2))
-	 (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))]
-  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
-  "@
-   rlwinm. %0,%1,%s2,0xffff
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC
-	 (zero_extend:SI
-	  (subreg:HI
-	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
-			(match_operand:SI 2 "const_int_operand" "")) 0))
-	 (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
-  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
-  [(set (match_dup 0)
-	(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
-   (set (match_dup 3)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC
-	 (zero_extend:SI
-	  (subreg:HI
-	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
-			(match_operand:SI 2 "const_int_operand" "")) 2))
-	 (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))]
-  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
+	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+  "includes_rshift_p (operands[2], operands[3]) && reload_completed"
   [(set (match_dup 0)
-	(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))
-   (set (match_dup 3)
+	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (set (match_dup 4)
 	(compare:CC (match_dup 0)
 		    (const_int 0)))]
   "")
@@ -6682,491 +5894,6 @@ (define_split
 		    (const_int 0)))]
   "")
 
-(define_insn "*rotldi3_internal7le"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(zero_extend:DI
-	 (subreg:QI
-	  (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-		     (match_operand:DI 2 "reg_or_cint_operand" "rn")) 0)))]
-  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
-  "rld%I2cl %0,%1,%H2,56"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")])
-
-(define_insn "*rotldi3_internal7be"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(zero_extend:DI
-	 (subreg:QI
-	  (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-		     (match_operand:DI 2 "reg_or_cint_operand" "rn")) 7)))]
-  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
-  "rld%I2cl %0,%1,%H2,56"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")])
-
-(define_insn "*rotldi3_internal8le"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:DI
-		     (subreg:QI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r"))]
-  "TARGET_64BIT && !BYTES_BIG_ENDIAN"
-  "@
-   rld%I2cl. %3,%1,%H2,56
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_insn "*rotldi3_internal8be"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:DI
-		     (subreg:QI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 7))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r"))]
-  "TARGET_64BIT && BYTES_BIG_ENDIAN"
-  "@
-   rld%I2cl. %3,%1,%H2,56
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:DI
-		     (subreg:QI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
-				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 3)
-	(zero_extend:DI (subreg:QI
-		      (rotate:DI (match_dup 1)
-				 (match_dup 2)) 0)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 3)
-		    (const_int 0)))]
-  "")
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:DI
-		     (subreg:QI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
-				 (match_operand:DI 2 "reg_or_cint_operand" "")) 7))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 3)
-	(zero_extend:DI (subreg:QI
-		      (rotate:DI (match_dup 1)
-				 (match_dup 2)) 7)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 3)
-		    (const_int 0)))]
-  "")
-
-(define_insn "*rotldi3_internal9le"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:DI
-		     (subreg:QI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
-  "TARGET_64BIT && !BYTES_BIG_ENDIAN"
-  "@
-   rld%I2cl. %0,%1,%H2,56
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_insn "*rotldi3_internal9be"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:DI
-		     (subreg:QI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 7))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))]
-  "TARGET_64BIT && BYTES_BIG_ENDIAN"
-  "@
-   rld%I2cl. %0,%1,%H2,56
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:DI
-		     (subreg:QI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
-				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "")
-	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
-  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 0)
-	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
-   (set (match_dup 3)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:DI
-		     (subreg:QI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
-				 (match_operand:DI 2 "reg_or_cint_operand" "")) 7))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "")
-	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))]
-  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 0)
-	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))
-   (set (match_dup 3)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
-
-(define_insn "*rotldi3_internal10le"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(zero_extend:DI
-	 (subreg:HI
-	  (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-		     (match_operand:DI 2 "reg_or_cint_operand" "rn")) 0)))]
-  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
-  "rld%I2cl %0,%1,%H2,48"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")])
-
-(define_insn "*rotldi3_internal10be"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(zero_extend:DI
-	 (subreg:HI
-	  (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-		     (match_operand:DI 2 "reg_or_cint_operand" "rn")) 6)))]
-  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
-  "rld%I2cl %0,%1,%H2,48"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")])
-
-(define_insn "*rotldi3_internal11le"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:DI
-		     (subreg:HI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r"))]
-  "TARGET_64BIT && !BYTES_BIG_ENDIAN"
-  "@
-   rld%I2cl. %3,%1,%H2,48
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_insn "*rotldi3_internal11be"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:DI
-		     (subreg:HI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 6))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r"))]
-  "TARGET_64BIT && BYTES_BIG_ENDIAN"
-  "@
-   rld%I2cl. %3,%1,%H2,48
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:DI
-		     (subreg:HI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
-				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 3)
-	(zero_extend:DI (subreg:HI
-		      (rotate:DI (match_dup 1)
-				 (match_dup 2)) 0)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 3)
-		    (const_int 0)))]
-  "")
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:DI
-		     (subreg:HI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
-				 (match_operand:DI 2 "reg_or_cint_operand" "")) 6))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 3)
-	(zero_extend:DI (subreg:HI
-		      (rotate:DI (match_dup 1)
-				 (match_dup 2)) 6)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 3)
-		    (const_int 0)))]
-  "")
-
-(define_insn "*rotldi3_internal12le"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:DI
-		     (subreg:HI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
-  "TARGET_64BIT && !BYTES_BIG_ENDIAN"
-  "@
-   rld%I2cl. %0,%1,%H2,48
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_insn "*rotldi3_internal12be"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:DI
-		     (subreg:HI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 6))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))]
-  "TARGET_64BIT && BYTES_BIG_ENDIAN"
-  "@
-   rld%I2cl. %0,%1,%H2,48
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:DI
-		     (subreg:HI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
-				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "")
-	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
-  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 0)
-	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
-   (set (match_dup 3)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:DI
-		     (subreg:HI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
-				 (match_operand:DI 2 "reg_or_cint_operand" "")) 6))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "")
-	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))]
-  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 0)
-	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))
-   (set (match_dup 3)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
-
-(define_insn "*rotldi3_internal13le"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(zero_extend:DI
-	 (subreg:SI
-	  (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-		     (match_operand:DI 2 "reg_or_cint_operand" "rn")) 0)))]
-  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
-  "rld%I2cl %0,%1,%H2,32"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")])
-
-(define_insn "*rotldi3_internal13be"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(zero_extend:DI
-	 (subreg:SI
-	  (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-		     (match_operand:DI 2 "reg_or_cint_operand" "rn")) 4)))]
-  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
-  "rld%I2cl %0,%1,%H2,32"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")])
-
-(define_insn "*rotldi3_internal14le"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:DI
-		     (subreg:SI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r"))]
-  "TARGET_64BIT && !BYTES_BIG_ENDIAN"
-  "@
-   rld%I2cl. %3,%1,%H2,32
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_insn "*rotldi3_internal14be"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:DI
-		     (subreg:SI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 4))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r"))]
-  "TARGET_64BIT && BYTES_BIG_ENDIAN"
-  "@
-   rld%I2cl. %3,%1,%H2,32
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:DI
-		     (subreg:SI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
-				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 3)
-	(zero_extend:DI (subreg:SI
-		      (rotate:DI (match_dup 1)
-				 (match_dup 2)) 0)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 3)
-		    (const_int 0)))]
-  "")
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:DI
-		     (subreg:SI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
-				 (match_operand:DI 2 "reg_or_cint_operand" "")) 4))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 3)
-	(zero_extend:DI (subreg:SI
-		      (rotate:DI (match_dup 1)
-				 (match_dup 2)) 4)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 3)
-		    (const_int 0)))]
-  "")
-
-(define_insn "*rotldi3_internal15le"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:DI
-		     (subreg:SI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
-  "TARGET_64BIT && !BYTES_BIG_ENDIAN"
-  "@
-   rld%I2cl. %0,%1,%H2,32
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_insn "*rotldi3_internal15be"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:DI
-		     (subreg:SI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-				 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 4))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))]
-  "TARGET_64BIT && BYTES_BIG_ENDIAN"
-  "@
-   rld%I2cl. %0,%1,%H2,32
-   #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:DI
-		     (subreg:SI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
-				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "")
-	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
-  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 0)
-	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
-   (set (match_dup 3)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:DI
-		     (subreg:SI
-		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
-				 (match_operand:DI 2 "reg_or_cint_operand" "")) 4))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "")
-	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))]
-  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
-  [(set (match_dup 0)
-	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))
-   (set (match_dup 3)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
 
 (define_insn "*ashldi3_internal4"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-- 
1.8.1.4

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

* [PATCH 6/6] rs6000: Clean up the various rlwinm patterns
  2015-05-10 16:14 [PATCH 0/6] Getting rid of some zero_ext* patterns Segher Boessenkool
                   ` (2 preceding siblings ...)
  2015-05-10 16:15 ` [PATCH 2/6] combine: If recog fails, try again with zero_ext{ract,end} simplified Segher Boessenkool
@ 2015-05-10 16:16 ` Segher Boessenkool
  2015-05-10 18:02   ` Maciej W. Rozycki
  2015-05-11 15:31   ` David Edelsohn
  2015-05-10 16:16 ` [PATCH 4/6] rs6000: Delete some now-superfluous zero_ext{end,ract} patterns Segher Boessenkool
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 20+ messages in thread
From: Segher Boessenkool @ 2015-05-10 16:16 UTC (permalink / raw)
  To: gcc-patches; +Cc: dje.gcc, Segher Boessenkool

Some cleanups:

* Give every define_insn a name;
* Add missing conditions for some of the dot forms;
* Use define_insn_and_split to reduce duplication;
* Renumber operands so 0,1,2,3 are the actual operands of the machine
  instruction, in order;
* Reformat some patterns.

Is this okay for trunk?


Segher


2015-05-10  Segher Boessenkool  <segher@kernel.crashing.org>

	* config/rs6000/rs6000.md (*rotlsi3_internal4, *rotlsi3_internal5,
	*rotlsi3_internal6, rlwinm, 5 unnamed define_insns, and 6
	define_splits): Delete.
	(*rotlsi3_mask, *rotlsi3_mask_dot, *rotlsi3_mask_dot2,
	*ashlsi3_imm_mask, *ashlsi3_imm_mask_dot, *ashlsi3_imm_mask_dot2,
	*lshrsi3_imm_mask, *lshrsi3_imm_mask_dot, *lshrsi3_imm_mask_dot2):
	New.

---
 gcc/config/rs6000/rs6000.md | 243 +++++++++++++++++++-------------------------
 1 file changed, 105 insertions(+), 138 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index d3b1a7a..1fcd69e 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -3745,7 +3745,7 @@ (define_insn_and_split "*rotl<mode>3_dot2"
    (set_attr "length" "4,8")])
 
 
-(define_insn "*rotlsi3_internal4"
+(define_insn "*rotlsi3_mask"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
 			   (match_operand:SI 2 "reg_or_cint_operand" "rn"))
@@ -3755,75 +3755,62 @@ (define_insn "*rotlsi3_internal4"
   [(set_attr "type" "shift")
    (set_attr "maybe_var_shift" "yes")])
 
-(define_insn "*rotlsi3_internal5"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (and:SI
-		     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
-		     (match_operand:SI 3 "mask_operand" "n,n"))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 4 "=r,r"))]
-  ""
+(define_insn_and_split "*rotlsi3_mask_dot"
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
+	(compare:CC
+	 (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+			    (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
+		 (match_operand:SI 3 "mask_operand" "n,n"))
+	 (const_int 0)))
+   (clobber (match_scratch:SI 0 "=r,r"))]
+  "rs6000_gen_cell_microcode
+   && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)"
   "@
-   rlw%I2nm. %4,%1,%h2,%m3,%M3
+   rlw%I2nm. %0,%1,%h2,%m3,%M3
    #"
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
+  [(set (match_dup 0)
+	(and:SI (rotate:SI (match_dup 1)
+			   (match_dup 2))
+		(match_dup 3)))
+   (set (match_dup 4)
+	(compare:CC (match_dup 0)
+		    (const_int 0)))]
+  ""
   [(set_attr "type" "shift")
    (set_attr "maybe_var_shift" "yes")
    (set_attr "dot" "yes")
    (set_attr "length" "4,8")])
 
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (and:SI
-		     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
-				(match_operand:SI 2 "reg_or_cint_operand" ""))
-		     (match_operand:SI 3 "mask_operand" ""))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 4 ""))]
-  "reload_completed"
-  [(set (match_dup 4)
-	(and:SI (rotate:SI (match_dup 1)
-				(match_dup 2))
-		     (match_dup 3)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 4)
-		    (const_int 0)))]
-  "")
-
-(define_insn "*rotlsi3_internal6"
+(define_insn_and_split "*rotlsi3_mask_dot2"
   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
-	(compare:CC (and:SI
-		     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
-		     (match_operand:SI 3 "mask_operand" "n,n"))
-		    (const_int 0)))
+	(compare:CC
+	 (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+			    (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
+		 (match_operand:SI 3 "mask_operand" "n,n"))
+	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  ""
+	(and:SI (rotate:SI (match_dup 1)
+			   (match_dup 2))
+		(match_dup 3)))]
+  "rs6000_gen_cell_microcode
+   && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)"
   "@
    rlw%I2nm. %0,%1,%h2,%m3,%M3
    #"
-  [(set_attr "type" "shift")
-   (set_attr "maybe_var_shift" "yes")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (and:SI
-		     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
-				(match_operand:SI 2 "reg_or_cint_operand" ""))
-		     (match_operand:SI 3 "mask_operand" ""))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  "reload_completed"
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
   [(set (match_dup 0)
-	(and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+	(and:SI (rotate:SI (match_dup 1)
+			   (match_dup 2))
+		(match_dup 3)))
    (set (match_dup 4)
 	(compare:CC (match_dup 0)
 		    (const_int 0)))]
-  "")
+  ""
+  [(set_attr "type" "shift")
+   (set_attr "maybe_var_shift" "yes")
+   (set_attr "dot" "yes")
+   (set_attr "length" "4,8")])
 
 
 (define_insn "ashl<mode>3"
@@ -3894,7 +3881,7 @@ (define_insn_and_split "*ashl<mode>3_dot2"
    (set_attr "length" "4,8")])
 
 
-(define_insn "rlwinm"
+(define_insn "*ashlsi3_imm_mask"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
 			   (match_operand:SI 2 "const_int_operand" "i"))
@@ -3903,40 +3890,34 @@ (define_insn "rlwinm"
   "rlwinm %0,%1,%h2,%m3,%M3"
   [(set_attr "type" "shift")])
 
-(define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+(define_insn_and_split "*ashlsi3_imm_mask_dot"
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
 	(compare:CC
 	 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
 			    (match_operand:SI 2 "const_int_operand" "i,i"))
 		 (match_operand:SI 3 "mask_operand" "n,n"))
 	 (const_int 0)))
-   (clobber (match_scratch:SI 4 "=r,r"))]
-  "includes_lshift_p (operands[2], operands[3])"
+   (clobber (match_scratch:SI 0 "=r,r"))]
+  "rs6000_gen_cell_microcode
+   && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)
+   && includes_lshift_p (operands[2], operands[3])"
   "@
-   rlwinm. %4,%1,%h2,%m3,%M3
+   rlwinm. %0,%1,%h2,%m3,%M3
    #"
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
+  [(set (match_dup 0)
+	(and:SI (ashift:SI (match_dup 1)
+			   (match_dup 2))
+		(match_dup 3)))
+   (set (match_dup 4)
+	(compare:CC (match_dup 0)
+		    (const_int 0)))]
+  ""
   [(set_attr "type" "shift")
    (set_attr "dot" "yes")
    (set_attr "length" "4,8")])
 
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC
-	 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
-			    (match_operand:SI 2 "const_int_operand" ""))
-		 (match_operand:SI 3 "mask_operand" ""))
-	 (const_int 0)))
-   (clobber (match_scratch:SI 4 ""))]
-  "includes_lshift_p (operands[2], operands[3]) && reload_completed"
-  [(set (match_dup 4)
-	(and:SI (ashift:SI (match_dup 1) (match_dup 2))
-		 (match_dup 3)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 4)
-		    (const_int 0)))]
-  "")
-
-(define_insn ""
+(define_insn_and_split "*ashlsi3_imm_mask_dot2"
   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
 	(compare:CC
 	 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
@@ -3944,31 +3925,27 @@ (define_insn ""
 		 (match_operand:SI 3 "mask_operand" "n,n"))
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  "includes_lshift_p (operands[2], operands[3])"
+	(and:SI (ashift:SI (match_dup 1)
+			   (match_dup 2))
+		(match_dup 3)))]
+  "rs6000_gen_cell_microcode
+   && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)
+   && includes_lshift_p (operands[2], operands[3])"
   "@
    rlwinm. %0,%1,%h2,%m3,%M3
    #"
-  [(set_attr "type" "shift")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC
-	 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
-			    (match_operand:SI 2 "const_int_operand" ""))
-		 (match_operand:SI 3 "mask_operand" ""))
-	 (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  "includes_lshift_p (operands[2], operands[3]) && reload_completed"
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
   [(set (match_dup 0)
-	(and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+	(and:SI (ashift:SI (match_dup 1)
+			   (match_dup 2))
+		(match_dup 3)))
    (set (match_dup 4)
 	(compare:CC (match_dup 0)
 		    (const_int 0)))]
-  "")
+  ""
+  [(set_attr "type" "shift")
+   (set_attr "dot" "yes")
+   (set_attr "length" "4,8")])
 
 
 (define_insn "lshr<mode>3"
@@ -4039,7 +4016,7 @@ (define_insn_and_split "*lshr<mode>3_dot2"
    (set_attr "length" "4,8")])
 
 
-(define_insn ""
+(define_insn "*lshrsi3_imm_mask"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
 			     (match_operand:SI 2 "const_int_operand" "i"))
@@ -4048,40 +4025,34 @@ (define_insn ""
   "rlwinm %0,%1,%s2,%m3,%M3"
   [(set_attr "type" "shift")])
 
-(define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+(define_insn_and_split "*lshrsi3_imm_mask_dot"
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
 	(compare:CC
 	 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
 			      (match_operand:SI 2 "const_int_operand" "i,i"))
 		 (match_operand:SI 3 "mask_operand" "n,n"))
 	 (const_int 0)))
-   (clobber (match_scratch:SI 4 "=r,r"))]
-  "includes_rshift_p (operands[2], operands[3])"
+   (clobber (match_scratch:SI 0 "=r,r"))]
+  "rs6000_gen_cell_microcode
+   && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)
+   && includes_rshift_p (operands[2], operands[3])"
   "@
-   rlwinm. %4,%1,%s2,%m3,%M3
+   rlwinm. %0,%1,%s2,%m3,%M3
    #"
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
+  [(set (match_dup 0)
+	(and:SI (lshiftrt:SI (match_dup 1)
+			     (match_dup 2))
+		(match_dup 3)))
+   (set (match_dup 4)
+	(compare:CC (match_dup 0)
+		    (const_int 0)))]
+  ""
   [(set_attr "type" "shift")
    (set_attr "dot" "yes")
    (set_attr "length" "4,8")])
 
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC
-	 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
-			      (match_operand:SI 2 "const_int_operand" ""))
-		 (match_operand:SI 3 "mask_operand" ""))
-	 (const_int 0)))
-   (clobber (match_scratch:SI 4 ""))]
-  "includes_rshift_p (operands[2], operands[3]) && reload_completed"
-  [(set (match_dup 4)
-	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
-		 (match_dup 3)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 4)
-		    (const_int 0)))]
-  "")
-
-(define_insn ""
+(define_insn_and_split "*lshrsi3_imm_mask_dot2"
   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
 	(compare:CC
 	 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
@@ -4089,31 +4060,27 @@ (define_insn ""
 		 (match_operand:SI 3 "mask_operand" "n,n"))
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  "includes_rshift_p (operands[2], operands[3])"
+	(and:SI (lshiftrt:SI (match_dup 1)
+			     (match_dup 2))
+		(match_dup 3)))]
+  "rs6000_gen_cell_microcode
+   && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)
+   && includes_rshift_p (operands[2], operands[3])"
   "@
    rlwinm. %0,%1,%s2,%m3,%M3
    #"
-  [(set_attr "type" "shift")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC
-	 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
-			      (match_operand:SI 2 "const_int_operand" ""))
-		 (match_operand:SI 3 "mask_operand" ""))
-	 (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  "includes_rshift_p (operands[2], operands[3]) && reload_completed"
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
   [(set (match_dup 0)
-	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+	(and:SI (lshiftrt:SI (match_dup 1)
+			     (match_dup 2))
+		(match_dup 3)))
    (set (match_dup 4)
 	(compare:CC (match_dup 0)
 		    (const_int 0)))]
-  "")
+  ""
+  [(set_attr "type" "shift")
+   (set_attr "dot" "yes")
+   (set_attr "length" "4,8")])
 
 
 (define_expand "ashr<mode>3"
-- 
1.8.1.4

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

* Re: [PATCH 6/6] rs6000: Clean up the various rlwinm patterns
  2015-05-10 16:16 ` [PATCH 6/6] rs6000: Clean up the various rlwinm patterns Segher Boessenkool
@ 2015-05-10 18:02   ` Maciej W. Rozycki
  2015-05-10 19:45     ` Segher Boessenkool
  2015-05-11 15:31   ` David Edelsohn
  1 sibling, 1 reply; 20+ messages in thread
From: Maciej W. Rozycki @ 2015-05-10 18:02 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, dje.gcc

On Sun, 10 May 2015, Segher Boessenkool wrote:

> * Give every define_insn a name;
> * Add missing conditions for some of the dot forms;
> * Use define_insn_and_split to reduce duplication;
> * Renumber operands so 0,1,2,3 are the actual operands of the machine
>   instruction, in order;
> * Reformat some patterns.
[...]
> 2015-05-10  Segher Boessenkool  <segher@kernel.crashing.org>
> 
> 	* config/rs6000/rs6000.md (*rotlsi3_internal4, *rotlsi3_internal5,
> 	*rotlsi3_internal6, rlwinm, 5 unnamed define_insns, and 6
> 	define_splits): Delete.
> 	(*rotlsi3_mask, *rotlsi3_mask_dot, *rotlsi3_mask_dot2,
> 	*ashlsi3_imm_mask, *ashlsi3_imm_mask_dot, *ashlsi3_imm_mask_dot2,
> 	*lshrsi3_imm_mask, *lshrsi3_imm_mask_dot, *lshrsi3_imm_mask_dot2):
> 	New.
[...]
> diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
> index d3b1a7a..1fcd69e 100644
> --- a/gcc/config/rs6000/rs6000.md
> +++ b/gcc/config/rs6000/rs6000.md
[...]
> @@ -3894,7 +3881,7 @@ (define_insn_and_split "*ashl<mode>3_dot2"
>     (set_attr "length" "4,8")])
>  
>  
> -(define_insn "rlwinm"
> +(define_insn "*ashlsi3_imm_mask"
>    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
>  	(and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
>  			   (match_operand:SI 2 "const_int_operand" "i"))

 This clearly renames rather than removing the `rlwinm' pattern, please 
correctly reflect that in ChangeLog.  Some other, unnamed patterns are 
given names rather than deleted as well, just as you've noted at the top.  
And none of the other changes are mentioned in your ChangeLog entry.

 Would you be able to split this change up further by any chance?  
Perhaps into the very steps you listed at the top so that each individual 
change addresses a single issue only.  That would avoid problems with 
ChangeLog and make the review easier.

 Thanks,

  Maciej

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

* Re: [PATCH 6/6] rs6000: Clean up the various rlwinm patterns
  2015-05-10 18:02   ` Maciej W. Rozycki
@ 2015-05-10 19:45     ` Segher Boessenkool
  2015-05-11 18:17       ` Maciej W. Rozycki
  0 siblings, 1 reply; 20+ messages in thread
From: Segher Boessenkool @ 2015-05-10 19:45 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: gcc-patches, dje.gcc

On Sun, May 10, 2015 at 07:02:33PM +0100, Maciej W. Rozycki wrote:
> > -(define_insn "rlwinm"
> > +(define_insn "*ashlsi3_imm_mask"
> >    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
> >  	(and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
> >  			   (match_operand:SI 2 "const_int_operand" "i"))
> 
>  This clearly renames rather than removing the `rlwinm' pattern, please 
> correctly reflect that in ChangeLog.  Some other, unnamed patterns are 
> given names rather than deleted as well, just as you've noted at the top.  
> And none of the other changes are mentioned in your ChangeLog entry.

The changelog says it deletes the patterns with the old names.  Which it
does.  And it adds the ones with the new names.  Which it does.  No one
said changelogs are useful ;-)

>  Would you be able to split this change up further by any chance?  

I could, but it would be a lot of extra work.  First, I haven't done those
steps in order (they aren't "steps" at all): I take one pattern, and fix
it up, then the next, etc.

But much worse: if you do tiny pattern changes like you suggest, I can
guarantee you the patches _will_ mis-apply.  All of the time :-(

[ Sometimes two patterns even have the same name, and sometimes even 100%
identical contents.  Exciting! ]

> Perhaps into the very steps you listed at the top so that each individual 
> change addresses a single issue only.  That would avoid problems with 
> ChangeLog and make the review easier.

This isn't the first patch like this, I've cleaned up most other PowerPC
integer patterns already.  It's enough work already.  Often the changes
cannot be separated, and even if they can you then need them in the fixed
order you made for them, etc.

For this small patch I could probably do a better changelog though.


Segher

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

* Re: [PATCH 1/6] combine: undo_to_marker
  2015-05-10 16:14 ` [PATCH 1/6] combine: undo_to_marker Segher Boessenkool
@ 2015-05-11  4:10   ` Jeff Law
  0 siblings, 0 replies; 20+ messages in thread
From: Jeff Law @ 2015-05-11  4:10 UTC (permalink / raw)
  To: Segher Boessenkool, gcc-patches; +Cc: dje.gcc

On 05/10/2015 10:13 AM, Segher Boessenkool wrote:
> This generalises undo_all to allow undoing only the last some SUBSTs.
> This is used by the next patch, but is more generally useful.
>
> Comments?
>
>
> Segher
>
>
> 2015-05-10  Segher Boessenkool  <segher@kernel.crashing.org>
>
> 	* combine.c (get_undo_marker): New function.
> 	(undo_to_marker): New function, largely factored out from ...
> 	(undo_all): ... this.  Adjust.
Seems quite reasonable to me.  I can't think of any reason offhand why 
it'd be a bad idea.

jeff

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

* Re: [PATCH 2/6] combine: If recog fails, try again with zero_ext{ract,end} simplified
  2015-05-10 16:15 ` [PATCH 2/6] combine: If recog fails, try again with zero_ext{ract,end} simplified Segher Boessenkool
@ 2015-05-11  4:15   ` Jeff Law
  2015-05-11  6:18     ` Segher Boessenkool
  2015-05-12  8:25   ` Kyrill Tkachov
  1 sibling, 1 reply; 20+ messages in thread
From: Jeff Law @ 2015-05-11  4:15 UTC (permalink / raw)
  To: Segher Boessenkool, gcc-patches; +Cc: dje.gcc

On 05/10/2015 10:13 AM, Segher Boessenkool wrote:
> Combine has its own ideas of what is "canonical" RTL, forcing all
> backends to have special patterns in their machine description for the
> "more simplified" patterns combine often creates, even though the
> backend already has patterns for a more general form.  Backends that
> do not implement those patterns get less well optimised code.
>
> This patch lifts that burden for two cases: combine often converts
> an AND (with, say, 0xff) to a ZERO_EXTEND of a SUBREG; and an LSHIFTRT
> followed by an AND to a ZERO_EXTRACT.  This is perfectly helpful for
> e.g. MEMs, but not nice if you have instructions to do more generic
> masking (like PowerPC rlwinm, and similar on some other archs).
>
> With this patch, if recog_for_combine fails, and there are any
> ZERO_EXT* in the pattern to be matched, it tries again with those
> expressed as AND etc.  If that also fails it rolls back the changes,
> because it might still match after e.g. splitting, and we want to
> try the ZERO_EXT* for that as well.
>
> Tested on powerpc-linux, before and after removing many patterns
> from the machine description, and checked that the only changes in
> the bootstrapped compiler are new and removed functions.
>
> I'll also test on x86_64-linux before committing.
>
>
> Segher
>
>
> 2015-05-10  Segher Boessenkool   <segher@kernel.crashing.org>
>
> 	* combine.c (recog_for_combine_1): New function, factored out
> 	from recog_for_combine.
> 	(change_zero_ext): New function.
> 	(recog_for_combine): If recog fails, try again with the pattern
> 	modified by change_zero_ext; if that still fails, restore the
> 	pattern.
I like it.  Attacking the extensions are the most obvious candidates, 
but I wonder if there's others (like the whole "ASHIFT vs MULT" stuff 
that we were recently looking at for ARM).


jeff

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

* Re: [PATCH 2/6] combine: If recog fails, try again with zero_ext{ract,end} simplified
  2015-05-11  4:15   ` Jeff Law
@ 2015-05-11  6:18     ` Segher Boessenkool
  0 siblings, 0 replies; 20+ messages in thread
From: Segher Boessenkool @ 2015-05-11  6:18 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches, dje.gcc

On Sun, May 10, 2015 at 10:15:34PM -0600, Jeff Law wrote:
> >	(recog_for_combine): If recog fails, try again with the pattern
> >	modified by change_zero_ext; if that still fails, restore the
> >	pattern.
> I like it.  Attacking the extensions are the most obvious candidates, 
> but I wonder if there's others (like the whole "ASHIFT vs MULT" stuff 
> that we were recently looking at for ARM).

Yeah, I thought about that as well.  But that case, MULT instead of shift,
outside of MEM, is simply non-canonical RTL; and combine created it on
purpose.  It just shouldn't.

There certainly will be other cases though; hopefully not overlapping,
I don't want to recog an exponentially expanding number of times ;-)


Segher

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

* Re: [PATCH 4/6] rs6000: Delete some now-superfluous zero_ext{end,ract} patterns
  2015-05-10 16:16 ` [PATCH 4/6] rs6000: Delete some now-superfluous zero_ext{end,ract} patterns Segher Boessenkool
@ 2015-05-11 15:29   ` David Edelsohn
  0 siblings, 0 replies; 20+ messages in thread
From: David Edelsohn @ 2015-05-11 15:29 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: GCC Patches

On Sun, May 10, 2015 at 12:13 PM, Segher Boessenkool
<segher@kernel.crashing.org> wrote:
> After the change to combine, we no longer need all the special-case
> patterns.
>
> Tested on powerpc64-linux, as usual.  As mentioned with the combine
> patch, there are no differences to generated code in cc1.
>
> This does not delete DImode lshiftrt patterns, because those do not
> exist (yet).
>
> Is this okay for trunk?
>
>
> Segher
>
> [ Save the planet!  Delete 11% of your machine descriptions! ]
>
>
> 2015-05-10  Segher Boessenkool  <segher@kernel.crashing.org>
>
>         * config/rs6000/rs6000.md (extzv): FAIL for SImode.
>         (extzvsi_internal, *extzvsi_internal1, *extzvsi_internal2,
>         *rotlsi3_internal7le, *rotlsi3_internal7be, *rotlsi3_internal8le,
>         *rotlsi3_internal8be, *rotlsi3_internal9le, *rotlsi3_internal9be,
>         *rotlsi3_internal10le, *rotlsi3_internal10be, *rotlsi3_internal11le,
>         *rotlsi3_internal11be, *rotlsi3_internal12le, *rotlsi3_internal12be,
>         *lshiftrt_internal1le, *lshiftrt_internal1be, *lshiftrt_internal2le,
>         *lshiftrt_internal2be, *lshiftrt_internal3le, *lshiftrt_internal3be,
>         *lshiftrt_internal4le, *lshiftrt_internal4be, *lshiftrt_internal5le,
>         *lshiftrt_internal5be, *lshiftrt_internal5le, *lshiftrt_internal5be,
>         *rotldi3_internal7le, *rotldi3_internal7be, *rotldi3_internal8le,
>         *rotldi3_internal8be, *rotldi3_internal9le, *rotldi3_internal9be,
>         *rotldi3_internal10le, *rotldi3_internal10be, *rotldi3_internal11le,
>         *rotldi3_internal11be, *rotldi3_internal12le, *rotldi3_internal12be,
>         *rotldi3_internal13le, *rotldi3_internal13be, *rotldi3_internal14le,
>         *rotldi3_internal14be, *rotldi3_internal15le, *rotldi3_internal15be,
>         and 30 corresponding splitters): Delete.

Okay.

Thanks, David

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

* Re: [PATCH 5/6] rs6000: Don't use gen_rlwinm
  2015-05-10 16:16 ` [PATCH 5/6] rs6000: Don't use gen_rlwinm Segher Boessenkool
@ 2015-05-11 15:30   ` David Edelsohn
  0 siblings, 0 replies; 20+ messages in thread
From: David Edelsohn @ 2015-05-11 15:30 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: GCC Patches

On Sun, May 10, 2015 at 12:13 PM, Segher Boessenkool
<segher@kernel.crashing.org> wrote:
> The next patch will rename the "rlwinm" pattern (as well as the other patterns
> that implement rlwinm, now unnamed).  The only place that uses gen_rlwinm
> (an expander) is better off expanding the separate operations separately.
> Do so.
>
> Okay for trunk?
>
>
> Segher
>
>
> 2015-05-10  Segher Boessenkool  <segher@kernel.crashing.org>
>
>         * config/rs6000/rs6000.md (rs6000_adjust_atomic_subword): Use
>         gen_ashlsi3 and gen_andsi3 instead of gen_rlwinm.

Okay.

Thanks, David

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

* Re: [PATCH 6/6] rs6000: Clean up the various rlwinm patterns
  2015-05-10 16:16 ` [PATCH 6/6] rs6000: Clean up the various rlwinm patterns Segher Boessenkool
  2015-05-10 18:02   ` Maciej W. Rozycki
@ 2015-05-11 15:31   ` David Edelsohn
  1 sibling, 0 replies; 20+ messages in thread
From: David Edelsohn @ 2015-05-11 15:31 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: GCC Patches

On Sun, May 10, 2015 at 12:13 PM, Segher Boessenkool
<segher@kernel.crashing.org> wrote:
> Some cleanups:
>
> * Give every define_insn a name;
> * Add missing conditions for some of the dot forms;
> * Use define_insn_and_split to reduce duplication;
> * Renumber operands so 0,1,2,3 are the actual operands of the machine
>   instruction, in order;
> * Reformat some patterns.
>
> Is this okay for trunk?
>
>
> Segher
>
>
> 2015-05-10  Segher Boessenkool  <segher@kernel.crashing.org>
>
>         * config/rs6000/rs6000.md (*rotlsi3_internal4, *rotlsi3_internal5,
>         *rotlsi3_internal6, rlwinm, 5 unnamed define_insns, and 6
>         define_splits): Delete.
>         (*rotlsi3_mask, *rotlsi3_mask_dot, *rotlsi3_mask_dot2,
>         *ashlsi3_imm_mask, *ashlsi3_imm_mask_dot, *ashlsi3_imm_mask_dot2,
>         *lshrsi3_imm_mask, *lshrsi3_imm_mask_dot, *lshrsi3_imm_mask_dot2):
>         New.

Okay.

Thanks, David

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

* Re: [PATCH 3/6] rs6000: Don't use zero_extract in the bswap:HI splitter
  2015-05-10 16:15 ` [PATCH 3/6] rs6000: Don't use zero_extract in the bswap:HI splitter Segher Boessenkool
@ 2015-05-11 15:32   ` David Edelsohn
  0 siblings, 0 replies; 20+ messages in thread
From: David Edelsohn @ 2015-05-11 15:32 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: GCC Patches

On Sun, May 10, 2015 at 12:13 PM, Segher Boessenkool
<segher@kernel.crashing.org> wrote:
> The next patch removes the zero_extract insn this splits to.  Write
> it as (and (lshiftrt ... instead.
>
> Okay for trunk?
>
>
> Segher
>
>
> 2015-05-10  Segher Boessenkool  <segher@kernel.crashing.org>
>
>         * config/rs6000/rs6000.md (define_split for bswaphi): Don't use
>         zero_extract.

Okay.

Thanks, David

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

* Re: [PATCH 6/6] rs6000: Clean up the various rlwinm patterns
  2015-05-10 19:45     ` Segher Boessenkool
@ 2015-05-11 18:17       ` Maciej W. Rozycki
  0 siblings, 0 replies; 20+ messages in thread
From: Maciej W. Rozycki @ 2015-05-11 18:17 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, dje.gcc

On Sun, 10 May 2015, Segher Boessenkool wrote:

> >  This clearly renames rather than removing the `rlwinm' pattern, please 
> > correctly reflect that in ChangeLog.  Some other, unnamed patterns are 
> > given names rather than deleted as well, just as you've noted at the top.  
> > And none of the other changes are mentioned in your ChangeLog entry.
> 
> The changelog says it deletes the patterns with the old names.  Which it
> does.  And it adds the ones with the new names.  Which it does.  No one
> said changelogs are useful ;-)

 No one?  Well, I'm saying it now, then. :)

> >  Would you be able to split this change up further by any chance?  
> 
> I could, but it would be a lot of extra work.  First, I haven't done those
> steps in order (they aren't "steps" at all): I take one pattern, and fix
> it up, then the next, etc.

 Yeah, I know the pain, it's usually how it happens.  You start cleaning 
up things and then you find yourself having done a number conceptually 
independent changes that overlap one another in the source modified.  
I've been through it many times.

 The thing is this extra work of untangling is worth doing as it'll help 
the maintainer and other members of the community, including those 
investigating change history months if not years from now for one reason 
or another, understand what the consequences of conceptually individual 
changes are.

 Specifically which changes are obviously harmless (e.g. formatting 
changes or the addition of debug `*' pattern names) and which are 
potential trouble makers (e.g. the reordering of operands or folding 
`define_insn' and `define_split' into `define_insn_and_split'), that e.g. 
need to be taken into account when porting changes that may rely on them.  
When all the bits are lumped together, it's very difficult to decipher 
them and easy to miss something.

 So I've done such patch splitting and rearrangement many times, using 
various techniques.  For example it's often faster and easier if you 
hand-edit the patch being split into two rather than trying to reproduce 
the intermediate stage in the source being patched.  Other people may have 
other hints and tricks.

 Of course you'll want to keep the original final version of the file 
changed around and then you can compare it to the result of applying a 
patch series, to make sure both results are identical.

> But much worse: if you do tiny pattern changes like you suggest, I can
> guarantee you the patches _will_ mis-apply.  All of the time :-(

 Well, if you get the line numbers recorded in patches right, which is how 
`diff' generates them, then it won't happen.  And as a committer you can 
verify you applied your own patches correctly, by taking a diff against 
your original patched version before pushing the changes into the repo. 
Especially when other upstream source changes have since caused line 
numbers to shift.

> > change addresses a single issue only.  That would avoid problems with 
> > ChangeLog and make the review easier.
> 
> This isn't the first patch like this, I've cleaned up most other PowerPC
> integer patterns already.  It's enough work already.  Often the changes
> cannot be separated, and even if they can you then need them in the fixed
> order you made for them, etc.

 Of course changes can be separated (if they cannot, then they weren't 
really conceptually separate in the first place), and you do need to get 
the order right.  E.g. patches that are potentially of interest to older 
release branches need to go first, followed by ones that are meant to stay 
on trunk only.

 I'll leave it up to David to decide anyway as he's the port maintainer, 
and I'm only a member of the community who happened to poke at this port 
once or twice in the past.

  Maciej

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

* Re: [PATCH 2/6] combine: If recog fails, try again with zero_ext{ract,end} simplified
  2015-05-10 16:15 ` [PATCH 2/6] combine: If recog fails, try again with zero_ext{ract,end} simplified Segher Boessenkool
  2015-05-11  4:15   ` Jeff Law
@ 2015-05-12  8:25   ` Kyrill Tkachov
  2015-05-12 11:16     ` Segher Boessenkool
  1 sibling, 1 reply; 20+ messages in thread
From: Kyrill Tkachov @ 2015-05-12  8:25 UTC (permalink / raw)
  To: Segher Boessenkool, gcc-patches; +Cc: dje.gcc

Hi Segher,

On 10/05/15 17:13, Segher Boessenkool wrote:
> Combine has its own ideas of what is "canonical" RTL, forcing all
> backends to have special patterns in their machine description for the
> "more simplified" patterns combine often creates, even though the
> backend already has patterns for a more general form.  Backends that
> do not implement those patterns get less well optimised code.
>
> This patch lifts that burden for two cases: combine often converts
> an AND (with, say, 0xff) to a ZERO_EXTEND of a SUBREG; and an LSHIFTRT
> followed by an AND to a ZERO_EXTRACT.  This is perfectly helpful for
> e.g. MEMs, but not nice if you have instructions to do more generic
> masking (like PowerPC rlwinm, and similar on some other archs).
>
> With this patch, if recog_for_combine fails, and there are any
> ZERO_EXT* in the pattern to be matched, it tries again with those
> expressed as AND etc.  If that also fails it rolls back the changes,
> because it might still match after e.g. splitting, and we want to
> try the ZERO_EXT* for that as well.
>
> Tested on powerpc-linux, before and after removing many patterns
> from the machine description, and checked that the only changes in
> the bootstrapped compiler are new and removed functions.


Does this patch means we can remove any patterns in
the backend that look like:

-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-       (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                        (match_operand:SI 2 "const_int_operand" "i")
-                        (match_operand:SI 3 "const_int_operand" "i")))]


as long as we have an equivalent and-with-mask pattern?

Thanks,
Kyrill


>
> I'll also test on x86_64-linux before committing.
>
>
> Segher
>
>
> 2015-05-10  Segher Boessenkool   <segher@kernel.crashing.org>
>
> 	* combine.c (recog_for_combine_1): New function, factored out
> 	from recog_for_combine.
> 	(change_zero_ext): New function.
> 	(recog_for_combine): If recog fails, try again with the pattern
> 	modified by change_zero_ext; if that still fails, restore the
> 	pattern.
>
> ---
>   gcc/combine.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
>   1 file changed, 107 insertions(+), 13 deletions(-)
>
> diff --git a/gcc/combine.c b/gcc/combine.c
> index 1e4d65e..896d9d2 100644
> --- a/gcc/combine.c
> +++ b/gcc/combine.c
> @@ -10849,21 +10849,11 @@ simplify_shift_const (rtx x, enum rtx_code code, machine_mode result_mode,
>   }
>   
>   \f
> -/* Like recog, but we receive the address of a pointer to a new pattern.
> -   We try to match the rtx that the pointer points to.
> -   If that fails, we may try to modify or replace the pattern,
> -   storing the replacement into the same pointer object.
> -
> -   Modifications include deletion or addition of CLOBBERs.
> -
> -   PNOTES is a pointer to a location where any REG_UNUSED notes added for
> -   the CLOBBERs are placed.
> -
> -   The value is the final insn code from the pattern ultimately matched,
> -   or -1.  */
> +/* A subroutine of recog_for_combine.  See there for arguments and
> +   return value.  */
>   
>   static int
> -recog_for_combine (rtx *pnewpat, rtx_insn *insn, rtx *pnotes)
> +recog_for_combine_1 (rtx *pnewpat, rtx_insn *insn, rtx *pnotes)
>   {
>     rtx pat = *pnewpat;
>     rtx pat_without_clobbers;
> @@ -11010,6 +11000,110 @@ recog_for_combine (rtx *pnewpat, rtx_insn *insn, rtx *pnotes)
>   
>     return insn_code_number;
>   }
> +
> +/* Change every ZERO_EXTRACT and ZERO_EXTEND of a SUBREG that can be
> +   expressed as an AND and maybe an LSHIFTRT, to that formulation.
> +   Return whether anything was so changed.  */
> +
> +static bool
> +change_zero_ext (rtx *src)
> +{
> +  bool changed = false;
> +
> +  subrtx_ptr_iterator::array_type array;
> +  FOR_EACH_SUBRTX_PTR (iter, array, src, NONCONST)
> +    {
> +      rtx x = **iter;
> +      machine_mode mode = GET_MODE (x);
> +      int size;
> +
> +      if (GET_CODE (x) == ZERO_EXTRACT
> +	  && CONST_INT_P (XEXP (x, 1))
> +	  && CONST_INT_P (XEXP (x, 2))
> +	  && GET_MODE (XEXP (x, 0)) == mode)
> +	{
> +	  size = INTVAL (XEXP (x, 1));
> +
> +	  int start = INTVAL (XEXP (x, 2));
> +	  if (BITS_BIG_ENDIAN)
> +	    start = GET_MODE_PRECISION (mode) - size - start;
> +
> +	  x = gen_rtx_LSHIFTRT (mode, XEXP (x, 0), GEN_INT (start));
> +	}
> +      else if (GET_CODE (x) == ZERO_EXTEND
> +	       && GET_CODE (XEXP (x, 0)) == SUBREG
> +	       && GET_MODE (SUBREG_REG (XEXP (x, 0))) == mode
> +	       && subreg_lowpart_p (XEXP (x, 0)))
> +	{
> +	  size = GET_MODE_PRECISION (GET_MODE (XEXP (x, 0)));
> +	  x = SUBREG_REG (XEXP (x, 0));
> +	}
> +      else
> +	continue;
> +
> +      unsigned HOST_WIDE_INT mask = 1;
> +      mask <<= size;
> +      mask--;
> +
> +      x = gen_rtx_AND (mode, x, GEN_INT (mask));
> +
> +      SUBST (**iter, x);
> +      changed = true;
> +    }
> +
> +  return changed;
> +}
> +
> +/* Like recog, but we receive the address of a pointer to a new pattern.
> +   We try to match the rtx that the pointer points to.
> +   If that fails, we may try to modify or replace the pattern,
> +   storing the replacement into the same pointer object.
> +
> +   Modifications include deletion or addition of CLOBBERs.  If the
> +   instruction will still not match, we change ZERO_EXTEND and ZERO_EXTRACT
> +   to the equivalent AND and perhaps LSHIFTRT patterns, and try with that
> +   (and undo if that fails).
> +
> +   PNOTES is a pointer to a location where any REG_UNUSED notes added for
> +   the CLOBBERs are placed.
> +
> +   The value is the final insn code from the pattern ultimately matched,
> +   or -1.  */
> +
> +static int
> +recog_for_combine (rtx *pnewpat, rtx_insn *insn, rtx *pnotes)
> +{
> +  rtx pat = PATTERN (insn);
> +  int insn_code_number = recog_for_combine_1 (pnewpat, insn, pnotes);
> +  if (insn_code_number >= 0 || check_asm_operands (pat))
> +    return insn_code_number;
> +
> +  void *marker = get_undo_marker ();
> +  bool changed = false;
> +
> +  if (GET_CODE (pat) == SET)
> +    changed = change_zero_ext (&SET_SRC (pat));
> +  else if (GET_CODE (pat) == PARALLEL)
> +    {
> +      int i;
> +      for (i = 0; i < XVECLEN (pat, 0); i++)
> +	{
> +	  rtx set = XVECEXP (pat, 0, i);
> +	  if (GET_CODE (set) == SET)
> +	    changed |= change_zero_ext (&SET_SRC (set));
> +	}
> +    }
> +
> +  if (changed)
> +    {
> +      insn_code_number = recog_for_combine_1 (pnewpat, insn, pnotes);
> +
> +      if (insn_code_number < 0)
> +	undo_to_marker (marker);
> +    }
> +
> +  return insn_code_number;
> +}
>   \f
>   /* Like gen_lowpart_general but for use by combine.  In combine it
>      is not possible to create any new pseudoregs.  However, it is

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

* Re: [PATCH 2/6] combine: If recog fails, try again with zero_ext{ract,end} simplified
  2015-05-12  8:25   ` Kyrill Tkachov
@ 2015-05-12 11:16     ` Segher Boessenkool
  0 siblings, 0 replies; 20+ messages in thread
From: Segher Boessenkool @ 2015-05-12 11:16 UTC (permalink / raw)
  To: Kyrill Tkachov; +Cc: gcc-patches, dje.gcc

On Tue, May 12, 2015 at 09:20:18AM +0100, Kyrill Tkachov wrote:
> Does this patch means we can remove any patterns in
> the backend that look like:
> 
> -  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
> -       (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
> -                        (match_operand:SI 2 "const_int_operand" "i")
> -                        (match_operand:SI 3 "const_int_operand" "i")))]
> 
> 
> as long as we have an equivalent and-with-mask pattern?

Yes, exactly.  But you can also keep them, it will find either.

Older / CISC targets will usually want the zero_ext*, newer / RISC
targets will more often write something as AND (and LSHIFTRT).

You can also have both in the same target: for example, many targets
will want to write their plain zero_extend patterns as that, because
you want to allow both mem and reg in the same pattern, for reload.


Segher

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

* Re: [PATCH 0/6] Getting rid of some zero_ext* patterns
  2015-05-10 16:14 [PATCH 0/6] Getting rid of some zero_ext* patterns Segher Boessenkool
                   ` (5 preceding siblings ...)
  2015-05-10 16:16 ` [PATCH 5/6] rs6000: Don't use gen_rlwinm Segher Boessenkool
@ 2015-05-12 14:01 ` Segher Boessenkool
  6 siblings, 0 replies; 20+ messages in thread
From: Segher Boessenkool @ 2015-05-12 14:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: dje.gcc

On Sun, May 10, 2015 at 09:13:49AM -0700, Segher Boessenkool wrote:
> This series teaches combine to behave a bit better, and then takes
> advantage of that in the rs6000 backend.
> 
> I'll test the combine patches on x86_64-linux before committing,
> and will wait a bit for comments anyway.

Done now.


Segher

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

end of thread, other threads:[~2015-05-12 14:00 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-10 16:14 [PATCH 0/6] Getting rid of some zero_ext* patterns Segher Boessenkool
2015-05-10 16:14 ` [PATCH 1/6] combine: undo_to_marker Segher Boessenkool
2015-05-11  4:10   ` Jeff Law
2015-05-10 16:15 ` [PATCH 3/6] rs6000: Don't use zero_extract in the bswap:HI splitter Segher Boessenkool
2015-05-11 15:32   ` David Edelsohn
2015-05-10 16:15 ` [PATCH 2/6] combine: If recog fails, try again with zero_ext{ract,end} simplified Segher Boessenkool
2015-05-11  4:15   ` Jeff Law
2015-05-11  6:18     ` Segher Boessenkool
2015-05-12  8:25   ` Kyrill Tkachov
2015-05-12 11:16     ` Segher Boessenkool
2015-05-10 16:16 ` [PATCH 6/6] rs6000: Clean up the various rlwinm patterns Segher Boessenkool
2015-05-10 18:02   ` Maciej W. Rozycki
2015-05-10 19:45     ` Segher Boessenkool
2015-05-11 18:17       ` Maciej W. Rozycki
2015-05-11 15:31   ` David Edelsohn
2015-05-10 16:16 ` [PATCH 4/6] rs6000: Delete some now-superfluous zero_ext{end,ract} patterns Segher Boessenkool
2015-05-11 15:29   ` David Edelsohn
2015-05-10 16:16 ` [PATCH 5/6] rs6000: Don't use gen_rlwinm Segher Boessenkool
2015-05-11 15:30   ` David Edelsohn
2015-05-12 14:01 ` [PATCH 0/6] Getting rid of some zero_ext* patterns Segher Boessenkool

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