RFR: 8370200: Crash: assert(outer->outcnt() >= phis + 2 - be_loads && outer->outcnt() <= phis + 2 + stores + 1) failed: only phis

Roland Westrelin roland at openjdk.org
Fri Dec 5 11:55:34 UTC 2025


The crash occurs because verification code expects the inner and outer
loop of a loop strip mining nest to have the same number of phis but,
in this case, the inner loop has one more memory phis than the outer
loop.

1) After `OuterStripMinedLoopNode::adjust_strip_mined_loop`, inner and
outer loops have the same number of phis, as expected.


 309  MergeMem  === _ 1 306 1 1 284  [[ 429 ]]  { - - N284:instptr:java/lang/Throwable (java/io/Serializable):BotPTR+20,iid=bot [narrow] }  Memory: @ptr:BotPTR+bot, idx=Bot; !orig=205 !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)

 248  OuterStripMinedLoop  === 248 321 247  [[ 248 249 428 429 430 ]] 
 429  Phi  === 248 309 205  [[ 93 ]]  #memory  Memory: @ptr:BotPTR+bot, idx=Bot; !orig=93 !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)
 430  Phi  === 248 306 121  [[ 94 ]]  #memory  Memory: @instptr:TestMismatchedMemoryPhis:BotPTR+16,iid=bot, name=l, idx=4; !orig=94 !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)

 249  CountedLoop  === 249 248 197  [[ 249 119 96 93 94 ]] inner stride: 1  strip mined !orig=[223],[91] !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)
  93  Phi  === 249 429 205  [[ 117 97 ]]  #memory  Memory: @ptr:BotPTR+bot, idx=Bot; !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)
  94  Phi  === 249 430 121  [[ 97 ]]  #memory  Memory: @instptr:TestMismatchedMemoryPhis:BotPTR+16,iid=bot, name=l, idx=4; !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)


2) Then `PhiNode::Ideal` runs for 429 and pushed the `MergeMem` 309
through the outer loop phi:


 248  OuterStripMinedLoop  === 248 321 247  [[ 248 249 428 429 430 444 446 ]] 
 430  Phi  === 248 306 121  [[ 94 ]]  #memory  Memory: @instptr:TestMismatchedMemoryPhis:BotPTR+16,iid=bot, name=l, idx=4; !orig=94 !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)
 444  Phi  === 248 306 121  [[ 445 ]]  #memory  Memory: @ptr:BotPTR+bot, idx=Bot; !orig=429,93 !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)
 446  Phi  === 248 284 170  [[ 445 ]]  #memory  Memory: @instptr:java/lang/Throwable (java/io/Serializable):BotPTR+20,iid=bot [narrow], name=detailMessage, idx=5; !orig=444,429,93 !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)

 445  MergeMem  === _ 1 444 1 1 446  [[ 93 ]]  { - - N446:instptr:java/lang/Throwable (java/io/Serializable):BotPTR+20,iid=bot [narrow] }  Memory: @ptr:BotPTR+bot, idx=Bot; !orig=[429],93 !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)

 249  CountedLoop  === 249 248 197  [[ 249 119 96 93 94 ]] inner stride: 1  strip mined !orig=[223],[91] !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)
  93  Phi  === 249 445 205  [[ 117 97 ]]  #memory  Memory: @ptr:BotPTR+bot, idx=Bot; !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)
  94  Phi  === 249 430 121  [[ 97 ]]  #memory  Memory: @instptr:TestMismatchedMemoryPhis:BotPTR+16,iid=bot, name=l, idx=4; !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)


3) `PhiNode::Identity` runs for 430 and finds that it can be replace
by 429: the non bottom memory phi 430 can be replaced by the bottom
memory 429 that has the same inputs.


 248  OuterStripMinedLoop  === 248 321 247  [[ 248 249 428 446 444 ]] 
 446  Phi  === 248 284 170  [[ 445 ]]  #memory  Memory: @instptr:java/lang/Throwable (java/io/Serializable):BotPTR+20,iid=bot [narrow], name=detailMessage, idx=5; !orig=444,[429],93 !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)
 444  Phi  === 248 306 121  [[ 445 94 ]]  #memory  Memory: @ptr:BotPTR+bot, idx=Bot; !orig=[429],93 !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)

 445  MergeMem  === _ 1 444 1 1 446  [[ 93 ]]  { - - N446:instptr:java/lang/Throwable (java/io/Serializable):BotPTR+20,iid=bot [narrow] }  Memory: @ptr:BotPTR+bot, idx=Bot; !orig=[429],93 !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)

 249  CountedLoop  === 249 248 197  [[ 249 119 96 93 94 ]] inner stride: 1  strip mined !orig=[223],[91] !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)
  93  Phi  === 249 445 205  [[ 117 97 ]]  #memory  Memory: @ptr:BotPTR+bot, idx=Bot; !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)
  94  Phi  === 249 444 121  [[ 97 ]]  #memory  Memory: @instptr:TestMismatchedMemoryPhis:BotPTR+16,iid=bot, name=l, idx=4; !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)


4) `PhiNode::Ideal` runs for 93 and pushed the `MergeMem` through that
`Phi`:

 248  OuterStripMinedLoop  === 248 321 247  [[ 248 249 428 446 444 ]] 
 446  Phi  === 248 284 170  [[ 453 ]]  #memory  Memory: @instptr:java/lang/Throwable (java/io/Serializable):BotPTR+20,iid=bot [narrow], name=detailMessage, idx=5; !orig=444,[429],[93] !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)
 444  Phi  === 248 306 121  [[ 451 94 ]]  #memory  Memory: @ptr:BotPTR+bot, idx=Bot; !orig=[429],[93] !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)

 249  CountedLoop  === 249 248 197  [[ 249 119 96 453 94 451 ]] inner stride: 1  strip mined !orig=[223],[91] !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)
 453  Phi  === 249 446 170  [[ 452 ]]  #memory  Memory: @instptr:java/lang/Throwable (java/io/Serializable):BotPTR+20,iid=bot [narrow], name=detailMessage, idx=5; !orig=451,[93] !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)
  94  Phi  === 249 444 121  [[ 97 ]]  #memory  Memory: @instptr:TestMismatchedMemoryPhis:BotPTR+16,iid=bot, name=l, idx=4; !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)
 451  Phi  === 249 444 121  [[ 452 ]]  #memory  Memory: @ptr:BotPTR+bot, idx=Bot; !orig=[93] !jvms: TestMismatchedMemoryPhis::mainTest @ bci:37 (line 49)

Now, `PhiNode::Identity` for 94 could replace it with the bottom
memory phi with same inputs 451. But it doesn't run. It last ran
between 3) and 4) and there's no reason for igvn to execute it again
because 4) doesn't cause 94 to change in any way.

The fix I propose is to mirror the transformation from
`PhiNode::Identity` in `PhiNode::Ideal` so the end result doesn't
depend on what phi is modified and processed by igvn last.

-------------

Commit messages:
 - more
 - test
 - more
 - fix

Changes: https://git.openjdk.org/jdk/pull/28677/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=28677&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8370200
  Stats: 124 lines in 5 files changed: 102 ins; 16 del; 6 mod
  Patch: https://git.openjdk.org/jdk/pull/28677.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/28677/head:pull/28677

PR: https://git.openjdk.org/jdk/pull/28677


More information about the hotspot-compiler-dev mailing list