Skip to content

Fix Arm64 conditional select lowering#128700

Open
jonathandavies-arm wants to merge 2 commits into
dotnet:mainfrom
jonathandavies-arm:upstream/conditional-select-lowering
Open

Fix Arm64 conditional select lowering#128700
jonathandavies-arm wants to merge 2 commits into
dotnet:mainfrom
jonathandavies-arm:upstream/conditional-select-lowering

Conversation

@jonathandavies-arm

Copy link
Copy Markdown
Contributor

Arm64 lowering could form SELECT_INCCC from an int local while the select result was long. That could emit a 64-bit csinc using the int local value as the increment source, changing -1 + 1 from 0 to 0x1_0000_0000.

Arm64 lowering could also replace checked add or neg operations feeding a select with csinc or csneg. Those instructions do not report overflow, so the transformed code could skip required OverflowException behavior.

Solution: Require the compared local width to match the select result before applying the constant-select-to-cinc transform, and recreate valid replacement locals with their own type. Also bail out of the conditional-select-to-CS-op transform when the operation being removed may overflow and is marked as checked overflow. Add Arm64 regression coverage for both cases.

Arm64 lowering could form SELECT_INCCC from an int local while the select result was long. That could emit a 64-bit csinc using the int local value as the increment source, changing -1 + 1 from 0 to 0x1_0000_0000.

Arm64 lowering could also replace checked add or neg operations feeding a select with csinc or csneg. Those instructions do not report overflow, so the transformed code could skip required OverflowException behavior.

Solution: Require the compared local width to match the select result before applying the constant-select-to-cinc transform, and recreate valid replacement locals with their own type. Also bail out of the conditional-select-to-CS-op transform when the operation being removed may overflow and is marked as checked overflow. Add Arm64 regression coverage for both cases.
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label May 28, 2026
@github-actions github-actions Bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 28, 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.

var_types lclType = genActualType(lclNode);
var_types selectType = genActualType(select);

if (genTypeSize(lclType) != genTypeSize(selectType))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

simplify to if (lclType != selectType) ?

// The checked negation must remain explicit so the overflow path is preserved.
//ARM64-NOT: csneg
//ARM64-NOT: cneg
return condition ? x : checked(-x);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I wonder if this test might be unneeded - TryLowerCselToCSOp doesn't operate on SUB, and "OperMayOverflow" is false for GT_NEG.

Is it easy to check quickly what we do for
return condition ? x : (-x);
(without the checked)?

@dhartglassMSFT

Copy link
Copy Markdown
Contributor

Change lgtm aside from a couple nits, thanks for finding and submitting the fix

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 community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants