https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91202

--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I've tried:
--- gcc/config/i386/i386.md.jj  2019-07-19 11:56:10.475964435 +0200
+++ gcc/config/i386/i386.md     2019-07-19 12:43:52.461469500 +0200
@@ -10661,6 +10661,43 @@
   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
   [(set_attr "type" "multi")])

+(define_insn_and_split "*shrqi3_3"
+  [(set (match_operand:SI 0 "register_operand")
+       (ashiftrt:SI
+         (zero_extend:SI (match_operand:QI 1 "register_operand"))
+         (match_operand:QI 2 "nonmemory_operand")))
+   (clobber (reg:CC FLAGS_REG))]
+  ""
+  "#"
+  "&& 1"
+  [(parallel
+     [(set (match_dup 3)
+          (subreg:QI (ashiftrt:SI
+                       (zero_extend:SI (match_dup 1))
+                       (match_dup 2)) 0))
+      (clobber (reg:CC FLAGS_REG))])
+   (set (match_dup 0) (zero_extend:SI (match_dup 3)))]
+{
+  operands[3] = (can_create_pseudo_p ()
+                ? gen_reg_rtx (QImode) : gen_lowpart (QImode, operands[0]));
+})
+
+(define_insn "*shrqi3_4"
+  [(set (match_operand:QI 0 "register_operand" "=q")
+       (subreg:QI
+         (ashiftrt:SI
+           (zero_extend:SI (match_operand:QI 1 "register_operand" "0"))
+           (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
+   (clobber (reg:CC FLAGS_REG))]
+  ""
+{
+  if (operands[2] == const1_rtx
+      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+    return "shr{q}\t%0";
+  else
+    return "shr{q}\t{%2, %0|%0, %2}";
+})
+
 ;; By default we don't ask for a scratch register, because when DWImode
 ;; values are manipulated, registers are already at a premium.  But if
 ;; we have one handy, we won't turn it away.
and surprisingly, not just before RA, but even after it nothing will optimize
away the extra zero extend.
unsigned char foo (unsigned char a, unsigned char b) { return a >> b; }
void bar (unsigned char a, unsigned char b, unsigned char *c) { *c = a >> b; }
changes with the patch as:
-       movzbl  %dil, %eax
        movl    %esi, %ecx
-       sarl    %cl, %eax
+       shrq    %cl, %dil
+       movzbl  %dil, %eax
and:
-       movzbl  %dil, %edi
        movl    %esi, %ecx
-       sarl    %cl, %edi
+       shrq    %cl, %dil
+       movzbl  %dil, %edi
        movb    %dil, (%rdx)

Reply via email to