[Bug middle-end/91202] Unnecessary promotion of shift operands
jakub at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Jul 19 10:49:00 GMT 2019
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)
More information about the Gcc-bugs
mailing list