6675699: need comprehensive fix for unconstrained ConvI2L with narrowed type

Wed, 27 Jan 2016 09:02:51 +0100

author
thartmann
date
Wed, 27 Jan 2016 09:02:51 +0100
changeset 8285
535618ab1c04
parent 8282
16f7b676725a
child 8286
7a567d2cc7fb

6675699: need comprehensive fix for unconstrained ConvI2L with narrowed type
Summary: Emit CastII to make narrow ConvI2L dependent on the corresponding range check.
Reviewed-by: kvn, roland

src/share/vm/opto/compile.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/compile.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/connode.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/connode.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/graphKit.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/graphKit.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/loopTransform.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/loopopts.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/node.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/node.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/parse2.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/phaseX.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/superword.cpp file | annotate | diff | comparison | revisions
test/compiler/loopopts/TestLoopPeeling.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/opto/compile.cpp	Mon Jan 25 08:46:19 2016 +0000
     1.2 +++ b/src/share/vm/opto/compile.cpp	Wed Jan 27 09:02:51 2016 +0100
     1.3 @@ -412,6 +412,13 @@
     1.4        remove_macro_node(n);
     1.5      }
     1.6    }
     1.7 +  // Remove useless CastII nodes with range check dependency
     1.8 +  for (int i = range_check_cast_count() - 1; i >= 0; i--) {
     1.9 +    Node* cast = range_check_cast_node(i);
    1.10 +    if (!useful.member(cast)) {
    1.11 +      remove_range_check_cast(cast);
    1.12 +    }
    1.13 +  }
    1.14    // Remove useless expensive node
    1.15    for (int i = C->expensive_count()-1; i >= 0; i--) {
    1.16      Node* n = C->expensive_node(i);
    1.17 @@ -1148,6 +1155,7 @@
    1.18    _macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
    1.19    _predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
    1.20    _expensive_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
    1.21 +  _range_check_casts = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
    1.22    register_library_intrinsics();
    1.23  }
    1.24  
    1.25 @@ -1876,6 +1884,22 @@
    1.26    assert(predicate_count()==0, "should be clean!");
    1.27  }
    1.28  
    1.29 +void Compile::add_range_check_cast(Node* n) {
    1.30 +  assert(n->isa_CastII()->has_range_check(), "CastII should have range check dependency");
    1.31 +  assert(!_range_check_casts->contains(n), "duplicate entry in range check casts");
    1.32 +  _range_check_casts->append(n);
    1.33 +}
    1.34 +
    1.35 +// Remove all range check dependent CastIINodes.
    1.36 +void Compile::remove_range_check_casts(PhaseIterGVN &igvn) {
    1.37 +  for (int i = range_check_cast_count(); i > 0; i--) {
    1.38 +    Node* cast = range_check_cast_node(i-1);
    1.39 +    assert(cast->isa_CastII()->has_range_check(), "CastII should have range check dependency");
    1.40 +    igvn.replace_node(cast, cast->in(1));
    1.41 +  }
    1.42 +  assert(range_check_cast_count() == 0, "should be empty");
    1.43 +}
    1.44 +
    1.45  // StringOpts and late inlining of string methods
    1.46  void Compile::inline_string_calls(bool parse_time) {
    1.47    {
    1.48 @@ -2218,6 +2242,12 @@
    1.49      PhaseIdealLoop::verify(igvn);
    1.50    }
    1.51  
    1.52 +  if (range_check_cast_count() > 0) {
    1.53 +    // No more loop optimizations. Remove all range check dependent CastIINodes.
    1.54 +    C->remove_range_check_casts(igvn);
    1.55 +    igvn.optimize();
    1.56 +  }
    1.57 +
    1.58    {
    1.59      NOT_PRODUCT( TracePhase t2("macroExpand", &_t_macroExpand, TimeCompiler); )
    1.60      PhaseMacroExpand  mex(igvn);
    1.61 @@ -2987,6 +3017,16 @@
    1.62  
    1.63  #endif
    1.64  
    1.65 +#ifdef ASSERT
    1.66 +  case Op_CastII:
    1.67 +    // Verify that all range check dependent CastII nodes were removed.
    1.68 +    if (n->isa_CastII()->has_range_check()) {
    1.69 +      n->dump(3);
    1.70 +      assert(false, "Range check dependent CastII node was not removed");
    1.71 +    }
    1.72 +    break;
    1.73 +#endif
    1.74 +
    1.75    case Op_ModI:
    1.76      if (UseDivMod) {
    1.77        // Check if a%b and a/b both exist
    1.78 @@ -4024,6 +4064,24 @@
    1.79    }
    1.80  }
    1.81  
    1.82 +// Convert integer value to a narrowed long type dependent on ctrl (for example, a range check)
    1.83 +Node* Compile::constrained_convI2L(PhaseGVN* phase, Node* value, const TypeInt* itype, Node* ctrl) {
    1.84 +  if (ctrl != NULL) {
    1.85 +    // Express control dependency by a CastII node with a narrow type.
    1.86 +    value = new (phase->C) CastIINode(value, itype, false, true /* range check dependency */);
    1.87 +    // Make the CastII node dependent on the control input to prevent the narrowed ConvI2L
    1.88 +    // node from floating above the range check during loop optimizations. Otherwise, the
    1.89 +    // ConvI2L node may be eliminated independently of the range check, causing the data path
    1.90 +    // to become TOP while the control path is still there (although it's unreachable).
    1.91 +    value->set_req(0, ctrl);
    1.92 +    // Save CastII node to remove it after loop optimizations.
    1.93 +    phase->C->add_range_check_cast(value);
    1.94 +    value = phase->transform(value);
    1.95 +  }
    1.96 +  const TypeLong* ltype = TypeLong::make(itype->_lo, itype->_hi, itype->_widen);
    1.97 +  return phase->transform(new (phase->C) ConvI2LNode(value, ltype));
    1.98 +}
    1.99 +
   1.100  // Auxiliary method to support randomized stressing/fuzzing.
   1.101  //
   1.102  // This method can be called the arbitrary number of times, with current count
     2.1 --- a/src/share/vm/opto/compile.hpp	Mon Jan 25 08:46:19 2016 +0000
     2.2 +++ b/src/share/vm/opto/compile.hpp	Wed Jan 27 09:02:51 2016 +0100
     2.3 @@ -75,6 +75,7 @@
     2.4  class JVMState;
     2.5  class Type;
     2.6  class TypeData;
     2.7 +class TypeInt;
     2.8  class TypePtr;
     2.9  class TypeOopPtr;
    2.10  class TypeFunc;
    2.11 @@ -334,6 +335,7 @@
    2.12    GrowableArray<Node*>* _macro_nodes;           // List of nodes which need to be expanded before matching.
    2.13    GrowableArray<Node*>* _predicate_opaqs;       // List of Opaque1 nodes for the loop predicates.
    2.14    GrowableArray<Node*>* _expensive_nodes;       // List of nodes that are expensive to compute and that we'd better not let the GVN freely common
    2.15 +  GrowableArray<Node*>* _range_check_casts;     // List of CastII nodes with a range check dependency
    2.16    ConnectionGraph*      _congraph;
    2.17  #ifndef PRODUCT
    2.18    IdealGraphPrinter*    _printer;
    2.19 @@ -669,7 +671,7 @@
    2.20    void set_congraph(ConnectionGraph* congraph)  { _congraph = congraph;}
    2.21    void add_macro_node(Node * n) {
    2.22      //assert(n->is_macro(), "must be a macro node");
    2.23 -    assert(!_macro_nodes->contains(n), " duplicate entry in expand list");
    2.24 +    assert(!_macro_nodes->contains(n), "duplicate entry in expand list");
    2.25      _macro_nodes->append(n);
    2.26    }
    2.27    void remove_macro_node(Node * n) {
    2.28 @@ -689,10 +691,23 @@
    2.29      }
    2.30    }
    2.31    void add_predicate_opaq(Node * n) {
    2.32 -    assert(!_predicate_opaqs->contains(n), " duplicate entry in predicate opaque1");
    2.33 +    assert(!_predicate_opaqs->contains(n), "duplicate entry in predicate opaque1");
    2.34      assert(_macro_nodes->contains(n), "should have already been in macro list");
    2.35      _predicate_opaqs->append(n);
    2.36    }
    2.37 +
    2.38 +  // Range check dependent CastII nodes that can be removed after loop optimizations
    2.39 +  void add_range_check_cast(Node* n);
    2.40 +  void remove_range_check_cast(Node* n) {
    2.41 +    if (_range_check_casts->contains(n)) {
    2.42 +      _range_check_casts->remove(n);
    2.43 +    }
    2.44 +  }
    2.45 +  Node* range_check_cast_node(int idx) const { return _range_check_casts->at(idx);  }
    2.46 +  int   range_check_cast_count()       const { return _range_check_casts->length(); }
    2.47 +  // Remove all range check dependent CastIINodes.
    2.48 +  void  remove_range_check_casts(PhaseIterGVN &igvn);
    2.49 +
    2.50    // remove the opaque nodes that protect the predicates so that the unused checks and
    2.51    // uncommon traps will be eliminated from the graph.
    2.52    void cleanup_loop_predicates(PhaseIterGVN &igvn);
    2.53 @@ -1201,6 +1216,9 @@
    2.54    // Definitions of pd methods
    2.55    static void pd_compiler2_init();
    2.56  
    2.57 +  // Convert integer value to a narrowed long type dependent on ctrl (for example, a range check)
    2.58 +  static Node* constrained_convI2L(PhaseGVN* phase, Node* value, const TypeInt* itype, Node* ctrl);
    2.59 +
    2.60    // Auxiliary method for randomized fuzzing/stressing
    2.61    static bool randomized_select(int count);
    2.62  };
     3.1 --- a/src/share/vm/opto/connode.cpp	Mon Jan 25 08:46:19 2016 +0000
     3.2 +++ b/src/share/vm/opto/connode.cpp	Wed Jan 27 09:02:51 2016 +0100
     3.3 @@ -535,6 +535,9 @@
     3.4    if (_carry_dependency) {
     3.5      st->print(" carry dependency");
     3.6    }
     3.7 +  if (_range_check_dependency) {
     3.8 +    st->print(" range check dependency");
     3.9 +  }
    3.10  }
    3.11  #endif
    3.12  
    3.13 @@ -994,7 +997,8 @@
    3.14    }
    3.15  
    3.16  #ifdef _LP64
    3.17 -  // Convert ConvI2L(AddI(x, y)) to AddL(ConvI2L(x), ConvI2L(y)) ,
    3.18 +  // Convert ConvI2L(AddI(x, y)) to AddL(ConvI2L(x), ConvI2L(y)) or
    3.19 +  // ConvI2L(CastII(AddI(x, y))) to AddL(ConvI2L(CastII(x)), ConvI2L(CastII(y))),
    3.20    // but only if x and y have subranges that cannot cause 32-bit overflow,
    3.21    // under the assumption that x+y is in my own subrange this->type().
    3.22  
    3.23 @@ -1018,6 +1022,13 @@
    3.24  
    3.25    Node* z = in(1);
    3.26    int op = z->Opcode();
    3.27 +  Node* ctrl = NULL;
    3.28 +  if (op == Op_CastII && z->as_CastII()->has_range_check()) {
    3.29 +    // Skip CastII node but save control dependency
    3.30 +    ctrl = z->in(0);
    3.31 +    z = z->in(1);
    3.32 +    op = z->Opcode();
    3.33 +  }
    3.34    if (op == Op_AddI || op == Op_SubI) {
    3.35      Node* x = z->in(1);
    3.36      Node* y = z->in(2);
    3.37 @@ -1075,9 +1086,10 @@
    3.38        rylo = -ryhi;
    3.39        ryhi = -rylo0;
    3.40      }
    3.41 -
    3.42 -    Node* cx = phase->transform( new (phase->C) ConvI2LNode(x, TypeLong::make(rxlo, rxhi, widen)) );
    3.43 -    Node* cy = phase->transform( new (phase->C) ConvI2LNode(y, TypeLong::make(rylo, ryhi, widen)) );
    3.44 +    assert(rxlo == (int)rxlo && rxhi == (int)rxhi, "x should not overflow");
    3.45 +    assert(rylo == (int)rylo && ryhi == (int)ryhi, "y should not overflow");
    3.46 +    Node* cx = phase->C->constrained_convI2L(phase, x, TypeInt::make(rxlo, rxhi, widen), ctrl);
    3.47 +    Node* cy = phase->C->constrained_convI2L(phase, y, TypeInt::make(rylo, ryhi, widen), ctrl);
    3.48      switch (op) {
    3.49      case Op_AddI:  return new (phase->C) AddLNode(cx, cy);
    3.50      case Op_SubI:  return new (phase->C) SubLNode(cx, cy);
     4.1 --- a/src/share/vm/opto/connode.hpp	Mon Jan 25 08:46:19 2016 +0000
     4.2 +++ b/src/share/vm/opto/connode.hpp	Wed Jan 27 09:02:51 2016 +0100
     4.3 @@ -244,19 +244,31 @@
     4.4    private:
     4.5    // Can this node be removed post CCP or does it carry a required dependency?
     4.6    const bool _carry_dependency;
     4.7 +  // Is this node dependent on a range check?
     4.8 +  const bool _range_check_dependency;
     4.9  
    4.10    protected:
    4.11    virtual uint cmp( const Node &n ) const;
    4.12    virtual uint size_of() const;
    4.13  
    4.14  public:
    4.15 -  CastIINode(Node *n, const Type *t, bool carry_dependency = false)
    4.16 -    : ConstraintCastNode(n,t), _carry_dependency(carry_dependency) {}
    4.17 +  CastIINode(Node *n, const Type *t, bool carry_dependency = false, bool range_check_dependency = false)
    4.18 +    : ConstraintCastNode(n,t), _carry_dependency(carry_dependency), _range_check_dependency(range_check_dependency) {
    4.19 +    init_class_id(Class_CastII);
    4.20 +  }
    4.21    virtual int Opcode() const;
    4.22    virtual uint ideal_reg() const { return Op_RegI; }
    4.23    virtual Node *Identity( PhaseTransform *phase );
    4.24    virtual const Type *Value( PhaseTransform *phase ) const;
    4.25    virtual Node *Ideal_DU_postCCP( PhaseCCP * );
    4.26 +  const bool has_range_check() {
    4.27 + #ifdef _LP64
    4.28 +     return _range_check_dependency;
    4.29 + #else
    4.30 +     assert(!_range_check_dependency, "Should not have range check dependency");
    4.31 +     return false;
    4.32 + #endif
    4.33 +   }
    4.34  #ifndef PRODUCT
    4.35    virtual void dump_spec(outputStream *st) const;
    4.36  #endif
     5.1 --- a/src/share/vm/opto/graphKit.cpp	Mon Jan 25 08:46:19 2016 +0000
     5.2 +++ b/src/share/vm/opto/graphKit.cpp	Wed Jan 27 09:02:51 2016 +0100
     5.3 @@ -1645,7 +1645,7 @@
     5.4  
     5.5  //-------------------------array_element_address-------------------------
     5.6  Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt,
     5.7 -                                      const TypeInt* sizetype) {
     5.8 +                                      const TypeInt* sizetype, Node* ctrl) {
     5.9    uint shift  = exact_log2(type2aelembytes(elembt));
    5.10    uint header = arrayOopDesc::base_offset_in_bytes(elembt);
    5.11  
    5.12 @@ -1670,9 +1670,9 @@
    5.13    // number.  (The prior range check has ensured this.)
    5.14    // This assertion is used by ConvI2LNode::Ideal.
    5.15    int index_max = max_jint - 1;  // array size is max_jint, index is one less
    5.16 -  if (sizetype != NULL)  index_max = sizetype->_hi - 1;
    5.17 -  const TypeLong* lidxtype = TypeLong::make(CONST64(0), index_max, Type::WidenMax);
    5.18 -  idx = _gvn.transform( new (C) ConvI2LNode(idx, lidxtype) );
    5.19 +  if (sizetype != NULL) index_max = sizetype->_hi - 1;
    5.20 +  const TypeInt* iidxtype = TypeInt::make(0, index_max, Type::WidenMax);
    5.21 +  idx = C->constrained_convI2L(&_gvn, idx, iidxtype, ctrl);
    5.22  #endif
    5.23    Node* scale = _gvn.transform( new (C) LShiftXNode(idx, intcon(shift)) );
    5.24    return basic_plus_adr(ary, base, scale);
    5.25 @@ -3491,10 +3491,6 @@
    5.26  
    5.27    Node* initial_slow_cmp  = _gvn.transform( new (C) CmpUNode( length, intcon( fast_size_limit ) ) );
    5.28    Node* initial_slow_test = _gvn.transform( new (C) BoolNode( initial_slow_cmp, BoolTest::gt ) );
    5.29 -  if (initial_slow_test->is_Bool()) {
    5.30 -    // Hide it behind a CMoveI, or else PhaseIdealLoop::split_up will get sick.
    5.31 -    initial_slow_test = initial_slow_test->as_Bool()->as_int_value(&_gvn);
    5.32 -  }
    5.33  
    5.34    // --- Size Computation ---
    5.35    // array_size = round_to_heap(array_header + (length << elem_shift));
    5.36 @@ -3540,13 +3536,35 @@
    5.37    Node* lengthx = ConvI2X(length);
    5.38    Node* headerx = ConvI2X(header_size);
    5.39  #ifdef _LP64
    5.40 -  { const TypeLong* tllen = _gvn.find_long_type(lengthx);
    5.41 -    if (tllen != NULL && tllen->_lo < 0) {
    5.42 +  { const TypeInt* tilen = _gvn.find_int_type(length);
    5.43 +    if (tilen != NULL && tilen->_lo < 0) {
    5.44        // Add a manual constraint to a positive range.  Cf. array_element_address.
    5.45 -      jlong size_max = arrayOopDesc::max_array_length(T_BYTE);
    5.46 -      if (size_max > tllen->_hi)  size_max = tllen->_hi;
    5.47 -      const TypeLong* tlcon = TypeLong::make(CONST64(0), size_max, Type::WidenMin);
    5.48 -      lengthx = _gvn.transform( new (C) ConvI2LNode(length, tlcon));
    5.49 +      jlong size_max = fast_size_limit;
    5.50 +      if (size_max > tilen->_hi)  size_max = tilen->_hi;
    5.51 +      const TypeInt* tlcon = TypeInt::make(0, size_max, Type::WidenMin);
    5.52 +
    5.53 +      // Only do a narrow I2L conversion if the range check passed.
    5.54 +      IfNode* iff = new (C) IfNode(control(), initial_slow_test, PROB_MIN, COUNT_UNKNOWN);
    5.55 +      _gvn.transform(iff);
    5.56 +      RegionNode* region = new (C) RegionNode(3);
    5.57 +      _gvn.set_type(region, Type::CONTROL);
    5.58 +      lengthx = new (C) PhiNode(region, TypeLong::LONG);
    5.59 +      _gvn.set_type(lengthx, TypeLong::LONG);
    5.60 +
    5.61 +      // Range check passed. Use ConvI2L node with narrow type.
    5.62 +      Node* passed = IfFalse(iff);
    5.63 +      region->init_req(1, passed);
    5.64 +      // Make I2L conversion control dependent to prevent it from
    5.65 +      // floating above the range check during loop optimizations.
    5.66 +      lengthx->init_req(1, C->constrained_convI2L(&_gvn, length, tlcon, passed));
    5.67 +
    5.68 +      // Range check failed. Use ConvI2L with wide type because length may be invalid.
    5.69 +      region->init_req(2, IfTrue(iff));
    5.70 +      lengthx->init_req(2, ConvI2X(length));
    5.71 +
    5.72 +      set_control(region);
    5.73 +      record_for_igvn(region);
    5.74 +      record_for_igvn(lengthx);
    5.75      }
    5.76    }
    5.77  #endif
    5.78 @@ -3577,6 +3595,11 @@
    5.79    Node *mem = reset_memory();
    5.80    set_all_memory(mem); // Create new memory state
    5.81  
    5.82 +  if (initial_slow_test->is_Bool()) {
    5.83 +    // Hide it behind a CMoveI, or else PhaseIdealLoop::split_up will get sick.
    5.84 +    initial_slow_test = initial_slow_test->as_Bool()->as_int_value(&_gvn);
    5.85 +  }
    5.86 +
    5.87    // Create the AllocateArrayNode and its result projections
    5.88    AllocateArrayNode* alloc
    5.89      = new (C) AllocateArrayNode(C, AllocateArrayNode::alloc_type(TypeInt::INT),
     6.1 --- a/src/share/vm/opto/graphKit.hpp	Mon Jan 25 08:46:19 2016 +0000
     6.2 +++ b/src/share/vm/opto/graphKit.hpp	Wed Jan 27 09:02:51 2016 +0100
     6.3 @@ -626,7 +626,9 @@
     6.4    // Return addressing for an array element.
     6.5    Node* array_element_address(Node* ary, Node* idx, BasicType elembt,
     6.6                                // Optional constraint on the array size:
     6.7 -                              const TypeInt* sizetype = NULL);
     6.8 +                              const TypeInt* sizetype = NULL,
     6.9 +                              // Optional control dependency (for example, on range check)
    6.10 +                              Node* ctrl = NULL);
    6.11  
    6.12    // Return a load of array element at idx.
    6.13    Node* load_array_element(Node* ctl, Node* ary, Node* idx, const TypeAryPtr* arytype);
     7.1 --- a/src/share/vm/opto/loopTransform.cpp	Mon Jan 25 08:46:19 2016 +0000
     7.2 +++ b/src/share/vm/opto/loopTransform.cpp	Wed Jan 27 09:02:51 2016 +0100
     7.3 @@ -2438,7 +2438,7 @@
     7.4  
     7.5  //=============================================================================
     7.6  // Process all the loops in the loop tree and replace any fill
     7.7 -// patterns with an intrisc version.
     7.8 +// patterns with an intrinsic version.
     7.9  bool PhaseIdealLoop::do_intrinsify_fill() {
    7.10    bool changed = false;
    7.11    for (LoopTreeIterator iter(_ltree_root); !iter.done(); iter.next()) {
    7.12 @@ -2536,8 +2536,9 @@
    7.13    }
    7.14  
    7.15    // Make sure the address expression can be handled.  It should be
    7.16 -  // head->phi * elsize + con.  head->phi might have a ConvI2L.
    7.17 +  // head->phi * elsize + con.  head->phi might have a ConvI2L(CastII()).
    7.18    Node* elements[4];
    7.19 +  Node* cast = NULL;
    7.20    Node* conv = NULL;
    7.21    bool found_index = false;
    7.22    int count = store->in(MemNode::Address)->as_AddP()->unpack_offsets(elements, ARRAY_SIZE(elements));
    7.23 @@ -2552,6 +2553,12 @@
    7.24          conv = value;
    7.25          value = value->in(1);
    7.26        }
    7.27 +      if (value->Opcode() == Op_CastII &&
    7.28 +          value->as_CastII()->has_range_check()) {
    7.29 +        // Skip range check dependent CastII nodes
    7.30 +        cast = value;
    7.31 +        value = value->in(1);
    7.32 +      }
    7.33  #endif
    7.34        if (value != head->phi()) {
    7.35          msg = "unhandled shift in address";
    7.36 @@ -2564,9 +2571,16 @@
    7.37          }
    7.38        }
    7.39      } else if (n->Opcode() == Op_ConvI2L && conv == NULL) {
    7.40 -      if (n->in(1) == head->phi()) {
    7.41 +      conv = n;
    7.42 +      n = n->in(1);
    7.43 +      if (n->Opcode() == Op_CastII &&
    7.44 +          n->as_CastII()->has_range_check()) {
    7.45 +        // Skip range check dependent CastII nodes
    7.46 +        cast = n;
    7.47 +        n = n->in(1);
    7.48 +      }
    7.49 +      if (n == head->phi()) {
    7.50          found_index = true;
    7.51 -        conv = n;
    7.52        } else {
    7.53          msg = "unhandled input to ConvI2L";
    7.54        }
    7.55 @@ -2625,6 +2639,7 @@
    7.56    // Address elements are ok
    7.57    if (con)   ok.set(con->_idx);
    7.58    if (shift) ok.set(shift->_idx);
    7.59 +  if (cast)  ok.set(cast->_idx);
    7.60    if (conv)  ok.set(conv->_idx);
    7.61  
    7.62    for (uint i = 0; msg == NULL && i < lpt->_body.size(); i++) {
     8.1 --- a/src/share/vm/opto/loopopts.cpp	Mon Jan 25 08:46:19 2016 +0000
     8.2 +++ b/src/share/vm/opto/loopopts.cpp	Wed Jan 27 09:02:51 2016 +0100
     8.3 @@ -772,6 +772,9 @@
     8.4  #ifdef _LP64
     8.5          if (m->Opcode() == Op_ConvI2L)
     8.6            return false;
     8.7 +        if (m->is_CastII() && m->isa_CastII()->has_range_check()) {
     8.8 +          return false;
     8.9 +        }
    8.10  #endif
    8.11        }
    8.12      }
     9.1 --- a/src/share/vm/opto/node.cpp	Mon Jan 25 08:46:19 2016 +0000
     9.2 +++ b/src/share/vm/opto/node.cpp	Wed Jan 27 09:02:51 2016 +0100
     9.3 @@ -521,6 +521,11 @@
     9.4      C->add_macro_node(n);
     9.5    if (is_expensive())
     9.6      C->add_expensive_node(n);
     9.7 +  // If the cloned node is a range check dependent CastII, add it to the list.
     9.8 +  CastIINode* cast = n->isa_CastII();
     9.9 +  if (cast != NULL && cast->has_range_check()) {
    9.10 +    C->add_range_check_cast(cast);
    9.11 +  }
    9.12  
    9.13    n->set_idx(C->next_unique()); // Get new unique index as well
    9.14    debug_only( n->verify_construction() );
    9.15 @@ -649,6 +654,11 @@
    9.16    if (is_expensive()) {
    9.17      compile->remove_expensive_node(this);
    9.18    }
    9.19 +  CastIINode* cast = isa_CastII();
    9.20 +  if (cast != NULL && cast->has_range_check()) {
    9.21 +    compile->remove_range_check_cast(cast);
    9.22 +  }
    9.23 +
    9.24    if (is_SafePoint()) {
    9.25      as_SafePoint()->delete_replaced_nodes();
    9.26    }
    9.27 @@ -1344,6 +1354,10 @@
    9.28        if (dead->is_expensive()) {
    9.29          igvn->C->remove_expensive_node(dead);
    9.30        }
    9.31 +      CastIINode* cast = dead->isa_CastII();
    9.32 +      if (cast != NULL && cast->has_range_check()) {
    9.33 +        igvn->C->remove_range_check_cast(cast);
    9.34 +      }
    9.35        igvn->C->record_dead_node(dead->_idx);
    9.36        // Kill all inputs to the dead guy
    9.37        for (uint i=0; i < dead->req(); i++) {
    10.1 --- a/src/share/vm/opto/node.hpp	Mon Jan 25 08:46:19 2016 +0000
    10.2 +++ b/src/share/vm/opto/node.hpp	Wed Jan 27 09:02:51 2016 +0100
    10.3 @@ -54,6 +54,7 @@
    10.4  class CatchNode;
    10.5  class CatchProjNode;
    10.6  class CheckCastPPNode;
    10.7 +class CastIINode;
    10.8  class ClearArrayNode;
    10.9  class CmpNode;
   10.10  class CodeBuffer;
   10.11 @@ -603,6 +604,7 @@
   10.12      DEFINE_CLASS_ID(Type,  Node, 2)
   10.13        DEFINE_CLASS_ID(Phi,   Type, 0)
   10.14        DEFINE_CLASS_ID(ConstraintCast, Type, 1)
   10.15 +        DEFINE_CLASS_ID(CastII, ConstraintCast, 0)
   10.16        DEFINE_CLASS_ID(CheckCastPP, Type, 2)
   10.17        DEFINE_CLASS_ID(CMove, Type, 3)
   10.18        DEFINE_CLASS_ID(SafePointScalarObject, Type, 4)
   10.19 @@ -727,6 +729,7 @@
   10.20    DEFINE_CLASS_QUERY(Catch)
   10.21    DEFINE_CLASS_QUERY(CatchProj)
   10.22    DEFINE_CLASS_QUERY(CheckCastPP)
   10.23 +  DEFINE_CLASS_QUERY(CastII)
   10.24    DEFINE_CLASS_QUERY(ConstraintCast)
   10.25    DEFINE_CLASS_QUERY(ClearArray)
   10.26    DEFINE_CLASS_QUERY(CMove)
    11.1 --- a/src/share/vm/opto/parse2.cpp	Mon Jan 25 08:46:19 2016 +0000
    11.2 +++ b/src/share/vm/opto/parse2.cpp	Wed Jan 27 09:02:51 2016 +0100
    11.3 @@ -154,7 +154,9 @@
    11.4    // Check for always knowing you are throwing a range-check exception
    11.5    if (stopped())  return top();
    11.6  
    11.7 -  Node* ptr = array_element_address(ary, idx, type, sizetype);
    11.8 +  // Make array address computation control dependent to prevent it
    11.9 +  // from floating above the range check during loop optimizations.
   11.10 +  Node* ptr = array_element_address(ary, idx, type, sizetype, control());
   11.11  
   11.12    if (result2 != NULL)  *result2 = elemtype;
   11.13  
   11.14 @@ -457,9 +459,12 @@
   11.15  #ifdef _LP64
   11.16    // Clean the 32-bit int into a real 64-bit offset.
   11.17    // Otherwise, the jint value 0 might turn into an offset of 0x0800000000.
   11.18 -  const TypeLong* lkeytype = TypeLong::make(CONST64(0), num_cases-1, Type::WidenMin);
   11.19 -  key_val       = _gvn.transform( new (C) ConvI2LNode(key_val, lkeytype) );
   11.20 +  const TypeInt* ikeytype = TypeInt::make(0, num_cases-1, Type::WidenMin);
   11.21 +  // Make I2L conversion control dependent to prevent it from
   11.22 +  // floating above the range check during loop optimizations.
   11.23 +  key_val = C->constrained_convI2L(&_gvn, key_val, ikeytype, control());
   11.24  #endif
   11.25 +
   11.26    // Shift the value by wordsize so we have an index into the table, rather
   11.27    // than a switch value
   11.28    Node *shiftWord = _gvn.MakeConX(wordSize);
    12.1 --- a/src/share/vm/opto/phaseX.cpp	Mon Jan 25 08:46:19 2016 +0000
    12.2 +++ b/src/share/vm/opto/phaseX.cpp	Wed Jan 27 09:02:51 2016 +0100
    12.3 @@ -1339,6 +1339,10 @@
    12.4        if (dead->is_expensive()) {
    12.5          C->remove_expensive_node(dead);
    12.6        }
    12.7 +      CastIINode* cast = dead->isa_CastII();
    12.8 +      if (cast != NULL && cast->has_range_check()) {
    12.9 +        C->remove_range_check_cast(cast);
   12.10 +      }
   12.11      }
   12.12    } // while (_stack.is_nonempty())
   12.13  }
    13.1 --- a/src/share/vm/opto/superword.cpp	Mon Jan 25 08:46:19 2016 +0000
    13.2 +++ b/src/share/vm/opto/superword.cpp	Wed Jan 27 09:02:51 2016 +0100
    13.3 @@ -2388,6 +2388,11 @@
    13.4        return true;
    13.5      }
    13.6    } else if (opc == Op_ConvI2L) {
    13.7 +    if (n->in(1)->Opcode() == Op_CastII &&
    13.8 +        n->in(1)->as_CastII()->has_range_check()) {
    13.9 +      // Skip range check dependent CastII nodes
   13.10 +      n = n->in(1);
   13.11 +    }
   13.12      if (scaled_iv_plus_offset(n->in(1))) {
   13.13        return true;
   13.14      }
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/test/compiler/loopopts/TestLoopPeeling.java	Wed Jan 27 09:02:51 2016 +0100
    14.3 @@ -0,0 +1,100 @@
    14.4 +/*
    14.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    14.7 + *
    14.8 + * This code is free software; you can redistribute it and/or modify it
    14.9 + * under the terms of the GNU General Public License version 2 only, as
   14.10 + * published by the Free Software Foundation.
   14.11 + *
   14.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   14.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14.15 + * version 2 for more details (a copy is included in the LICENSE file that
   14.16 + * accompanied this code).
   14.17 + *
   14.18 + * You should have received a copy of the GNU General Public License version
   14.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   14.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   14.21 + *
   14.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   14.23 + * or visit www.oracle.com if you need additional information or have any
   14.24 + * questions.
   14.25 + */
   14.26 +
   14.27 +/*
   14.28 + * @test
   14.29 + * @bug 8078262
   14.30 + * @summary Tests correct dominator information after loop peeling.
   14.31 + * @run main/othervm -Xcomp -XX:CompileCommand=compileonly,TestLoopPeeling::test* TestLoopPeeling
   14.32 + */
   14.33 +public class TestLoopPeeling {
   14.34 +
   14.35 +    public int[] array = new int[100];
   14.36 +
   14.37 +    public static void main(String args[]) {
   14.38 +        TestLoopPeeling test = new TestLoopPeeling();
   14.39 +        try {
   14.40 +            test.testArrayAccess(0, 1);
   14.41 +            test.testArrayAllocation(0, 1);
   14.42 +        } catch (Exception e) {
   14.43 +            // Ignore exceptions
   14.44 +        }
   14.45 +    }
   14.46 +
   14.47 +    public void testArrayAccess(int index, int inc) {
   14.48 +        int storeIndex = -1;
   14.49 +
   14.50 +        for (; index < 10; index += inc) {
   14.51 +            // This loop invariant check triggers loop peeling because it can
   14.52 +            // be moved out of the loop (see 'IdealLoopTree::policy_peeling').
   14.53 +            if (inc == 42) return;
   14.54 +
   14.55 +            // This loop variant usage of LShiftL( ConvI2L( Phi(storeIndex) ) )
   14.56 +            // prevents the split if optimization that would otherwise clone the
   14.57 +            // LShiftL and ConvI2L nodes and assign them to their corresponding array
   14.58 +            // address computation (see 'PhaseIdealLoop::split_if_with_blocks_post').
   14.59 +            if (storeIndex > 0 && array[storeIndex] == 42) return;
   14.60 +
   14.61 +            if (index == 42) {
   14.62 +                // This store and the corresponding range check are moved out of the
   14.63 +                // loop and both used after old loop and the peeled iteration exit.
   14.64 +                // For the peeled iteration, storeIndex is always -1 and the ConvI2L
   14.65 +                // is replaced by TOP. However, the range check is not folded because
   14.66 +                // we don't do the split if optimization in PhaseIdealLoop2.
   14.67 +                // As a result, we have a (dead) control path from the peeled iteration
   14.68 +                // to the StoreI but the data path is removed.
   14.69 +                array[storeIndex] = 1;
   14.70 +                return;
   14.71 +            }
   14.72 +
   14.73 +            storeIndex++;
   14.74 +        }
   14.75 +    }
   14.76 +
   14.77 +    public byte[] testArrayAllocation(int index, int inc) {
   14.78 +        int allocationCount = -1;
   14.79 +        byte[] result;
   14.80 +
   14.81 +        for (; index < 10; index += inc) {
   14.82 +            // This loop invariant check triggers loop peeling because it can
   14.83 +            // be moved out of the loop (see 'IdealLoopTree::policy_peeling').
   14.84 +            if (inc == 42) return null;
   14.85 +
   14.86 +            if (index == 42) {
   14.87 +                // This allocation and the corresponding size check are moved out of the
   14.88 +                // loop and both used after old loop and the peeled iteration exit.
   14.89 +                // For the peeled iteration, allocationCount is always -1 and the ConvI2L
   14.90 +                // is replaced by TOP. However, the size check is not folded because
   14.91 +                // we don't do the split if optimization in PhaseIdealLoop2.
   14.92 +                // As a result, we have a (dead) control path from the peeled iteration
   14.93 +                // to the allocation but the data path is removed.
   14.94 +                result = new byte[allocationCount];
   14.95 +                return result;
   14.96 +            }
   14.97 +
   14.98 +            allocationCount++;
   14.99 +        }
  14.100 +        return null;
  14.101 +    }
  14.102 +}
  14.103 +

mercurial