From 934f2a969d159429bd6bf4797e32a020089a103a Mon Sep 17 00:00:00 2001
From: Uros Bizjak <ubizjak@gmail.com>
Date: Fri, 27 Jun 2008 22:53:34 +0200
Subject: [PATCH] i386.md (ashlti3, [...]): Expand using
 ix86_expand_binary_operator directly.

	* config/i386/i386.md (ashlti3, ashrti3, lshrti3): Expand using
	ix86_expand_binary_operator directly.
	(*ashlti3_1): Rename from ashlti3_1.  Use nonmemory_operand predicate
	for operand 2.
	(*ashrti3_1): Ditto.
	(*lshrti3_1): Ditto.
	(*ashlti3_2, *ashrti3_2, *lshrti3_2): Remove insn patterns.
	(ashlti, ashrti and lshrti splitters): Handle nonmemory operand 2
	using only one splitter.  Conditionaly execute splitter before or
	after peephole2 pass.
	(ashlti, ashrti and lshrti peephole2): Define peephole2 patterns.
	(x86_shld): Rename from x86_shld_1.  Compress operand 2 constraints.
	Use only one alternative in asm template.
	(x86_64_shld): Compress operand 2 constraints. Use only one alternative
	in asm template.
	(*ashldi3_cmp_rex64): Use const_1_to_63_operand operand predicate and
	"J" operand constraint for operand 2.
	(*ashldi3_cconly_rex64): Ditto.
	(*ashrdi3_cmp_rex64): Ditto.
	(*ashrdi3_cconly_rex64): Ditto.
	(*lshrdi3_cmp_rex64): Ditto.
	(*lshrdi3_cconly_rex64): Ditto.
	* config/i386/predicates.md (const_1_to_63_operand): New predicate.
	* config/i386/i386.md (print_operand) ['s']: Print ", " using fputs.
	(split_ashr, split_ashl, split_lshr): Use gen_x86_shrd instead of
	gen_x86_shrd_1.

From-SVN: r137201
---
 gcc/ChangeLog                 |  29 +++++
 gcc/config/i386/i386.c        |  14 +--
 gcc/config/i386/i386.md       | 221 +++++++++++++---------------------
 gcc/config/i386/predicates.md |   6 +
 4 files changed, 123 insertions(+), 147 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ef3bf5fb4fd1..de6e75b53e89 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,32 @@
+2008-06-27 Uros Bizjak  <ubizjak@gmail.com>
+
+	* config/i386/i386.md (ashlti3, ashrti3, lshrti3): Expand using
+	ix86_expand_binary_operator directly.
+	(*ashlti3_1): Rename from ashlti3_1.  Use nonmemory_operand predicate
+	for operand 2.
+	(*ashrti3_1): Ditto.
+	(*lshrti3_1): Ditto.
+	(*ashlti3_2, *ashrti3_2, *lshrti3_2): Remove insn patterns.
+	(ashlti, ashrti and lshrti splitters): Handle nonmemory operand 2
+	using only one splitter.  Conditionaly execute splitter before or
+	after peephole2 pass.
+	(ashlti, ashrti and lshrti peephole2): Define peephole2 patterns.
+	(x86_shld): Rename from x86_shld_1.  Compress operand 2 constraints.
+	Use only one alternative in asm template.
+	(x86_64_shld): Compress operand 2 constraints. Use only one alternative
+	in asm template.
+	(*ashldi3_cmp_rex64): Use const_1_to_63_operand operand predicate and
+	"J" operand constraint for operand 2.
+	(*ashldi3_cconly_rex64): Ditto.
+	(*ashrdi3_cmp_rex64): Ditto.
+	(*ashrdi3_cconly_rex64): Ditto.
+	(*lshrdi3_cmp_rex64): Ditto.
+	(*lshrdi3_cconly_rex64): Ditto.
+	* config/i386/predicates.md (const_1_to_63_operand): New predicate.
+	* config/i386/i386.md (print_operand) ['s']: Print ", " using fputs.
+	(split_ashr, split_ashl, split_lshr): Use gen_x86_shrd instead of
+	gen_x86_shrd_1.
+
 2008-06-27  Jakub Jelinek  <jakub@redhat.com>
 
 	* gimplify.c (omp_is_private): Don't return true if decl
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 319d0b7f6615..38b4477b1c37 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -9207,7 +9207,7 @@ print_operand (FILE *file, rtx x, int code)
 	  if (CONST_INT_P (x) || ! SHIFT_DOUBLE_OMITS_COUNT)
 	    {
 	      PRINT_OPERAND (file, x, 0);
-	      putc (',', file);
+	      fputs (", ", file);
 	    }
 	  return;
 
