Skip to content

Check if loop body occured before loopTop and if so unmark alignment #91854

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

Merged
merged 1 commit into from
Sep 12, 2023

Conversation

kunalspathak
Copy link
Member

With optimizations conducted in various phases, we might rearrange the blocks such that loop body appears lexically before the loopTop. As such, we should unmark the alignment of such loops, because when we try to find the size of the loop, we don't find the block that targets back to the loop top. We were previously unmarking such loops, however, it was only if the loop body appears just before the loop top. In the failure case, the loop top is several blocks below the loop body. Updated the code in placeLoopAlignInstructions to track if we have already seen a particular bbNatLoopNum. If yes, and a block is marked as aligned, that means we have already encountered the loop body block that had the same bbNatLoopNum. Unmark such loops.

Fixes: #91838

@ghost ghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Sep 10, 2023
@ghost ghost assigned kunalspathak Sep 10, 2023
@ghost
Copy link

ghost commented Sep 10, 2023

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

Issue Details

With optimizations conducted in various phases, we might rearrange the blocks such that loop body appears lexically before the loopTop. As such, we should unmark the alignment of such loops, because when we try to find the size of the loop, we don't find the block that targets back to the loop top. We were previously unmarking such loops, however, it was only if the loop body appears just before the loop top. In the failure case, the loop top is several blocks below the loop body. Updated the code in placeLoopAlignInstructions to track if we have already seen a particular bbNatLoopNum. If yes, and a block is marked as aligned, that means we have already encountered the loop body block that had the same bbNatLoopNum. Unmark such loops.

Fixes: #91838

Author: kunalspathak
Assignees: -
Labels:

area-CodeGen-coreclr

Milestone: -

@kunalspathak kunalspathak marked this pull request as ready for review September 10, 2023 16:25
@kunalspathak
Copy link
Member Author

@BruceForstall

@kunalspathak
Copy link
Member Author

@dotnet/jit-contrib @AndyAyersMS

@kunalspathak kunalspathak merged commit d67314e into dotnet:main Sep 12, 2023
@kunalspathak kunalspathak deleted the loopTop branch September 12, 2023 04:19
@kunalspathak
Copy link
Member Author

/backport to release/8.0

@github-actions
Copy link
Contributor

Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/6154847476

@@ -5276,6 +5276,13 @@ PhaseStatus Compiler::placeLoopAlignInstructions()
weight_t minBlockSoFar = BB_MAX_WEIGHT;
BasicBlock* bbHavingAlign = nullptr;
BasicBlock::loopNumber currentAlignedLoopNum = BasicBlock::NOT_IN_LOOP;
bool visitedLoopNum[BasicBlock::MAX_LOOP_NUM];
memset(visitedLoopNum, false, sizeof(visitedLoopNum));
Copy link
Contributor

Choose a reason for hiding this comment

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

It's weird to use memset to zero a bool array, but ok.


#ifdef DEBUG
int visitedBlockForLoopNum[BasicBlock::MAX_LOOP_NUM];
memset(visitedBlockForLoopNum, false, sizeof(visitedBlockForLoopNum));
Copy link
Contributor

Choose a reason for hiding this comment

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

It's weird to use false as a value to zero an int array.

memset(visitedLoopNum, false, sizeof(visitedLoopNum));

#ifdef DEBUG
int visitedBlockForLoopNum[BasicBlock::MAX_LOOP_NUM];
Copy link
Contributor

Choose a reason for hiding this comment

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

block nums can't be negative; use unsigned?

@@ -5352,12 +5359,19 @@ PhaseStatus Compiler::placeLoopAlignInstructions()
madeChanges = true;
unmarkedLoopAlign = true;
}
else if ((block->bbNatLoopNum != BasicBlock::NOT_IN_LOOP) && (block->bbNatLoopNum == loopTop->bbNatLoopNum))
else if (visitedLoopNum[loopTop->bbNatLoopNum])
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't you need to check that block->bbNatLoopNum != BasicBlock::NOT_IN_LOOP?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not really. block is the previous block before loopTop and we want to check here if we have seen a loop body related to loopTop->bbNatLoopNum.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, sorry, I meant, don't you need to check loopTop->bbNatLoopNum != BasicBlock::NOT_IN_LOOP?

It appears that sometimes it does equal NOT_IN_LOOP, leading to reading beyond the array bounds.

@ghost ghost locked as resolved and limited conversation to collaborators Oct 13, 2023
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.

JIT: "Mismatch in align instruction" in superpmi-replay
3 participants