changeset 12716:b70c17184fdb

Merge
author jwilhelm
date Thu, 30 Mar 2017 19:55:04 +0200
parents c68024d52834 (current diff) 60721d6ff1ac (diff)
children 0af429be8bba
files
diffstat 7 files changed, 75 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Sat Mar 25 00:31:29 2017 +0100
+++ b/.hgtags	Thu Mar 30 19:55:04 2017 +0200
@@ -565,3 +565,4 @@
 94b4e2e5331d38eab6a3639c3511b2e0715df0e9 jdk-9+160
 191ffbdb3d7b734288daa7fb76b37a0a85dfe7eb jdk-9+161
 b01c519b715ef6f785d0631adee0a6537cf6c12e jdk-9+162
+983fe207555724d98f4876991e1cbafbcf2733e8 jdk-9+163
--- a/src/cpu/aarch64/vm/aarch64.ad	Sat Mar 25 00:31:29 2017 +0100
+++ b/src/cpu/aarch64/vm/aarch64.ad	Thu Mar 30 19:55:04 2017 +0200
@@ -15501,7 +15501,7 @@
 %}
 
 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
-       iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
+       iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
 %{
   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
@@ -15520,7 +15520,7 @@
 %}
 
 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
-       iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
+       iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
 %{
   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
@@ -15539,7 +15539,7 @@
 %}
 
 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
-       iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
+       iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
 %{
   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
@@ -15558,7 +15558,7 @@
 %}
 
 instruct string_indexofLU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
-       iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
+       iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
 %{
   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LU);
   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
@@ -15577,8 +15577,8 @@
 %}
 
 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
-                 immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
-                 iRegI tmp3, iRegI tmp4, rFlagsReg cr)
+                 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
+                 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
 %{
   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
@@ -15598,8 +15598,8 @@
 %}
 
 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
-                 immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
-                 iRegI tmp3, iRegI tmp4, rFlagsReg cr)
+                 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
+                 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
 %{
   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
@@ -15619,8 +15619,8 @@
 %}
 
 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
-                 immI_1 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
-                 iRegI tmp3, iRegI tmp4, rFlagsReg cr)
+                 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
+                 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
 %{
   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
@@ -15640,8 +15640,8 @@
 %}
 
 instruct string_indexof_conLU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
-                 immI_1 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
-                 iRegI tmp3, iRegI tmp4, rFlagsReg cr)
+                 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
+                 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
 %{
   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LU);
   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
@@ -15661,8 +15661,8 @@
 %}
 
 instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch,
-                              iRegI_R0 result, iRegI tmp1, iRegI tmp2,
-                              iRegI tmp3, rFlagsReg cr)
+                              iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
+                              iRegINoSp tmp3, rFlagsReg cr)
 %{
   match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
   effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
@@ -16101,7 +16101,7 @@
 
 // ====================REDUCTION ARITHMETIC====================================
 
-instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegI tmp, iRegI tmp2)
+instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp, iRegINoSp tmp2)
 %{
   match(Set dst (AddReductionVI src1 src2));
   ins_cost(INSN_COST);
@@ -16120,7 +16120,7 @@
   ins_pipe(pipe_class_default);
 %}
 
-instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegI tmp2)
+instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2)
 %{
   match(Set dst (AddReductionVI src1 src2));
   ins_cost(INSN_COST);
@@ -16138,7 +16138,7 @@
   ins_pipe(pipe_class_default);
 %}
 
-instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegI tmp)
+instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp)
 %{
   match(Set dst (MulReductionVI src1 src2));
   ins_cost(INSN_COST);
@@ -16157,7 +16157,7 @@
   ins_pipe(pipe_class_default);
 %}
 
-instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegI tmp2)
+instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2)
 %{
   match(Set dst (MulReductionVI src1 src2));
   ins_cost(INSN_COST);
--- a/src/share/vm/opto/castnode.cpp	Sat Mar 25 00:31:29 2017 +0100
+++ b/src/share/vm/opto/castnode.cpp	Thu Mar 30 19:55:04 2017 +0200
@@ -225,7 +225,10 @@
   }
 
   // Similar to ConvI2LNode::Ideal() for the same reasons
-  if (can_reshape && !phase->C->major_progress()) {
+  // Do not narrow the type of range check dependent CastIINodes to
+  // avoid corruption of the graph if a CastII is replaced by TOP but
+  // the corresponding range check is not removed.
+  if (can_reshape && !_range_check_dependency && !phase->C->major_progress()) {
     const TypeInt* this_type = this->type()->is_int();
     const TypeInt* in_type = phase->type(in(1))->isa_int();
     if (in_type != NULL && this_type != NULL &&
--- a/src/share/vm/opto/convertnode.cpp	Sat Mar 25 00:31:29 2017 +0100
+++ b/src/share/vm/opto/convertnode.cpp	Thu Mar 30 19:55:04 2017 +0200
@@ -294,8 +294,7 @@
   }
 
 #ifdef _LP64
-  // Convert ConvI2L(AddI(x, y)) to AddL(ConvI2L(x), ConvI2L(y)) or
-  // ConvI2L(CastII(AddI(x, y))) to AddL(ConvI2L(CastII(x)), ConvI2L(CastII(y))),
+  // Convert ConvI2L(AddI(x, y)) to AddL(ConvI2L(x), ConvI2L(y))
   // but only if x and y have subranges that cannot cause 32-bit overflow,
   // under the assumption that x+y is in my own subrange this->type().
 
@@ -319,13 +318,6 @@
 
   Node* z = in(1);
   int op = z->Opcode();
-  Node* ctrl = NULL;
-  if (op == Op_CastII && z->as_CastII()->has_range_check()) {
-    // Skip CastII node but save control dependency
-    ctrl = z->in(0);
-    z = z->in(1);
-    op = z->Opcode();
-  }
   if (op == Op_AddI || op == Op_SubI) {
     Node* x = z->in(1);
     Node* y = z->in(2);
@@ -385,8 +377,8 @@
     }
     assert(rxlo == (int)rxlo && rxhi == (int)rxhi, "x should not overflow");
     assert(rylo == (int)rylo && ryhi == (int)ryhi, "y should not overflow");
-    Node* cx = phase->C->constrained_convI2L(phase, x, TypeInt::make(rxlo, rxhi, widen), ctrl);
-    Node* cy = phase->C->constrained_convI2L(phase, y, TypeInt::make(rylo, ryhi, widen), ctrl);
+    Node* cx = phase->C->constrained_convI2L(phase, x, TypeInt::make(rxlo, rxhi, widen), NULL);
+    Node* cy = phase->C->constrained_convI2L(phase, y, TypeInt::make(rylo, ryhi, widen), NULL);
     switch (op) {
       case Op_AddI:  return new AddLNode(cx, cy);
       case Op_SubI:  return new SubLNode(cx, cy);
--- a/src/share/vm/opto/library_call.cpp	Sat Mar 25 00:31:29 2017 +0100
+++ b/src/share/vm/opto/library_call.cpp	Thu Mar 30 19:55:04 2017 +0200
@@ -2372,7 +2372,7 @@
   // the barriers get omitted and the unsafe reference begins to "pollute"
   // the alias analysis of the rest of the graph, either Compile::can_alias
   // or Compile::must_alias will throw a diagnostic assert.)
-  bool need_mem_bar;
+  bool need_mem_bar = false;
   switch (kind) {
       case Relaxed:
           need_mem_bar = mismatched && !adr_type->isa_aryptr();
--- a/test/compiler/loopopts/TestLoopPeeling.java	Sat Mar 25 00:31:29 2017 +0100
+++ b/test/compiler/loopopts/TestLoopPeeling.java	Thu Mar 30 19:55:04 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8078262
+ * @bug 8078262 8177095
  * @summary Tests correct dominator information after loop peeling.
  *
  * @run main/othervm -Xcomp
@@ -40,14 +40,16 @@
     public static void main(String args[]) {
         TestLoopPeeling test = new TestLoopPeeling();
         try {
-            test.testArrayAccess(0, 1);
+            test.testArrayAccess1(0, 1);
+            test.testArrayAccess2(0);
+            test.testArrayAccess3(0, false);
             test.testArrayAllocation(0, 1);
         } catch (Exception e) {
             // Ignore exceptions
         }
     }
 
-    public void testArrayAccess(int index, int inc) {
+    public void testArrayAccess1(int index, int inc) {
         int storeIndex = -1;
 
         for (; index < 10; index += inc) {
@@ -63,7 +65,7 @@
 
             if (index == 42) {
                 // This store and the corresponding range check are moved out of the
-                // loop and both used after old loop and the peeled iteration exit.
+                // loop and both used after main loop and the peeled iteration exit.
                 // For the peeled iteration, storeIndex is always -1 and the ConvI2L
                 // is replaced by TOP. However, the range check is not folded because
                 // we don't do the split if optimization in PhaseIdealLoop2.
@@ -77,6 +79,44 @@
         }
     }
 
+    public int testArrayAccess2(int index) {
+        // Load1 and the corresponding range check are moved out of the loop
+        // and both are used after the main loop and the peeled iteration exit.
+        // For the peeled iteration, storeIndex is always Integer.MIN_VALUE and
+        // for the main loop it is 0. Hence, the merging phi has type int:<=0.
+        // Load1 reads the array at index ConvI2L(CastII(AddI(storeIndex, -1)))
+        // where the CastII is range check dependent and has type int:>=0.
+        // The CastII gets pushed through the AddI and its type is changed to int:>=1
+        // which does not overlap with the input type of storeIndex (int:<=0).
+        // The CastII is replaced by TOP causing a cascade of other eliminations.
+        // Since the control path through the range check CmpU(AddI(storeIndex, -1))
+        // is not eliminated, the graph is in a corrupted state. We fail once we merge
+        // with the result of Load2 because we get data from a non-dominating region.
+        int storeIndex = Integer.MIN_VALUE;
+        for (; index < 10; ++index) {
+            if (index == 42) {
+                return array[storeIndex-1]; // Load1
+            }
+            storeIndex = 0;
+        }
+        return array[42]; // Load2
+    }
+
+    public int testArrayAccess3(int index, boolean b) {
+        // Same as testArrayAccess2 but manifests as crash in register allocator.
+        int storeIndex = Integer.MIN_VALUE;
+        for (; index < 10; ++index) {
+            if (b) {
+                return 0;
+            }
+            if (index == 42) {
+                return array[storeIndex-1]; // Load1
+            }
+            storeIndex = 0;
+        }
+        return array[42]; // Load2
+    }
+
     public byte[] testArrayAllocation(int index, int inc) {
         int allocationCount = -1;
         byte[] result;
@@ -88,7 +128,7 @@
 
             if (index == 42) {
                 // This allocation and the corresponding size check are moved out of the
-                // loop and both used after old loop and the peeled iteration exit.
+                // loop and both used after main loop and the peeled iteration exit.
                 // For the peeled iteration, allocationCount is always -1 and the ConvI2L
                 // is replaced by TOP. However, the size check is not folded because
                 // we don't do the split if optimization in PhaseIdealLoop2.
--- a/test/serviceability/jvmti/GetNamedModule/libGetNamedModuleTest.c	Sat Mar 25 00:31:29 2017 +0100
+++ b/test/serviceability/jvmti/GetNamedModule/libGetNamedModuleTest.c	Thu Mar 30 19:55:04 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -183,7 +183,7 @@
     err = (*jvmti)->GetNamedModule(jvmti, loader, pkg_name, module_ptr);
     if (err != JVMTI_ERROR_NONE) {
         printf("    Error in GetNamedModule for package \"%s\": %s (%d)\n",
-               pkg_name, TranslateError(err), err);
+               name, TranslateError(err), err);
         return err;
     }
     printf("    returned module: %p\n", *module_ptr);