[Bug middle-end/91202] Unnecessary promotion of shift operands

ubizjak at gmail dot com gcc-bugzilla@gcc.gnu.org
Fri Jul 19 10:02:00 GMT 2019


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

--- Comment #8 from Uroš Bizjak <ubizjak at gmail dot com> ---
(In reply to Jakub Jelinek from comment #7)
> Perhaps we could define patterns for combine like:
>         (set (match_operand:SI 0 "register_operand" "=q")
>             (ashiftrt:SI (zero_extend:SI (match_operand:QI 1
> "register_operand" "q"))
>                 (match_operand:QI 2 "nonmemory_operand" "cI")))
>         (clobber (reg:CC 17 flags))
> etc. and split them before reload into an insn that does that with a
> subreg:QI followed by zero extension (or sign extension in certain cases)
> and then hope before reload the zero extension will be cancelled with the
> following subreg use (I guess we can't look at immediate uses during
> splitting).

The split pass is performed quite late in the game, and the narrowed insn would
miss combine pass (c.f. Comment #0 for optimization opportunity).

> The disadvantage would be that this would match even if we aren't using a
> subreg at the end, so would match even the case of:
> unsigned int foo (unsigned char a, unsigned char b)
> {
>   return a >> b;
> }
> and would change the movzbl %dil, %edi; shrq %cl, %edi into shrq %cl, %dil;
> movzbl %dil, %edi.  Dunno if that is acceptable.

I think that much cleaner solution would be to do the transformation in a kind
of "narrowing/widening" pass, as proposed by Richard in Comment #3. There, all
type data can be easily determined and operation can be narrowed if the target
provides adequate set of instructions.


More information about the Gcc-bugs mailing list