--- a/hotspot/src/share/vm/opto/memnode.cpp Thu Dec 01 14:21:31 2016 -0500
+++ b/hotspot/src/share/vm/opto/memnode.cpp Wed Apr 19 18:02:26 2017 -0700
@@ -61,6 +61,15 @@
return calculate_adr_type(adr->bottom_type(), cross_check);
}
+bool MemNode::check_if_adr_maybe_raw(Node* adr) {
+ if (adr != NULL) {
+ if (adr->bottom_type()->base() == Type::RawPtr || adr->bottom_type()->base() == Type::AnyPtr) {
+ return true;
+ }
+ }
+ return false;
+}
+
#ifndef PRODUCT
void MemNode::dump_spec(outputStream *st) const {
if (in(Address) == NULL) return; // node is dead
@@ -560,6 +569,7 @@
if (offset == Type::OffsetBot)
return NULL; // cannot unalias unless there are precise offsets
+ const bool adr_maybe_raw = check_if_adr_maybe_raw(adr);
const TypeOopPtr *addr_t = adr->bottom_type()->isa_oopptr();
intptr_t size_in_bytes = memory_size();
@@ -577,6 +587,13 @@
Node* st_base = AddPNode::Ideal_base_and_offset(st_adr, phase, st_offset);
if (st_base == NULL)
break; // inscrutable pointer
+
+ // For raw accesses it's not enough to prove that constant offsets don't intersect.
+ // We need the bases to be the equal in order for the offset check to make sense.
+ if ((adr_maybe_raw || check_if_adr_maybe_raw(st_adr)) && st_base != base) {
+ break;
+ }
+
if (st_offset != offset && st_offset != Type::OffsetBot) {
const int MAX_STORE = BytesPerLong;
if (st_offset >= offset + size_in_bytes ||