https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91202
Bug ID: 91202 Summary: Unnecessary promotion of shift operands Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: ubizjak at gmail dot com Target Milestone: --- Following testcase: --cut here-- unsigned char foo (unsigned char a, unsigned char b) { return a >> b; } --cut here-- does not need its operand to be promoted to int on targets that have shift instruction in QI and HI mode. Currently, gcc compiles the testcase (-O2) via _.original: --cut here-- ;; Function foo (null) ;; enabled by -tree-original { return (unsigned char) ((int) a >> (int) b); } --cut here-- and ._optimized: ;; Function foo (foo, funcdef_no=0, decl_uid=1907, cgraph_uid=1, symbol_order=0) --cut here-- foo (unsigned char a, unsigned char b) { int _1; int _2; int _3; unsigned char _6; <bb 2> [local count: 1073741824]: _1 = (int) a_4(D); _2 = (int) b_5(D); _3 = _1 >> _2; _6 = (unsigned char) _3; return _6; } --cut here-- to: movzbl %dil, %eax movl %esi, %ecx sarl %cl, %eax ret However, on targets that provide QImode shift, the above code could be emitted as: movzbl %dil, %eax movl %esi, %ecx shrb %cl, %al ret This optimization would help the following testcase: --cut here-- struct S1 { unsigned char val; unsigned char pad1; unsigned short pad2; }; struct S1 test_shrb (struct S1 a, unsigned char b) { a.val >>= b; return a; } --cut here-- that currently compiles to: movzbl %dil, %edx movl %esi, %ecx movl %edi, %eax sarl %cl, %edx movb %dl, %al ret but after PR91188 was fixed, the testcase could be compiled with the proposed optimization to: movl %edi, %eax movl %esi, %ecx shrb %cl, %al ret Please note that MSVC v19.21 implements the proposed optimization and generates: movzx eax, cl movzx ecx, dl shr al, cl ret 0