Skip to content

arm64: Add support for BFI and BFX instruction - #123138

Merged
jakobbotsch merged 28 commits into
dotnet:mainfrom
jonathandavies-arm:upstream/co/bitfield-manipulation
Jun 12, 2026
Merged

arm64: Add support for BFI and BFX instruction#123138
jakobbotsch merged 28 commits into
dotnet:mainfrom
jonathandavies-arm:upstream/co/bitfield-manipulation

Conversation

@jonathandavies-arm

Copy link
Copy Markdown
Contributor

This patch adds support for the Arm BFI and BFX instructions. I've added a optimisation in lowering for bit packing and unpacking using each instruction respectively.

BFI

This is used when you pack 2 or more values into an integer. e.g.
return (a & 0xf) | ((b & 0x3) << 4);
This is the node pattern it is looking for

N009 ( 9, 12) [000008] -----+----- * OR int $103
N003 ( 3, 4) [000002] -----+----- +--* AND int $100
N001 ( 1, 1) [000000] -----+----- | +--* LCL_VAR int V00 arg0 u:1 (last use) $80
N002 ( 1, 2) [000001] -c---+----- | \--* CNS_INT int 15 $43
N008 ( 5, 7) [000007] -----+----- \--* LSH int $102
N006 ( 3, 4) [000005] -----+----- +--* AND int $101
N004 ( 1, 1) [000003] -----+----- | +--* LCL_VAR int V01 arg1 u:1 (last use) $81
N005 ( 1, 2) [000004] -c---+----- | \--* CNS_INT int 3 $44
N007 ( 1, 2) [000006] -c---+----- \--* CNS_INT int 4 $45

and changes to

 ( 9, 12) [000011] ----------- \--* BFI int N003 ( 3, 4) [000002] -----+----- +--* AND int $100
N001 ( 1, 1) [000000] -----+----- | +--* LCL_VAR int V00 arg0 u:1 (last use) $80
N002 ( 1, 2) [000001] -c---+----- | \--* CNS_INT int 15 $43
N004 ( 1, 1) [000003] -----+----- \--* LCL_VAR int V01 arg1 u:1 (last use) $81

BFX

When you extract a continuous range of bits from an integer. This is the inverse of above. e.g.
return (x >> 5) & 0x1F;

This is the node pattern it's looking for

N005 ( 5, 7) [000004] -----+----- \--* AND int $101
N003 ( 3, 4) [000002] -----+----- +--* RSH int $100
N001 ( 1, 1) [000000] -----+----- | +--* LCL_VAR int V00 arg0 u:1 (last use) $80
N002 ( 1, 2) [000001] -----+----- | \--* CNS_INT int 6 $42
N004 ( 1, 2) [000003] -----+----- \--* CNS_INT int 63 $43

and changes to

 ( 5, 7) [000007] ----------- \--* BFX int N001 ( 1, 1) [000000] -----+----- \--* LCL_VAR int V00 arg0 u:1 (last use) $80

@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Jan 13, 2026
@dotnet-policy-servicedotnet-policy-serviceBot added the community-contribution Indicates that the PR has been added by a community member label Jan 13, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

@jonathandavies-arm
jonathandavies-armforce-pushed the upstream/co/bitfield-manipulation branch from ce512bf to 1a8d58fCompareJanuary 19, 2026 11:18
@a74nh

Copy link
Copy Markdown
Contributor

Spmidiff errors

[05:14:28] ISSUE: <ASSERT> #9081 /Users/runner/work/1/s/src/coreclr/jit/codegenarm64.cpp (5916) - Assertion failed '(lsb + width) <= bitWidth' in 'Microsoft.AspNetCore.Connections.CorrelationIdGenerator+<>c:<GenerateId>b__3_0(System.Span`1[char],long):this' during 'Generate code' (IL size 267; hash 0xbd4b4083; Tier1)

https://helixr1107v0xdeko0k025g8.blob.core.windows.net/dotnet-runtime-refs-pull-123138-merge-73d1af1f3b444777be/linux-arm64-0/1/console.704b2183.log?helixlogtype=result

@jonathandavies-arm

Copy link
Copy Markdown
ContributorAuthor

Spmidiff errors

