Skip to content

Conversation

@kunalspathak
Copy link
Contributor

We were assuming that if a finally is empty, it doesn't have any blocks pointing to it, but sometimes Roslyn would have a copy of code inside finally into a block that follows finally block, and directly jump to that block.

IL to import:
IL_0000  72 33 11 00 70    ldstr        0x70001133
IL_0005  28 3c 00 00 0a    call         0xA00003C
IL_000a  de 02             leave.s      2 (IL_000e)
IL_000c  2b fe             br.s         -2 (IL_000c)
IL_000e  2b fe             br.s         -2 (IL_000e)

As such, after removing CALL_FINALLY block, the block inside finally can jump back to itself and hence one additional reference. As such, while removing empty finally, we should just decrease the reference count of finally block by 1 and then let fgRemoveBlock() take care of further reducing the reference count, if there exist one.

Fixes: #58729

@ghost ghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Sep 7, 2021
@kunalspathak
Copy link
Contributor Author

@dotnet/jit-contrib

@ghost
Copy link

ghost commented Sep 7, 2021

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

Issue Details

We were assuming that if a finally is empty, it doesn't have any blocks pointing to it, but sometimes Roslyn would have a copy of code inside finally into a block that follows finally block, and directly jump to that block.

IL to import:
IL_0000  72 33 11 00 70    ldstr        0x70001133
IL_0005  28 3c 00 00 0a    call         0xA00003C
IL_000a  de 02             leave.s      2 (IL_000e)
IL_000c  2b fe             br.s         -2 (IL_000c)
IL_000e  2b fe             br.s         -2 (IL_000e)

As such, after removing CALL_FINALLY block, the block inside finally can jump back to itself and hence one additional reference. As such, while removing empty finally, we should just decrease the reference count of finally block by 1 and then let fgRemoveBlock() take care of further reducing the reference count, if there exist one.

Fixes: #58729

Author: kunalspathak
Assignees: -
Labels:

area-CodeGen-coreclr

Milestone: -

@AndyAyersMS
Copy link
Member

I think we should fix this by classifying finallies that BBJ_ALWAYS to themselves as non-empty...

@kunalspathak
Copy link
Contributor Author

I think we should fix this by classifying finallies that BBJ_ALWAYS to themselves as non-empty...

Ah, ok. So will that remove the block inside finally in later phase (dead code) or it will never remove the block and we will go ahead and generate code except that we will not go to it?

@AndyAyersMS
Copy link
Member

I suspect it will stay around... as mentioned over in the issue the code in the finally is reachable if there's an exception thrown in the try. So it's not actually dead.

@kunalspathak kunalspathak changed the title Decrease refcount of unreachable finally properly Consider finally that jumps to itself as non-empty Sep 8, 2021
@kunalspathak
Copy link
Contributor Author

@AndyAyersMS - can you take another look?

@kunalspathak kunalspathak merged commit a09d088 into dotnet:main Sep 9, 2021
@kunalspathak
Copy link
Contributor Author

/backport to release/6.0

@kunalspathak kunalspathak deleted the unreachable-finally branch September 9, 2021 15:32
@github-actions
Copy link
Contributor

github-actions bot commented Sep 9, 2021

@BruceForstall
Copy link
Contributor

Isn't the issue that there is the code is looking for GT_RETFILT incorrectly? I.e., it's only looking for non-GT_RETFILT nodes, but not actually verifying that there is a (single) GT_RETFILT node?

@AndyAyersMS
Copy link
Member

I think the checks are equivalent, but yeah the comment I put there is not describing what the code does.

@ghost ghost locked as resolved and limited conversation to collaborators Nov 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Assertion failed 'block->countOfInEdges() > 0' during 'Remove empty finally' with infinite loop in finally

3 participants