Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JIT] X64 - Recognize patterns to emit bts, btc, btr instructions #81512

Open
TIHan opened this issue Feb 1, 2023 · 4 comments
Open

[JIT] X64 - Recognize patterns to emit bts, btc, btr instructions #81512

TIHan opened this issue Feb 1, 2023 · 4 comments
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI tenet-performance Performance related issue
Milestone

Comments

@TIHan
Copy link
Contributor

TIHan commented Feb 1, 2023

@tannergooding and I were having a discussion and these examples were brought up.

public class C {
    static uint SetBit(int position, uint bits)
    {
        return bits | (1u << position);
    }

    static uint ToggleBit(int position, uint bits)
    {
        return bits ^ (1u << position);
    }

    static uint ResetBit(int position, uint bits)
    {
        return bits & ~(1u << position);
    }
}

These examples currently emit:

C.SetBit(Int32, UInt32)
    L0000: mov eax, 1
    L0005: shlx eax, eax, ecx
    L000a: or eax, edx
    L000c: ret

C.ToggleBit(Int32, UInt32)
    L0000: mov eax, 1
    L0005: shlx eax, eax, ecx
    L000a: xor eax, edx
    L000c: ret

C.ResetBit(Int32, UInt32)
    L0000: mov eax, 1
    L0005: shlx eax, eax, ecx
    L000a: andn eax, eax, edx
    L000f: ret

They could emit:

SetBit(int, unsigned int):                            # @SetBit(int, unsigned int)
        mov     eax, ecx
        bts     eax, edx
        ret
ToggleBit(int, unsigned int):                         # @ToggleBit(int, unsigned int)
        mov     eax, ecx
        btc     eax, edx
        ret
ResetBit(int, unsigned int):                          # @ResetBit(int, unsigned int)
        mov     eax, ecx
        btr     eax, edx
        ret

In XARCH LIR, we have a GT_BT already, we can just add three more GT_BTS, GT_BTC, GT_BTR and recognize the patterns above to transform to those ops in lowering.

Related: #27382

@TIHan TIHan added tenet-performance Performance related issue area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI labels Feb 1, 2023
@TIHan TIHan self-assigned this Feb 1, 2023
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Feb 1, 2023
@ghost
Copy link

ghost commented Feb 1, 2023

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch, @kunalspathak
See info in area-owners.md if you want to be subscribed.

Issue Details

@tannergooding and I were having a discussion and these examples were brought up.

public class C {
    static uint SetBit(int position, uint bits)
    {
        return bits | (1u << position);
    }

    static uint ToggleBit(int position, uint bits)
    {
        return bits ^ (1u << position);
    }

    static uint ResetBit(int position, uint bits)
    {
        return bits & ~(1u << position);
    }
}

These examples currently emit:

C.SetBit(Int32, UInt32)
    L0000: mov eax, 1
    L0005: shlx eax, eax, ecx
    L000a: or eax, edx
    L000c: ret

C.ToggleBit(Int32, UInt32)
    L0000: mov eax, 1
    L0005: shlx eax, eax, ecx
    L000a: xor eax, edx
    L000c: ret

C.ResetBit(Int32, UInt32)
    L0000: mov eax, 1
    L0005: shlx eax, eax, ecx
    L000a: andn eax, eax, edx
    L000f: ret

They could emit:

SetBit(int, unsigned int):                            # @SetBit(int, unsigned int)
        mov     eax, esi
        bts     eax, edi
        ret
ToggleBit(int, unsigned int):                         # @ToggleBit(int, unsigned int)
        mov     eax, esi
        btc     eax, edi
        ret
ResetBit(int, unsigned int):                          # @ResetBit(int, unsigned int)
        mov     eax, esi
        btr     eax, edi
        ret

In XARCH LIR, we have a GT_BT already, we can just add three more GT_BTS, GT_BTC, GT_BTR and recognize the patterns above to transform to those ops in lowering.

Related: #6815

Author: TIHan
Assignees: TIHan
Labels:

tenet-performance, area-CodeGen-coreclr

Milestone: -

@TIHan TIHan removed the untriaged New issue has not been triaged by the area owner label Feb 1, 2023
@xtqqczze
Copy link
Contributor

static uint SetBit(int position, uint bits) {}
static uint ToggleBit(int position, uint bits) {}
static uint ResetBit(int position, uint bits) {}

We could also implement these as public APIs in BitOperations?

@tannergooding
Copy link
Member

Exposing the apis via public helpers is a separate consideration and one that would need to be in its own API proposal

@JulieLeeMSFT JulieLeeMSFT added the needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration label Apr 13, 2023
@JulieLeeMSFT JulieLeeMSFT added this to the Future milestone Apr 13, 2023
@xtqqczze
Copy link
Contributor

xtqqczze commented Jun 8, 2023

Merged in #83400:

/// <summary>
/// Flip the bit at a specific position in a given value.
/// Similar in behavior to the x86 instruction BTC (Bit Test and Complement).
/// </summary>
/// <param name="value">The value.</param>
/// <param name="index">The zero-based index of the bit to flip.
/// Any value outside the range [0..31] is treated as congruent mod 32.</param>
/// <returns>The new value.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static uint FlipBit(uint value, int index)
{
return value ^ (1u << index);
}

@BruceForstall BruceForstall removed the needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration label Oct 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI tenet-performance Performance related issue
Projects
None yet
Development

No branches or pull requests

5 participants