[05:14:28] ISSUE: <ASSERT> #9081 /Users/runner/work/1/s/src/coreclr/jit/codegenarm64.cpp (5916) - Assertion failed '(lsb + width) <= bitWidth' in 'Microsoft.AspNetCore.Connections.CorrelationIdGenerator+<>c:<GenerateId>b__3_0(System.Span`1[char],long):this' during 'Generate code' (IL size 267; hash 0xbd4b4083; Tier1)

https://helixr1107v0xdeko0k025g8.blob.core.windows.net/dotnet-runtime-refs-pull-123138-merge-73d1af1f3b444777be/linux-arm64-0/1/console.704b2183.log?helixlogtype=result

Fixed

@jakobbotsch

Copy link
Copy Markdown
Member

/azp run runtime-coreclr superpmi-replay

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jakobbotsch

Copy link
Copy Markdown
Member

Looks like there are replay failures.

[12:10:56] ISSUE: #367597 D:\a_work\1\s\src\coreclr\jit\gentree.cpp (7036) - Assertion failed 'this->OperIsBinary()' in 'System.Text.Unicode.Utf8Utility:TranscodeToUtf8(ptr,int,ptr,int,byref,byref):int' during 'LSRA allocate' (IL size 1666; hash 0xb2a9635e; FullOpts)

@jakobbotsch

Copy link
Copy Markdown
Member

The throughput regressions in the diffs seem large given the quite small number of diffs and the complexity of the transformation.

All the diffs I looked at looked like:

- lsr w2, w0, #6- and w2, w2, #63+ ubfx w2, w0, #6, #6

and

- lsr w2, w0, #6- and w2, w2, #63+ ubfx w2, w0, #6, #6

Could we simplify things by only focusing on these cases?

@jonathandavies-arm

Copy link
Copy Markdown
ContributorAuthor

The throughput regressions in the diffs seem large given the quite small number of diffs and the complexity of the transformation.

All the diffs I looked at looked like:

- lsr w2, w0, #6- and w2, w2, #63+ ubfx w2, w0, #6, #6

and

- lsr w2, w0, #6- and w2, w2, #63+ ubfx w2, w0, #6, #6

Could we simplify things by only focusing on these cases?

I'll have a look at reducing what the PR does to concentrate on this pattern.

@jonathandavies-arm

Copy link
Copy Markdown
ContributorAuthor

The throughput regressions in the diffs seem large given the quite small number of diffs and the complexity of the transformation.

All the diffs I looked at looked like:

- lsr w2, w0, #6- and w2, w2, #63+ ubfx w2, w0, #6, #6

and

- lsr w2, w0, #6- and w2, w2, #63+ ubfx w2, w0, #6, #6

Could we simplify things by only focusing on these cases?

I've pushed a commit that only focuses on the small case you suggested. From my local testing the throughput regressions should be no more, I would check the build but I can't find the page with the results.

Comment threadsrc/coreclr/jit/lowerarmarch.cpp Outdated
Comment threadsrc/coreclr/jit/lower.cpp Outdated
Comment threadsrc/coreclr/jit/compiler.hpp Outdated
Comment threadsrc/coreclr/jit/gentree.cpp Outdated
@jakobbotsch

Copy link
Copy Markdown
Member

/azp run runtime-coreclr superpmi-replay

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jakobbotschjakobbotsch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@jakobbotsch
jakobbotsch merged commit 73a17d6 into dotnet:mainJun 12, 2026
150 of 152 checks passed
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-preview6 milestone Jun 17, 2026
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
This patch adds support for the Arm BFX instruction.
When you extract a continuous range of bits from an integer e.g.
`return (x >> 5) & 0x1F;`
This is the node pattern it's looking for
```
N005 ( 5, 7) [000004] -----+----- \--* AND int $101
N003 ( 3, 4) [000002] -----+----- +--* RSH int $100
N001 ( 1, 1) [000000] -----+----- | +--* LCL_VAR int V00 arg0 u:1 (last use) $80
N002 ( 1, 2) [000001] -----+----- | \--* CNS_INT int 6 $42
N004 ( 1, 2) [000003] -----+----- \--* CNS_INT int 63 $43
```
and changes to ```
( 5, 7) [000007] ----------- \--* BFX int N001 ( 1, 1) [000000] -----+----- \--* LCL_VAR int V00 arg0 u:1 (last use) $80
```
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 18, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIcommunity-contributionIndicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@jonathandavies-arm@a74nh@jakobbotsch@JulieLeeMSFT@tannergooding@EgorBo