Skip to content

Conversation

@vitek-karas
Copy link
Member

This is more of a "workaround" to #2872

I created #2888 to track the work to add full support for switch instruction in branch removal.


// Common pattern generated by C# compiler in debug mode
if (i > 3 && GetConstantValue (FoldedInstructions[i - 3], out operand) && operand is int opint2 && IsPairedStlocLdloc (FoldedInstructions[i - 2], FoldedInstructions[i - 1])) {
if (i >= 3 && GetConstantValue (FoldedInstructions[i - 3], out operand) && operand is int opint2 && IsPairedStlocLdloc (FoldedInstructions[i - 2], FoldedInstructions[i - 1])) {
Copy link
Member Author

Choose a reason for hiding this comment

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

This fixes the case where the switch is the first thing in a method body - in which case the logic here would not kick in (now switch is disabled above, but if it's not it would not be recognized due to this).

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, I'm having trouble visualizing the kind of code this is matching. Could you write a comment with an example?

Copy link
Member

Choose a reason for hiding this comment

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

This looks like it is a bug not just for switch statements but for any branching instruction we consider, right? I wonder if we can write a test for this fix where the compiler doesn't emit a nop as the first instruction.

@agocke I think it's for cases where the compiler emits code like this:

call bool C::get_ConstantProperty()
stloc.0
ldloc.0
brfalse.s IL_xxxx // or a switch

Copy link
Member Author

Choose a reason for hiding this comment

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

Exactly - for some reason Roslyn always put the stloc/ldloc pair even in optimized build - in debug build there are actually two pairs like that one after another. The code would not handle the debug build at all right now, but that's for when we actually support switch.

Copy link
Member

@sbomer sbomer left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!


// Common pattern generated by C# compiler in debug mode
if (i > 3 && GetConstantValue (FoldedInstructions[i - 3], out operand) && operand is int opint2 && IsPairedStlocLdloc (FoldedInstructions[i - 2], FoldedInstructions[i - 1])) {
if (i >= 3 && GetConstantValue (FoldedInstructions[i - 3], out operand) && operand is int opint2 && IsPairedStlocLdloc (FoldedInstructions[i - 2], FoldedInstructions[i - 1])) {
Copy link
Member

Choose a reason for hiding this comment

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

This looks like it is a bug not just for switch statements but for any branching instruction we consider, right? I wonder if we can write a test for this fix where the compiler doesn't emit a nop as the first instruction.

@agocke I think it's for cases where the compiler emits code like this:

call bool C::get_ConstantProperty()
stloc.0
ldloc.0
brfalse.s IL_xxxx // or a switch

@vitek-karas vitek-karas merged commit 0872a5c into dotnet:main Jul 12, 2022
@vitek-karas vitek-karas deleted the DisableSupportForSwitchInBranchRemoval branch July 12, 2022 18:21
radical added a commit to radical/runtime that referenced this pull request Jul 13, 2022
lewing pushed a commit to dotnet/runtime that referenced this pull request Jul 13, 2022
The linker bump in dotnet/linker#2889 should
have fixed the issue.

Closes #71848 .
agocke pushed a commit to dotnet/runtime that referenced this pull request Nov 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants