< prev index next >

src/hotspot/share/opto/superword.cpp

Print this page

        

@@ -611,11 +611,11 @@
 
     // Create initial pack pairs of memory operations for which
     // alignment is set and vectors will be aligned.
     bool create_pack = true;
     if (memory_alignment(mem_ref, best_iv_adjustment) == 0 || _do_vector_loop) {
-      if (!Matcher::misaligned_vectors_ok()) {
+      if (!Matcher::misaligned_vectors_ok() || AlignVector) {
         int vw = vector_width(mem_ref);
         int vw_best = vector_width(best_align_to_mem_ref);
         if (vw > vw_best) {
           // Do not vectorize a memory access with more elements per vector
           // if unaligned memory access is not allowed because number of

@@ -636,11 +636,11 @@
         // same type since it could be overlapped accesses to the same array.
         create_pack = false;
       } else {
         // Allow independent (different type) unaligned memory operations
         // if HW supports them.
-        if (!Matcher::misaligned_vectors_ok()) {
+        if (!Matcher::misaligned_vectors_ok() || AlignVector) {
           create_pack = false;
         } else {
           // Check if packs of the same memory type but
           // with a different alignment were created before.
           for (uint i = 0; i < align_to_refs.size(); i++) {

@@ -3356,13 +3356,13 @@
       e = new AddINode(e, aref);
     }
     _igvn.register_new_node_with_optimizer(e);
     _phase->set_ctrl(e, pre_ctrl);
   }
-  if (vw > ObjectAlignmentInBytes) {
+  if (vw > ObjectAlignmentInBytes || align_to_ref_p.base()->is_top()) {
     // incorporate base e +/- base && Mask >>> log2(elt)
-    Node* xbase = new CastP2XNode(NULL, align_to_ref_p.base());
+    Node* xbase = new CastP2XNode(NULL, align_to_ref_p.adr());
     _igvn.register_new_node_with_optimizer(xbase);
 #ifdef _LP64
     xbase  = new ConvL2INode(xbase);
     _igvn.register_new_node_with_optimizer(xbase);
 #endif

@@ -3550,12 +3550,12 @@
   // The base address should be loop invariant
   if (!invariant(base)) {
     assert(!valid(), "base address is loop variant");
     return;
   }
-  //unsafe reference could not be aligned appropriately without runtime checking
-  if (base == NULL || base->bottom_type() == Type::TOP) {
+  // unsafe references require misaligned vector access support
+  if (base->is_top() && !Matcher::misaligned_vectors_ok()) {
     assert(!valid(), "unsafe access");
     return;
   }
 
   NOT_PRODUCT(if(_slp->is_trace_alignment()) _tracer.store_depth();)

@@ -3575,10 +3575,20 @@
     if (base == adr || !adr->is_AddP()) {
       NOT_PRODUCT(_tracer.ctor_5(adr, base, i);)
       break; // stop looking at addp's
     }
   }
+  if (!invariant(adr)) {
+    assert(!valid(), "adr is loop variant");
+    return;
+  }
+
+  if (!base->is_top() && adr != base) {
+    assert(!valid(), "adr and base differ");
+    return;
+  }
+
   NOT_PRODUCT(if(_slp->is_trace_alignment()) _tracer.restore_depth();)
   NOT_PRODUCT(_tracer.ctor_6(mem);)
 
   _base = base;
   _adr  = adr;
< prev index next >