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)