-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Segfault inside JIT in libraries-jitstress #68756
Comments
Tagging subscribers to this area: @JulieLeeMSFT Issue DetailsThe libraries-jitstress job is hitting AVs/segfaults in a few tests, e.g. https://dev.azure.com/dnceng/public/_build/results?buildId=1746194&view=ms.vss-test-web.build-test-results-tab&runId=47150832&resultId=193742&paneView=debug. It seems runtime/src/coreclr/jit/optimizer.cpp Line 342 in 71a73fb
which happens because endBlk is lexically before begBlk .
From bisection it was exposed by #68588.
|
Hoisting decides to hoist a null-check out of a loop and creates a preheader for it: optHoistThisLoop for loop L00 <BB03..BB07>:
Loop body contains a call
Loop has multiple exits
USEDEF (7)={V10 V03 V11 V04 V05 V01 V02}
INOUT (5)={V03 V11 V05 V01 V02}
LOOPVARS(5)={V03 V11 V05 V01 V02}
only considering hoisting in entry block BB04
optHoistLoopBlocks BB04 (weight= 17.78) of loop L00 <BB03..BB07>
[000213] not hoistable: unset
[000215] not hoistable: unset
*************** In fgCreateLoopPreHeader for L00
existing head BB02 isn't unique non-loop predecessor of loop entry
New Basic Block BB13 [0020] created.
Created PreHeader (BB13) for loop L00 (BB03 - BB07, entry BB04), with weight = 0
Setting edge weights for BB02 -> BB13 to [0 .. 3.402823e+38]
Setting edge weights for BB12 -> BB13 to [0 .. 3.402823e+38]
Setting edge weights for BB02 -> BB13 to [0 .. 0]
Setting edge weights for BB13 -> BB04 to [0 .. 3.402823e+38]
Setting edge weights for BB13 -> BB04 to [0 .. 0]
*************** In fgDebugCheckBBlist
*************** In fgDebugCheckLoopTable
*************** After fgCreateLoopPreHeader for L00
-----------------------------------------------------------------------------------------------------------------------------------------
BBnum BBid ref try hnd preds weight IBC lp [IL range] [jump] [EH region] [flags]
-----------------------------------------------------------------------------------------------------------------------------------------
BB01 [0000] 1 1 9 [000..009)-> BB11 ( cond ) i idxlen IBC
BB02 [0002] 1 BB01 0 0 [014..01D)-> BB13 (always) i rare hascall gcsafe newobj nullcheck IBC
BB13 [0020] 2 BB02,BB12 0 [01D..???)-> BB04 (always) internal rare LoopPH
BB03 [0003] 2 BB05,BB07 16 144 0 [01D..03C)-> BB12 ( cond ) i Loop hascall gcsafe idxlen nullcheck bwd bwd-target IBC
BB04 [0005] 2 BB03,BB13 17.78 160 0 [044..04C)-> BB07 ( cond ) i Loop hascall gcsafe nullcheck bwd bwd-src IBC
BB05 [0014] 1 BB04 933.33 8400 0 [044..045)-> BB03 ( cond ) i gcsafe bwd IBC
BB06 [0019] 1 BB05 933.33 0 [???..???)-> BB09 (always) internal gcsafe
BB07 [0015] 1 BB04 17.78 160 0 [044..045)-> BB03 ( cond ) i gcsafe nullcheck bwd IBC
BB08 [0018] 1 BB07 7.33 [???..???)-> BB10 (always) internal gcsafe
BB09 [0017] 1 BB06 933.33 8400 [???..???) internal gcsafe IBC
BB10 [0006] 2 BB08,BB09 7.33 66 [04C..04D) (return) i gcsafe IBC
BB11 [0001] 1 BB01 0 0 [009..014) (throw ) i rare hascall gcsafe newobj IBC
BB12 [0004] 1 BB03 0 0 [03C..044)-> BB13 (always) i rare hascall gcsafe bwd IBC
----------------------------------------------------------------------------------------------------------------------------------------- During assertion prop, we notice that the null check is useless and remove it, so that the loop pre-header becomes empty: VN based non-null prop in BB13:
N002 ( 2, 2) [000265] ---X---H--- ▌ NULLCHECK byte $VN.Void
removing useless STMT00033 ( ??? ... ??? )
N004 ( 2, 2) [000268] -----O----- ▌ COMMA void
N002 ( 2, 2) [000265] -----O-H--- ├──▌ NULLCHECK byte $VN.Void
N001 ( 1, 1) [000266] -------H--- │ └──▌ LCL_VAR ref V03 loc0 u:2 $24f
N003 ( 0, 0) [000267] ----------- └──▌ NOP void
from BB13
BB13 becomes empty We then call *************** In fgUpdateFlowGraph()
Before updating the flow graph:
-----------------------------------------------------------------------------------------------------------------------------------------
BBnum BBid ref try hnd preds weight IBC lp [IL range] [jump] [EH region] [flags]
-----------------------------------------------------------------------------------------------------------------------------------------
BB01 [0000] 1 1 9 [000..009)-> BB11 ( cond ) i idxlen IBC
BB02 [0002] 1 BB01 0 0 [014..01D)-> BB13 (always) i rare hascall gcsafe newobj nullcheck IBC
BB13 [0020] 2 BB02,BB12 0 [01D..???)-> BB04 (always) internal rare nullcheck LoopPH
BB03 [0003] 1 BB07 16 144 0 [01D..03C)-> BB12 ( cond ) i Loop hascall gcsafe idxlen nullcheck bwd bwd-target IBC
BB04 [0005] 2 BB03,BB13 17.78 160 0 [044..04C)-> BB07 ( cond ) i Loop hascall gcsafe nullcheck bwd bwd-src IBC
BB05 [0014] 1 BB04 933.33 8400 0 [044..045) i gcsafe bwd IBC
BB06 [0019] 1 BB05 933.33 0 [???..???)-> BB09 (always) internal gcsafe
BB07 [0015] 1 BB04 17.78 160 0 [044..045)-> BB03 (always) i gcsafe nullcheck bwd IBC
BB08 [0018] 0 7.33 [???..???)-> BB10 (always) internal gcsafe
BB09 [0017] 1 BB06 933.33 8400 [???..???) internal gcsafe IBC
BB10 [0006] 2 BB08,BB09 7.33 66 [04C..04D) (return) i gcsafe IBC
BB11 [0001] 1 BB01 0 0 [009..014) (throw ) i rare hascall gcsafe newobj IBC
BB12 [0004] 1 BB03 0 0 [03C..044)-> BB13 (always) i rare hascall gcsafe bwd IBC
-----------------------------------------------------------------------------------------------------------------------------------------
Removing unconditional jump to next block (BB02 -> BB13) (converted BB02 to fall-through)
fgRemoveBlock BB13, unreachable=false
Removing empty BB13
Unmarking a loop from BB04 to BB13 Note that the validity check for that is relying on runtime/src/coreclr/jit/optimizer.cpp Lines 575 to 584 in 9f2add0
@BruceForstall are we missing a call to |
I too noticed it recently that we rely on runtime/src/coreclr/jit/compiler.h Lines 6165 to 6168 in 809dd7c
|
Multiple things going on here:
I think, we should check if the block is preheader and if yes, just remove the block without unmarking the loop. The only thing I am not sure in that case is what should be the updated runtime/src/coreclr/jit/optimizer.cpp Lines 568 to 569 in c9d8f80
We can just have a minimal fix of what I discussed in 1. or have little more surgical fix (given my assumptions are correct). Here is my attempt -#68803. @BruceForstall - let me know if it makes sense. |
With the broader fix, before doing
Here, we are trying to delete the preheader |
The libraries-jitstress job is hitting AVs/segfaults in a few tests, e.g. https://dev.azure.com/dnceng/public/_build/results?buildId=1746194&view=ms.vss-test-web.build-test-results-tab&runId=47150832&resultId=193742&paneView=debug.
It seems
curBlk
is null here:runtime/src/coreclr/jit/optimizer.cpp
Line 342 in 71a73fb
which happens because
endBlk
is lexically beforebegBlk
.From bisection it was exposed by #68588.
cc @dotnet/jit-contrib
The text was updated successfully, but these errors were encountered: