hotspot/src/share/vm/opto/memnode.cpp
changeset 44739 3af2c3740d7b
parent 42063 dca9294d9f59
child 45241 dec8c0efd17b
--- 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 ||