From 10ff90d9a7d287c57574d6c623337d96da3f73af Mon Sep 17 00:00:00 2001 From: Quan Anh Mai Date: Sun, 24 May 2026 03:53:29 +0000 Subject: [PATCH] 8385137: C2: Uncast arguments to MemNode::all_control_dominate in some cases Reviewed-by: dlong, kvn --- src/hotspot/share/opto/memnode.cpp | 10 +++---- .../jtreg/compiler/c2/gvn/TestFindStore.java | 27 ++++++++++++++++++- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index 1521f89af4e..d5737166bb6 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp @@ -562,7 +562,7 @@ bool MemNode::detect_ptr_independence(Node* p1, AllocateNode* a1, // TypePtr::NULL_PTR, so we exclude that case. const Type* p1_type = p1->bottom_type(); const Type* p2_type = p2->bottom_type(); - if (p1_type->isa_oopptr() && p2_type->isa_oopptr() && + if (p1_type != p2_type && p1_type->isa_oopptr() && p2_type->isa_oopptr() && (!p1_type->maybe_null() || !p2_type->maybe_null()) && p1_type->join(p2_type)->empty()) { return true; @@ -578,9 +578,9 @@ bool MemNode::detect_ptr_independence(Node* p1, AllocateNode* a1, return (a1 != a2); } else if (a1 != nullptr) { // one allocation a1 // (Note: p2->is_Con implies p2->in(0)->is_Root, which dominates.) - return all_controls_dominate(p2, a1, phase); + return all_controls_dominate(p2->uncast(), a1, phase); } else { //(a2 != null) // one allocation a2 - return all_controls_dominate(p1, a2, phase); + return all_controls_dominate(p1->uncast(), a2, phase); } return false; } @@ -886,14 +886,14 @@ AccessAnalyzer::AccessIndependence AccessAnalyzer::detect_access_independence(No known_identical = true; } else if (_alloc != nullptr) { known_independent = true; - } else if (MemNode::all_controls_dominate(_n, st_alloc, _phase)) { + } else if (MemNode::all_controls_dominate(_base->uncast(), st_alloc, _phase)) { known_independent = true; } if (known_independent) { // The bases are provably independent: Either they are // manifestly distinct allocations, or else the control - // of _n dominates the store's allocation. + // of _base dominates the store's allocation. if (_alias_idx == Compile::AliasIdxRaw) { other = st_alloc->in(TypeFunc::Memory); } else { diff --git a/test/hotspot/jtreg/compiler/c2/gvn/TestFindStore.java b/test/hotspot/jtreg/compiler/c2/gvn/TestFindStore.java index aac3e0cf980..32eaebd2ba1 100644 --- a/test/hotspot/jtreg/compiler/c2/gvn/TestFindStore.java +++ b/test/hotspot/jtreg/compiler/c2/gvn/TestFindStore.java @@ -55,7 +55,8 @@ public class TestFindStore { @Run(test = {"testLoad", "testStore", "testLoadDependent1", "testLoadDependent2", "testLoadArray", "testLoadArrayOverlap", "testLoadIndependentAliasClasses", "testLoadMismatched", - "testLoadArrayCopy", "testLoadArrayCopyUnknownLength"}) + "testLoadArrayCopy", "testLoadArrayCopyUnknownLength", + "testAllocationIndependence1", "testAllocationIndependence2"}) public void run() { C1 c1 = new C1(); C2 c2 = new C2(); @@ -81,6 +82,9 @@ public class TestFindStore { Asserts.assertEQ(1, testLoadArrayCopyUnknownLength(a1, a2, 100, 1)); a1[2] = 0; Asserts.assertEQ(0, testLoadArrayCopyUnknownLength(a1, a2, 2, 1)); + + Asserts.assertEQ(3, testAllocationIndependence1(c1, 1, 2).v); + Asserts.assertEQ(3, testAllocationIndependence2(c1, 1, 2).v); } @Test @@ -170,4 +174,25 @@ public class TestFindStore { System.arraycopy(a2, 0, a1, 0, len); return a1[2]; } + + @Test + @IR(failOn = IRNode.LOAD, phase = CompilePhase.BEFORE_MACRO_EXPANSION) + static C1 testAllocationIndependence1(C1 o1, int v1, int v2) { + // o1 and o2 are independent + o1.v = v1; + C1 o2 = new C1(); + o2.v = o1.v + v2; + return o2; + } + + @Test + @IR(failOn = IRNode.LOAD, phase = CompilePhase.BEFORE_MACRO_EXPANSION) + static C1 testAllocationIndependence2(C1 o1, int v1, int v2) { + // o1 and o2 are independent, but we also want CastPP(o1) and o2 being independent + C1 o2 = new C1(); + o1.v = v1; + o2.v = v2; + o2.v = o1.v + o2.v; + return o2; + } }