RFR: 8371536: C2: VerifyIterativeGVN should assert on first detected failure
Benoît Maillard
bmaillard at openjdk.org
Thu Nov 13 16:25:54 UTC 2025
This PR introduces changes in the detection of missing IGVN optimizations. As explained in the JBS issue description, when `-XX:VerifyIterativeGVN` was introduced, it was helpful to list all the missing optimizations. Such failures occur less frequently now, and the focus has changed to being able to debug such failure quickly and identifying similar or related failures during bug triaging.
In summary, this PR brings the following changes:
- Assert at the first verification failure in `verify_Optimize` instead of attemtping to process all the nodes in the graph. This makes the output easier to parse, and also decreases the overhead of getting to the actual optimization site with a debugger.
- Avoid confusing `Need to remove from hash before changing edges` assert messages by removing the verified node from the hash table before attempting to optimize the node in question.
- Provide the failure reason (Ideal, Identity or Value) and the node name in the assert message itself to facilitate identifying related failures in the testing infrastructure during bug triaging.
### Example outputs
#### [JDK-8371534: C2: Missed Ideal optimization opportunity with AndL and URShiftL ](https://bugs.openjdk.org/browse/JDK-8371534)
Before the change, we would get two missed optimizations (the second one is only a consequence of the first one). After the change, we only get the first one, which is the one that actually needs to be fixed. We also get the name of the node in the assert message.
<details>
<summary>Before</summary>
Missed Ideal optimization (can_reshape=false):
The node was replaced by Ideal.
Old node:
dist dump
---------------------------------------------
1 22 ConI === 0 [[ 70 81 70 290 81 76 32 37 37 43 48 48 54 59 59 65 336 ]] #int:1
1 297 AndL === _ 298 21 [[ 290 ]] !orig=[236],[193] !jvms: TestMaskAndRShiftReorder::testURShiftL @ bci:42 (line 81)
0 290 URShiftL === _ 297 22 [[ 299 ]] !orig=[231],[194] !jvms: TestMaskAndRShiftReorder::testURShiftL @ bci:46 (line 82)
The result after Ideal:
dist dump
---------------------------------------------
1 337 ConL === 0 [[ 338 ]] #long:-9
1 336 URShiftL === _ 298 22 [[ 338 ]]
0 338 AndL === _ 336 337 [[ ]]
Missed Ideal optimization (can_reshape=true):
The node was replaced by Ideal.
Old node:
dist dump
---------------------------------------------
1 22 ConI === 0 [[ 70 81 70 290 81 76 32 37 37 43 48 48 54 59 59 65 336 ]] #int:1
1 297 AndL === _ 298 21 [[ 290 ]] !orig=[236],[193] !jvms: TestMaskAndRShiftReorder::testURShiftL @ bci:42 (line 81)
0 290 URShiftL === _ 297 22 [[ 299 ]] !orig=[231],[194] !jvms: TestMaskAndRShiftReorder::testURShiftL @ bci:46 (line 82)
The result after Ideal:
dist dump
---------------------------------------------
1 337 ConL === 0 [[ 338 340 ]] #long:-9
1 336 URShiftL === _ 298 22 [[ 338 340 ]] !orig=[339]
0 340 AndL === _ 336 337 [[ ]]
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/bmaillar/src/jdk/main/open/src/hotspot/share/opto/phaseX.cpp:1105), pid=1949581, tid=1949599
# assert(!failure) failed: Missed optimization opportunity in PhaseIterGVN
#
# JRE version: Java(TM) SE Runtime Environment (26.0) (fastdebug build 26-internal-bmaillar.open)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 26-internal-bmaillar.open, compiled mode, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V [libjvm.so+0x18897f9] PhaseIterGVN::verify_optimize()+0xd19
#
</details>
<details>
<summary>After</summary>
Missed Ideal optimization (can_reshape=false):
The node was replaced by Ideal.
Old node:
dist dump
---------------------------------------------
1 22 ConI === 0 [[ 70 81 70 290 81 76 32 37 37 43 48 48 54 59 59 65 336 ]] #int:1
1 297 AndL === _ 298 21 [[ 290 ]] !orig=[236],[193] !jvms: TestMaskAndRShiftReorder::testURShiftL @ bci:42 (line 81)
0 290 URShiftL === _ 297 22 [[ 299 ]] !orig=[231],[194] !jvms: TestMaskAndRShiftReorder::testURShiftL @ bci:46 (line 82)
The result after Ideal:
dist dump
---------------------------------------------
1 337 ConL === 0 [[ 338 ]] #long:-9
1 336 URShiftL === _ 298 22 [[ 338 ]]
0 338 AndL === _ 336 337 [[ ]]
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/bmaillar/src/jdk/JDK-8371536/open/src/hotspot/share/opto/phaseX.cpp:1096), pid=1950252, tid=1950270
# assert(!failure) failed: Missed Ideal optimization opportunity in PhaseIterGVN for URShiftL
#
# JRE version: Java(TM) SE Runtime Environment (26.0) (fastdebug build 26-internal-bmaillar.open)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 26-internal-bmaillar.open, compiled mode, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V [libjvm.so+0x1889a12] PhaseIterGVN::verify_optimize()+0x8b2
#
</details>
#### [JDK-8371558: C2: Missing optimization opportunity in AbsNode::Ideal](https://bugs.openjdk.org/browse/JDK-8371534)
Before, we get a confusing `Need to remove from hash before changing edges` assert.
After, we get the actual cause of the failure as well as the name of the node in the assert itself.
<details>
<summary>Before</summary>
Need to remove from hash before changing edges
435 SubI === _ 101 103 [[ 433 434 106 ]] !orig=[104] !jvms: TestMissingOptAbsZeroMinusX::testAbsI @ bci:16 (line 53)
434 AbsI === _ 435 [[ 433 ]] !orig=105 !jvms: TestMissingOptAbsZeroMinusX::testAbsI @ bci:20 (line 54)
Set at i = 1
103 LoadI === _ 7 102 [[ 503 435 105 ]] @java/lang/Class (java/io/Serializable,java/lang/constant/Constable,java/lang/reflect/AnnotatedElement,java/lang/invoke/TypeDescriptor,java/lang/reflect/GenericDeclaration,java/lang/reflect/Type,java/lang/invoke/TypeDescriptor$OfField):exact+120 *, name=a, idx=4; #int !jvms: TestMissingOptAbsZeroMinusX::testAbsI @ bci:13 (line 53)
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/bmaillar/src/jdk/main/open/src/hotspot/share/opto/phaseX.cpp:3357), pid=1956852, tid=1956870
# assert(false) failed: Need to remove from hash before changing edges
#
# JRE version: Java(TM) SE Runtime Environment (26.0) (fastdebug build 26-internal-bmaillar.open)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 26-internal-bmaillar.open, compiled mode, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V [libjvm.so+0x1881b85] Node::set_req_X(unsigned int, Node*, PhaseIterGVN*)+0x1e5
#
</details>
<details>
<summary>After</summary>
Missed Ideal optimization (can_reshape=false):
The node was reshaped by Ideal.
The result after Ideal:
dist dump
---------------------------------------------
1 103 LoadI === _ 7 102 [[ 503 435 105 434 ]] @java/lang/Class (java/io/Serializable,java/lang/constant/Constable,java/lang/reflect/AnnotatedElement,java/lang/invoke/TypeDescriptor,java/lang/reflect/GenericDeclaration,java/lang/reflect/Type,java/lang/invoke/TypeDescriptor$OfField):exact+120 *, name=a, idx=4; #int !jvms: TestMissingOptAbsZeroMinusX::testAbsI @ bci:13 (line 53)
0 434 AbsI === _ 103 [[ 433 ]] !orig=105 !jvms: TestMissingOptAbsZeroMinusX::testAbsI @ bci:20 (line 54)
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/bmaillar/src/jdk/JDK-8371536/open/src/hotspot/share/opto/phaseX.cpp:1096), pid=1958068, tid=1958086
# assert(!failure) failed: Missed Ideal optimization opportunity in PhaseIterGVN for AbsI
#
# JRE version: Java(TM) SE Runtime Environment (26.0) (fastdebug build 26-internal-bmaillar.open)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 26-internal-bmaillar.open, compiled mode, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V [libjvm.so+0x1889a12] PhaseIterGVN::verify_optimize()+0x8b2
#
</details>
### Testing
- [x] [GitHub Actions]([TODO](https://github.com/benoitmaillard/jdk/actions?query=branch%3AJDK-8371536))
- [x] tier1-4, plus some internal testing
- [x] Manual testing on recent missed optimizations reproducers, including [JDK-8371558](https://bugs.openjdk.org/browse/JDK-8371558), [JDK-8371534](https://bugs.openjdk.org/browse/JDK-8371534) and [JDK-8371674](https://bugs.openjdk.org/browse/JDK-8371674)
Thank you for reviewing!
-------------
Commit messages:
- Add comment for _table.hash_delete(n)
- Change assert to print only the cause and the node name
- Assert at first failure
- Remove node from hash table before calling Ideal in verification
Changes: https://git.openjdk.org/jdk/pull/28295/files
Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=28295&range=00
Issue: https://bugs.openjdk.org/browse/JDK-8371536
Stats: 29 lines in 1 file changed: 19 ins; 6 del; 4 mod
Patch: https://git.openjdk.org/jdk/pull/28295.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/28295/head:pull/28295
PR: https://git.openjdk.org/jdk/pull/28295
More information about the hotspot-compiler-dev
mailing list