# HG changeset patch # User kvn # Date 1204745611 28800 # Node ID 73970d8c0b275f8b24db8f9966db56404bb70ea5 # Parent f34d9da7acb2ea35558b7b9b45075cee21e96556 6671250: In Parse::do_if() old Cmp node 'c' should be replaced with new one after BoolNode transformation Summary: In Parse::do_if() 'c' (CmpNode) node may be changed during BoolNode transformation so 'c' may became dead but the node is referenced later in the code. Reviewed-by: never diff -r f34d9da7acb2 -r 73970d8c0b27 src/share/vm/opto/parse2.cpp --- a/src/share/vm/opto/parse2.cpp Fri Feb 29 19:57:41 2008 -0800 +++ b/src/share/vm/opto/parse2.cpp Wed Mar 05 11:33:31 2008 -0800 @@ -1022,10 +1022,27 @@ Node* tst = _gvn.transform(tst0); BoolTest::mask taken_btest = BoolTest::illegal; BoolTest::mask untaken_btest = BoolTest::illegal; - if (btest == BoolTest::ne) { - // For now, these are the only cases of btest that matter. (More later.) - taken_btest = taken_if_true ? btest : BoolTest::eq; - untaken_btest = taken_if_true ? BoolTest::eq : btest; + + if (tst->is_Bool()) { + // Refresh c from the transformed bool node, since it may be + // simpler than the original c. Also re-canonicalize btest. + // This wins when (Bool ne (Conv2B p) 0) => (Bool ne (CmpP p NULL)). + // That can arise from statements like: if (x instanceof C) ... + if (tst != tst0) { + // Canonicalize one more time since transform can change it. + btest = tst->as_Bool()->_test._test; + if (!BoolTest(btest).is_canonical()) { + // Reverse edges one more time... + tst = _gvn.transform( tst->as_Bool()->negate(&_gvn) ); + btest = tst->as_Bool()->_test._test; + assert(BoolTest(btest).is_canonical(), "sanity"); + taken_if_true = !taken_if_true; + } + c = tst->in(1); + } + BoolTest::mask neg_btest = BoolTest(btest).negate(); + taken_btest = taken_if_true ? btest : neg_btest; + untaken_btest = taken_if_true ? neg_btest : btest; } // Generate real control flow