Commit 46046a3
authored
JIT: Propagate GC safe point flag in
Fixes #116704. From that failure in particular, we have the following flowgraph before loop inversion runs:
```
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
BBnum BBid ref try hnd preds weight [IL range] [jump] [EH region] [flags]
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
BB01 [0000] 1 1 [000..004)-> BB03(0.5),BB02(0.5) ( cond ) i
BB02 [0001] 1 BB01 1 [004..005) (return) i
BB03 [0002] 1 BB01 1 [005..04E)-> BB05(1) (always) i hascall gcsafe newobj
BB04 [0003] 1 BB05 1 [04E..063)-> BB05(1) (always) i hascall gcsafe idxlen bwd bwd-target
BB05 [0004] 2 BB03,BB04 1 [063..06A)-> BB04(0.5),BB06(0.5) ( cond ) i bwd bwd-src
BB06 [0005] 1 BB05 1 [06A..0B9) (throw ) i hascall gcsafe newobj
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
```
`BB06` has a tail call, and is flagged as having a GC safe point. It is also the exit block of a loop headed by `BB05`. Loop inversion gives `BB06` an empty predecessor to keep the loop canonical by calling `fgSplitBlockAtBeginning`. This calls `fgSplitBlockAtEnd`, which removes the safe point flag on the new block since it initially keeps the code in the predecessor. `fgSplitBlockAtBeginning` does not reset the flag after moving the code into the new successor. Thus, we end up with the following flowgraph:
```
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
BBnum BBid ref try hnd preds weight [IL range] [jump] [EH region] [flags]
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
BB01 [0000] 1 1 [000..004)-> BB03(0.5),BB02(0.5) ( cond ) i
BB02 [0001] 1 BB01 1 [004..005) (return) i
BB03 [0002] 1 BB01 1 [005..04E)-> BB09(0.5),BB08(0.5) ( cond ) i hascall gcsafe newobj
BB08 [0021] 1 BB03 1 [???..???)-> BB04(1) (always) i hascall newobj
BB04 [0003] 2 BB04,BB08 1 [04E..06A)-> BB04(0.5),BB06(0.5) ( cond ) i hascall gcsafe idxlen bwd bwd-target
BB06 [0005] 1 BB04 1 [???..???)-> BB09(1) (always) i hascall gcsafe newobj
BB09 [0022] 2 BB03,BB06 1 [06A..0B9) (throw ) i hascall newobj
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
```
Note the presence of the flag on `BB06`, which has no IR, and the lack of the flag on `BB09`, which contains the actual tail call.fgSplitBlockAtBeginning (#116718)1 parent 300eba1 commit 46046a3
1 file changed
+6
-0
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4922 | 4922 | | |
4923 | 4923 | | |
4924 | 4924 | | |
| 4925 | + | |
| 4926 | + | |
| 4927 | + | |
| 4928 | + | |
| 4929 | + | |
| 4930 | + | |
4925 | 4931 | | |
4926 | 4932 | | |
4927 | 4933 | | |
| |||
0 commit comments