Hello!

We only have to copy registers without upper parts to a pseudo in
named patterns (extv, extzv and insv). Nowadays, it is the job of
TARGET_LEGITIMATE_COMBINED_INSN target hook to prevent propagation of
unwanted hard registers to a combined insn.

So, only check the supported mode in the predicate and let the target
hook do its job.

2016-12-30  Uros Bizjak  <ubiz...@gmail.com>

    * config/i386/predicates.md (ext_register_operand): Do not reject
    registers without upper parts here.
    * config/i386/i386.md (extv<mode>): Copy registers without
    upper parts in operand 1 to a pseudo.
    (extzv<mode>): Ditto.
    (insv<mode>): Ditto.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

The patch will be committed soon.

Uros.
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md (revision 243969)
+++ config/i386/i386.md (working copy)
@@ -2766,7 +2766,10 @@
   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
     FAIL;
 
-  if (! ext_register_operand (operands[1], VOIDmode))
+  unsigned int regno = reg_or_subregno (operands[1]);
+
+  /* Be careful to expand only with registers having upper parts.  */
+  if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
     operands[1] = copy_to_reg (operands[1]);
 })
 
@@ -2794,7 +2797,10 @@
   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
     FAIL;
 
-  if (! ext_register_operand (operands[1], VOIDmode))
+  unsigned int regno = reg_or_subregno (operands[1]);
+
+  /* Be careful to expand only with registers having upper parts.  */
+  if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
     operands[1] = copy_to_reg (operands[1]);
 })
 
@@ -2878,11 +2884,14 @@
   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
     FAIL;
 
-  dst = operands[0];
-  
-  if (!ext_register_operand (dst, VOIDmode))
-    dst = copy_to_reg (dst);
+  unsigned int regno = reg_or_subregno (operands[0]);
 
+  /* Be careful to expand only with registers having upper parts.  */
+  if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
+    dst = copy_to_reg (operands[0]);
+  else
+    dst = operands[0];
+
   emit_insn (gen_insv<mode>_1 (dst, operands[3]));
 
   /* Fix up the destination if needed.  */
Index: config/i386/predicates.md
===================================================================
--- config/i386/predicates.md   (revision 243969)
+++ config/i386/predicates.md   (working copy)
@@ -85,21 +85,14 @@
   (and (match_code "reg")
        (match_test "REGNO (op) == FLAGS_REG")))
 
-;; Match an SI or HImode register for a zero_extract.
+;; Match a DI, SI or HImode register for a zero_extract.
 (define_special_predicate "ext_register_operand"
-  (match_operand 0 "register_operand")
-{
-  if ((!TARGET_64BIT || GET_MODE (op) != DImode)
-      && GET_MODE (op) != SImode && GET_MODE (op) != HImode)
-    return false;
-  if (SUBREG_P (op))
-    op = SUBREG_REG (op);
+  (and (match_operand 0 "register_operand")
+       (ior (and (match_test "TARGET_64BIT")
+                (match_test "GET_MODE (op) == DImode"))
+           (match_test "GET_MODE (op) == SImode")
+           (match_test "GET_MODE (op) == HImode"))))
 
-  /* Be careful to accept only registers having upper parts.  */
-  return (REG_P (op)
-         && (REGNO (op) > LAST_VIRTUAL_REGISTER || QI_REGNO_P (REGNO (op))));
-})
-
 ;; Match register operands, but include memory operands for TARGET_SSE_MATH.
 (define_predicate "register_ssemem_operand"
   (if_then_else

Reply via email to