diff src/share/vm/opto/reg_split.cpp @ 295:ea18057223c4

6732194: Data corruption dependent on -server/-client/-Xbatch Summary: rematerializing nodes results in incorrect inputs Reviewed-by: rasbold
author never
date Mon, 18 Aug 2008 23:17:51 -0700
parents a61af66fc99e
children 1c6e3bfb543a
line wrap: on
line diff
--- a/src/share/vm/opto/reg_split.cpp	Thu Aug 14 10:15:29 2008 -0700
+++ b/src/share/vm/opto/reg_split.cpp	Mon Aug 18 23:17:51 2008 -0700
@@ -284,7 +284,7 @@
       // Check for single-def (LRG cannot redefined)
       uint lidx = n2lidx(in);
       if( lidx >= _maxlrg ) continue; // Value is a recent spill-copy
-      if( lrgs(lidx)._def != NodeSentinel ) continue;
+      if (lrgs(lidx).is_singledef()) continue;
 
       Block *b_def = _cfg._bbs[def->_idx];
       int idx_def = b_def->find_node(def);
@@ -311,12 +311,20 @@
       uint lidx = Find_id(in);
 
       // Walk backwards thru spill copy node intermediates
-      if( walkThru )
+      if (walkThru) {
         while ( in->is_SpillCopy() && lidx >= _maxlrg ) {
           in = in->in(1);
           lidx = Find_id(in);
         }
 
+        if (lidx < _maxlrg && lrgs(lidx).is_multidef()) {
+          // walkThru found a multidef LRG, which is unsafe to use, so
+          // just keep the original def used in the clone.
+          in = spill->in(i);
+          lidx = Find_id(in);
+        }
+      }
+
       if( lidx < _maxlrg && lrgs(lidx).reg() >= LRG::SPILL_REG ) {
         Node *rdef = Reachblock[lrg2reach[lidx]];
         if( rdef ) spill->set_req(i,rdef);
@@ -505,7 +513,7 @@
       // Do not bother splitting or putting in Phis for single-def
       // rematerialized live ranges.  This happens alot to constants
       // with long live ranges.
-      if( lrgs(lidx)._def != NodeSentinel &&
+      if( lrgs(lidx).is_singledef() &&
           lrgs(lidx)._def->rematerialize() ) {
         // reset the Reaches & UP entries
         Reachblock[slidx] = lrgs(lidx)._def;