# HG changeset patch # User kvn # Date 1417550921 28800 # Node ID dc763d49b82ddebee82d03af4c5128772d7cf204 # Parent 0b86bdf28e072715e759ec29127b295dee30fbd0 8065618: C2 RA incorrectly removes kill projections Summary: Don't remove KILL projections if their "defining" nodes have SCMemProj projection (memory side effects). Reviewed-by: iveresov, roland diff -r 0b86bdf28e07 -r dc763d49b82d src/share/vm/opto/ifg.cpp --- a/src/share/vm/opto/ifg.cpp Tue Dec 02 18:09:39 2014 +0000 +++ b/src/share/vm/opto/ifg.cpp Tue Dec 02 12:08:41 2014 -0800 @@ -541,6 +541,22 @@ if( !n->is_Proj() || // Could also be a flags-projection of a dead ADD or such. (_lrg_map.live_range_id(def) && !liveout.member(_lrg_map.live_range_id(def)))) { + if (n->is_MachProj()) { + // Don't remove KILL projections if their "defining" nodes have + // memory effects (have SCMemProj projection node) - + // they are not dead even when their result is not used. + // For example, compareAndSwapL (and other CAS) and EncodeISOArray nodes. + // The method add_input_to_liveout() keeps such nodes alive (put them on liveout list) + // when it sees SCMemProj node in a block. Unfortunately SCMemProj node could be placed + // in block in such order that KILL MachProj nodes are processed first. + uint cnt = def->outcnt(); + for (uint i = 0; i < cnt; i++) { + Node* proj = def->raw_out(i); + if (proj->Opcode() == Op_SCMemProj) { + return false; + } + } + } block->remove_node(j - 1); if (lrgs(r)._def == n) { lrgs(r)._def = 0;