Skip to content

[Intel] Failure to shift-in one bits via shld #168862

@Validark

Description

@Validark

Zig Godbolt

Attempt 1:

export fn shift_in_ones(a: u64, c: u8) u64 {
    return ~(~a << @truncate(c));
}
shift_in_ones:
        not     rdi
        shlx    rax, rdi, rsi
        not     rax
        ret

Attempt 2:

export fn shld(a: u64, b: u64, c: u8) u64 {
    return @truncate(@as(u128, @bitCast([2]u64{ a, b })) << @as(u6, @truncate(c)) >> 64);
}

export fn shift_in_ones_2(a: u64, c: u8) u64 {
    return shld(~@as(u64, 0), a, c);
}
shld:
        mov     ecx, edx
        mov     rax, rsi
        shld    rax, rdi, cl
        ret

shift_in_ones_2: ; for some reason inlining makes us not see that this a `shld`?
        shlx    rcx, rdi, rsi
        and     sil, 63
        not     sil
        movabs  rax, 9223372036854775807
        shrx    rax, rax, rsi
        or      rax, rcx
        ret

Should be:

shift_in_ones:
        mov     ecx, esi
        mov     rax, rdi
        mov     rdx, -1
        shld    rax, rdx, cl
        ret

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions