Skip to content

Feature request: Native bitshift operation #50225

Open
@jakobnissen

Description

@jakobnissen

The definition for Base.:>>>, Base.:>> and Base.:<< do not compile to native shift instructions, because they need to handle the case where the integer is shifted by more than the integer bitwidth:

julia> @code_native debuginfo=:none dump_module=false 1 >> 1
        .text
        pushq   %rbp
        movq    %rsp, %rbp
        cmpq    $63, %rsi
        movl    $63, %ecx
        cmovbl  %esi, %ecx
        movq    %rdi, %rdx
        sarq    %cl, %rdx
        movq    %rsi, %rcx
        negq    %rcx
        shlq    %cl, %rdi
        xorl    %eax, %eax
        cmpq    $64, %rcx
        cmovbq  %rdi, %rax
        testq   %rsi, %rsi
        cmovnsq %rdx, %rax
        popq    %rbp
        retq
        nopw    %cs:(%rax,%rax)

Often, this extra complication is not necessary, and it is possible to create a more effective bitshift operation by allowing overflow. This is completely analogous to how Base.:+ is more efficient than a saturating add, because it allows overflow:

julia> f(x, i) = x >> (i & (8*sizeof(i)-1));

julia> @code_native debuginfo=:none dump_module=false f(1, 1)
        .text
        pushq   %rbp
        movq    %rsp, %rbp
        sarxq   %rsi, %rdi, %rax
        popq    %rbp
        retq
        nopl    (%rax,%rax)

I find myself using that pattern relatively often, but this bit-twiddling trick is a little obscure, so readers may not understand what the function is doing, and may not know that this trick is available.
It would be nice if Base provided these very basic operations for users interested in high performance bit-twiddling.

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureIndicates new feature / enhancement requests

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions