src/share/vm/opto/loopTransform.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
hotspot Cdiff src/share/vm/opto/loopTransform.cpp
src/share/vm/opto/loopTransform.cpp
Print this page
rev 7345 : 8054478: C2: Incorrectly compiled char[] array access crashes JVM
Summary: propagate node replacements along control flow edges to callers
Reviewed-by: dead backbranch in main loop results in erroneous array access
rev 7347 : reviews
*** 25,34 ****
--- 25,35 ----
#include "precompiled.hpp"
#include "compiler/compileLog.hpp"
#include "memory/allocation.inline.hpp"
#include "opto/addnode.hpp"
#include "opto/callnode.hpp"
+ #include "opto/castnode.hpp"
#include "opto/connode.hpp"
#include "opto/convertnode.hpp"
#include "opto/divnode.hpp"
#include "opto/loopnode.hpp"
#include "opto/mulnode.hpp"
*** 883,892 ****
--- 884,907 ----
set_ctrl( n, find_non_split_ctrl(back_ctrl->in(0)) );
}
return n;
}
+ bool PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop) {
+ Node* castii = new CastIINode(incr, TypeInt::INT, true);
+ castii->set_req(0, ctrl);
+ register_new_node(castii, ctrl);
+ for (DUIterator_Fast imax, i = incr->fast_outs(imax); i < imax; i++) {
+ Node* n = incr->fast_out(i);
+ if (n->is_Phi() && n->in(0) == loop) {
+ int nrep = n->replace_edge(incr, castii);
+ return true;
+ }
+ }
+ return false;
+ }
+
//------------------------------insert_pre_post_loops--------------------------
// Insert pre and post loops. If peel_only is set, the pre-loop can not have
// more iterations added. It acts as a 'peel' only, no lower-bound RCE, no
// alignment. Useful to unroll loops that do no array accesses.
void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_new, bool peel_only ) {
*** 1079,1088 ****
--- 1094,1121 ----
_igvn.hash_delete(main_phi);
main_phi->set_req( LoopNode::EntryControl, fallpre );
}
}
+ // Nodes inside the loop may be control dependent on a predicate
+ // that was moved before the preloop. If the back branch of the main
+ // or post loops becomes dead, those nodes won't be dependent on the
+ // test that guards that loop nest anymore which could lead to an
+ // incorrect array access because it executes independently of the
+ // test that was guarding the loop nest. We add a special CastII on
+ // the if branch that enters the loop, between the input induction
+ // variable value and the induction variable Phi to preserve correct
+ // dependencies.
+
+ // CastII for the post loop:
+ bool inserted = cast_incr_before_loop(zer_opaq->in(1), zer_taken, post_head);
+ assert(inserted, "no castII inserted");
+
+ // CastII for the main loop:
+ inserted = cast_incr_before_loop(pre_incr, min_taken, main_head);
+ assert(inserted, "no castII inserted");
+
// Step B4: Shorten the pre-loop to run only 1 iteration (for now).
// RCE and alignment may change this later.
Node *cmp_end = pre_end->cmp_node();
assert( cmp_end->in(2) == limit, "" );
Node *pre_limit = new AddINode( init, stride );
src/share/vm/opto/loopTransform.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File