@@ -14542,7 +14542,7 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode)
 	  if (!rtx_equal_p (operands[0], operands[1]))
 	    emit_move_insn (operands[0], operands[1]);
 	  emit_insn ((mode == DImode
-		     ? gen_x86_shld_1
+		     ? gen_x86_shld
 		     : gen_x86_64_shld) (high[0], low[0], GEN_INT (count)));
 	  ix86_expand_ashl_const (low[0], count, mode);
 	}
@@ -14627,7 +14627,7 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode)
 
       (mode == DImode ? split_di : split_ti) (operands, 1, low, high);
       emit_insn ((mode == DImode
-		  ? gen_x86_shld_1
+		  ? gen_x86_shld
 		  : gen_x86_64_shld) (high[0], low[0], operands[2]));
     }
 
@@ -14685,7 +14685,7 @@ ix86_split_ashr (rtx *operands, rtx scratch, enum machine_mode mode)
 	  if (!rtx_equal_p (operands[0], operands[1]))
 	    emit_move_insn (operands[0], operands[1]);
 	  emit_insn ((mode == DImode
-		      ? gen_x86_shrd_1
+		      ? gen_x86_shrd
 		      : gen_x86_64_shrd) (low[0], high[0], GEN_INT (count)));
 	  emit_insn ((mode == DImode
 		      ? gen_ashrsi3
@@ -14700,7 +14700,7 @@ ix86_split_ashr (rtx *operands, rtx scratch, enum machine_mode mode)
       (mode == DImode ? split_di : split_ti) (operands, 1, low, high);
 
       emit_insn ((mode == DImode
-		  ? gen_x86_shrd_1
+		  ? gen_x86_shrd
 		  : gen_x86_64_shrd) (low[0], high[0], operands[2]));
       emit_insn ((mode == DImode
 		  ? gen_ashrsi3
@@ -14751,7 +14751,7 @@ ix86_split_lshr (rtx *operands, rtx scratch, enum machine_mode mode)
 	  if (!rtx_equal_p (operands[0], operands[1]))
 	    emit_move_insn (operands[0], operands[1]);
 	  emit_insn ((mode == DImode
-		      ? gen_x86_shrd_1
+		      ? gen_x86_shrd
 		      : gen_x86_64_shrd) (low[0], high[0], GEN_INT (count)));
 	  emit_insn ((mode == DImode
 		      ? gen_lshrsi3
@@ -14766,7 +14766,7 @@ ix86_split_lshr (rtx *operands, rtx scratch, enum machine_mode mode)
       (mode == DImode ? split_di : split_ti) (operands, 1, low, high);
 
       emit_insn ((mode == DImode
-		  ? gen_x86_shrd_1
+		  ? gen_x86_shrd
 		  : gen_x86_64_shrd) (low[0], high[0], operands[2]));
       emit_insn ((mode == DImode
 		  ? gen_lshrsi3
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index b3b9e90d57b7..36e812f33fd9 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -10849,33 +10849,14 @@
 ;; than 31.
 
 (define_expand "ashlti3"
-  [(parallel [(set (match_operand:TI 0 "register_operand" "")
-		   (ashift:TI (match_operand:TI 1 "register_operand" "")
-			      (match_operand:QI 2 "nonmemory_operand" "")))
-	      (clobber (reg:CC FLAGS_REG))])]
-  "TARGET_64BIT"
-{
-  if (! immediate_operand (operands[2], QImode))
-    {
-      emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
-      DONE;
-    }
-  ix86_expand_binary_operator (ASHIFT, TImode, operands);
-  DONE;
-})
-
-(define_insn "ashlti3_1"
-  [(set (match_operand:TI 0 "register_operand" "=r")
-	(ashift:TI (match_operand:TI 1 "register_operand" "0")
-		   (match_operand:QI 2 "register_operand" "c")))
-   (clobber (match_scratch:DI 3 "=&r"))
-   (clobber (reg:CC FLAGS_REG))]
+  [(set (match_operand:TI 0 "register_operand" "")
+	(ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
+		   (match_operand:QI 2 "nonmemory_operand" "")))]
   "TARGET_64BIT"
-  "#"
-  [(set_attr "type" "multi")])
+  "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
 
-;; This pattern must be defined before *ashlti3_2 to prevent
-;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
+;; This pattern must be defined before *ashlti3_1 to prevent
+;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
 
 (define_insn "sse2_ashlti3"
   [(set (match_operand:TI 0 "register_operand" "=x")
@@ -10890,45 +10871,45 @@
    (set_attr "prefix_data16" "1")
    (set_attr "mode" "TI")])
 
-(define_insn "*ashlti3_2"
-  [(set (match_operand:TI 0 "register_operand" "=r")
-	(ashift:TI (match_operand:TI 1 "register_operand" "0")
-		   (match_operand:QI 2 "immediate_operand" "O")))
+(define_insn "*ashlti3_1"
+  [(set (match_operand:TI 0 "register_operand" "=&r,r")
+	(ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
+		   (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT"
   "#"
   [(set_attr "type" "multi")])
 
-(define_split
-  [(set (match_operand:TI 0 "register_operand" "")
-	(ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
-		   (match_operand:QI 2 "register_operand" "")))
-   (clobber (match_scratch:DI 3 ""))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && reload_completed"
+(define_peephole2
+  [(match_scratch:DI 3 "r")
+   (parallel [(set (match_operand:TI 0 "register_operand" "")
+		   (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
+			      (match_operand:QI 2 "nonmemory_operand" "")))
+	      (clobber (reg:CC FLAGS_REG))])
+   (match_dup 3)]
+  "TARGET_64BIT"
   [(const_int 0)]
   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
 
 (define_split
   [(set (match_operand:TI 0 "register_operand" "")
-	(ashift:TI (match_operand:TI 1 "register_operand" "")
-		   (match_operand:QI 2 "immediate_operand" "")))
+	(ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
+		   (match_operand:QI 2 "nonmemory_operand" "")))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && reload_completed"
+  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
+		    ? epilogue_completed : reload_completed)"
   [(const_int 0)]
   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
 
 (define_insn "x86_64_shld"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
+  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
         (ior:DI (ashift:DI (match_dup 0)
-		  (match_operand:QI 2 "nonmemory_operand" "J,c"))
-		(lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
+		  (match_operand:QI 2 "nonmemory_operand" "Jc"))
+		(lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
 		  (minus:QI (const_int 64) (match_dup 2)))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT"
-  "@
-   shld{q}\t{%2, %1, %0|%0, %1, %2}
-   shld{q}\t{%s2%1, %0|%0, %1, %2}"
+  "shld{q}\t{%s2%1, %0|%0, %1, %2}"
   [(set_attr "type" "ishift")
    (set_attr "prefix_0f" "1")
    (set_attr "mode" "DI")
@@ -11021,7 +11002,7 @@
   [(set (reg FLAGS_REG)
 	(compare
 	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
-		     (match_operand:QI 2 "immediate_operand" "e"))
+		     (match_operand:QI 2 "const_1_to_63_operand" "J"))
 	  (const_int 0)))
    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
 	(ashift:DI (match_dup 1) (match_dup 2)))]
@@ -11064,7 +11045,7 @@
   [(set (reg FLAGS_REG)
 	(compare
 	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
-		     (match_operand:QI 2 "immediate_operand" "e"))
+		     (match_operand:QI 2 "const_1_to_63_operand" "J"))
 	  (const_int 0)))
    (clobber (match_scratch:DI 0 "=r"))]
   "TARGET_64BIT
@@ -11135,17 +11116,15 @@
   [(const_int 0)]
   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
 
-(define_insn "x86_shld_1"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
+(define_insn "x86_shld"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
         (ior:SI (ashift:SI (match_dup 0)
-		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
-		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
+		  (match_operand:QI 2 "nonmemory_operand" "Ic"))
+		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
 		  (minus:QI (const_int 32) (match_dup 2)))))
    (clobber (reg:CC FLAGS_REG))]
   ""
-  "@
-   shld{l}\t{%2, %1, %0|%0, %1, %2}
-   shld{l}\t{%s2%1, %0|%0, %1, %2}"
+  "shld{l}\t{%s2%1, %0|%0, %1, %2}"
   [(set_attr "type" "ishift")
    (set_attr "prefix_0f" "1")
    (set_attr "mode" "SI")
@@ -11845,70 +11824,51 @@
 ;; See comment above `ashldi3' about how this works.
 
 (define_expand "ashrti3"
-  [(parallel [(set (match_operand:TI 0 "register_operand" "")
-		   (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
-				(match_operand:QI 2 "nonmemory_operand" "")))
-	      (clobber (reg:CC FLAGS_REG))])]
+  [(set (match_operand:TI 0 "register_operand" "")
+	(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
+		     (match_operand:QI 2 "nonmemory_operand" "")))]
   "TARGET_64BIT"
-{
-  if (! immediate_operand (operands[2], QImode))
-    {
-      emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
-      DONE;
-    }
-  ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
-  DONE;
-})
+  "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
 
-(define_insn "ashrti3_1"
+(define_insn "*ashrti3_1"
   [(set (match_operand:TI 0 "register_operand" "=r")
 	(ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
-		     (match_operand:QI 2 "register_operand" "c")))
-   (clobber (match_scratch:DI 3 "=&r"))
+		     (match_operand:QI 2 "nonmemory_operand" "Oc")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT"
   "#"
   [(set_attr "type" "multi")])
 
-(define_insn "*ashrti3_2"
-  [(set (match_operand:TI 0 "register_operand" "=r")
-	(ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
-		     (match_operand:QI 2 "immediate_operand" "O")))
-   (clobber (reg:CC FLAGS_REG))]
+(define_peephole2
+  [(match_scratch:DI 3 "r")
+   (parallel [(set (match_operand:TI 0 "register_operand" "")
+		   (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
+			        (match_operand:QI 2 "nonmemory_operand" "")))
+	      (clobber (reg:CC FLAGS_REG))])
+   (match_dup 3)]
   "TARGET_64BIT"
-  "#"
-  [(set_attr "type" "multi")])
-
-(define_split
-  [(set (match_operand:TI 0 "register_operand" "")
-	(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
-		     (match_operand:QI 2 "register_operand" "")))
-   (clobber (match_scratch:DI 3 ""))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && reload_completed"
   [(const_int 0)]
   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
 
 (define_split
   [(set (match_operand:TI 0 "register_operand" "")
 	(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
-		     (match_operand:QI 2 "immediate_operand" "")))
+		     (match_operand:QI 2 "nonmemory_operand" "")))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && reload_completed"
+  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
+		    ? epilogue_completed : reload_completed)"
   [(const_int 0)]
   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
 
 (define_insn "x86_64_shrd"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
+  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
         (ior:DI (ashiftrt:DI (match_dup 0)
-		  (match_operand:QI 2 "nonmemory_operand" "J,c"))
-		(ashift:DI (match_operand:DI 1 "register_operand" "r,r")
+		  (match_operand:QI 2 "nonmemory_operand" "Jc"))
+		(ashift:DI (match_operand:DI 1 "register_operand" "r")
 		  (minus:QI (const_int 64) (match_dup 2)))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT"
-  "@
-   shrd{q}\t{%2, %1, %0|%0, %1, %2}
-   shrd{q}\t{%s2%1, %0|%0, %1, %2}"
+  "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
   [(set_attr "type" "ishift")
    (set_attr "prefix_0f" "1")
    (set_attr "mode" "DI")
@@ -12010,7 +11970,7 @@
   [(set (reg FLAGS_REG)
 	(compare
 	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
-		       (match_operand:QI 2 "const_int_operand" "n"))
+		       (match_operand:QI 2 "const_1_to_63_operand" "J"))
 	  (const_int 0)))
    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
 	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
@@ -12026,7 +11986,7 @@
   [(set (reg FLAGS_REG)
 	(compare
 	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
-		       (match_operand:QI 2 "const_int_operand" "n"))
+		       (match_operand:QI 2 "const_1_to_63_operand" "J"))
 	  (const_int 0)))
    (clobber (match_scratch:DI 0 "=r"))]
   "TARGET_64BIT
@@ -12070,17 +12030,15 @@
   [(const_int 0)]
   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
 
-(define_insn "x86_shrd_1"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
+(define_insn "x86_shrd"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
         (ior:SI (ashiftrt:SI (match_dup 0)
-		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
-		(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
+		  (match_operand:QI 2 "nonmemory_operand" "Ic"))
+		(ashift:SI (match_operand:SI 1 "register_operand" "r")
 		  (minus:QI (const_int 32) (match_dup 2)))))
    (clobber (reg:CC FLAGS_REG))]
   ""
-  "@
-   shrd{l}\t{%2, %1, %0|%0, %1, %2}
-   shrd{l}\t{%s2%1, %0|%0, %1, %2}"
+  "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
   [(set_attr "type" "ishift")
    (set_attr "prefix_0f" "1")
    (set_attr "pent_pair" "np")
@@ -12540,33 +12498,14 @@
 ;; See comment above `ashldi3' about how this works.
 
 (define_expand "lshrti3"
-  [(parallel [(set (match_operand:TI 0 "register_operand" "")
-		   (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
-			        (match_operand:QI 2 "nonmemory_operand" "")))
-	      (clobber (reg:CC FLAGS_REG))])]
-  "TARGET_64BIT"
-{
-  if (! immediate_operand (operands[2], QImode))
-    {
-      emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
-      DONE;
-    }
-  ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
-  DONE;
-})
-
-(define_insn "lshrti3_1"
-  [(set (match_operand:TI 0 "register_operand" "=r")
-	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
-		     (match_operand:QI 2 "register_operand" "c")))
-   (clobber (match_scratch:DI 3 "=&r"))
-   (clobber (reg:CC FLAGS_REG))]
+  [(set (match_operand:TI 0 "register_operand" "")
+	(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
+		     (match_operand:QI 2 "nonmemory_operand" "")))]
   "TARGET_64BIT"
-  "#"
-  [(set_attr "type" "multi")])
+  "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
 
-;; This pattern must be defined before *lshrti3_2 to prevent
-;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
+;; This pattern must be defined before *lshrti3_1 to prevent
+;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
 
 (define_insn "sse2_lshrti3"
   [(set (match_operand:TI 0 "register_operand" "=x")
@@ -12581,31 +12520,33 @@
    (set_attr "prefix_data16" "1")
    (set_attr "mode" "TI")])
 
-(define_insn "*lshrti3_2"
+(define_insn "*lshrti3_1"
   [(set (match_operand:TI 0 "register_operand" "=r")
 	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
-		     (match_operand:QI 2 "immediate_operand" "O")))
+		     (match_operand:QI 2 "nonmemory_operand" "Oc")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT"
   "#"
   [(set_attr "type" "multi")])
 
-(define_split
-  [(set (match_operand:TI 0 "register_operand" "")
-	(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
-		     (match_operand:QI 2 "register_operand" "")))
-   (clobber (match_scratch:DI 3 ""))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && reload_completed"
+(define_peephole2
+  [(match_scratch:DI 3 "r")
+   (parallel [(set (match_operand:TI 0 "register_operand" "")
+		   (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
+			        (match_operand:QI 2 "nonmemory_operand" "")))
+	      (clobber (reg:CC FLAGS_REG))])
+   (match_dup 3)]
+  "TARGET_64BIT"
   [(const_int 0)]
   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
 
 (define_split
   [(set (match_operand:TI 0 "register_operand" "")
 	(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
-		     (match_operand:QI 2 "immediate_operand" "")))
+		     (match_operand:QI 2 "nonmemory_operand" "")))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && reload_completed"
+  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
+		     ? epilogue_completed : reload_completed)"
   [(const_int 0)]
   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
 
@@ -12687,7 +12628,7 @@
   [(set (reg FLAGS_REG)
 	(compare
 	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
-		       (match_operand:QI 2 "const_int_operand" "e"))
+		       (match_operand:QI 2 "const_1_to_63_operand" "J"))
 	  (const_int 0)))
    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
 	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
@@ -12703,7 +12644,7 @@
   [(set (reg FLAGS_REG)
 	(compare
 	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
-		       (match_operand:QI 2 "const_int_operand" "e"))
+		       (match_operand:QI 2 "const_1_to_63_operand" "J"))
 	  (const_int 0)))
    (clobber (match_scratch:DI 0 "=r"))]
   "TARGET_64BIT
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 4f2ff6b7c9f6..f36c6d4cc4af 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -629,6 +629,12 @@
   (and (match_code "const_int")
        (match_test "IN_RANGE (INTVAL (op), 1, 31)")))
 
+;; Return nonzero if OP is CONST_INT >= 1 and <= 63 (a valid operand
+;; for 64bit shift & compare patterns, as shifting by 0 does not change flags).
+(define_predicate "const_1_to_63_operand"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (INTVAL (op), 1, 63)")))
+
 ;; Match 2 or 3.
 (define_predicate "const_2_to_3_operand"
   (and (match_code "const_int")
-- 
GitLab