Wed, 05 Mar 2008 11:33:31 -0800
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
src/share/vm/opto/parse2.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/opto/parse2.cpp Fri Feb 29 19:57:41 2008 -0800 1.2 +++ b/src/share/vm/opto/parse2.cpp Wed Mar 05 11:33:31 2008 -0800 1.3 @@ -1022,10 +1022,27 @@ 1.4 Node* tst = _gvn.transform(tst0); 1.5 BoolTest::mask taken_btest = BoolTest::illegal; 1.6 BoolTest::mask untaken_btest = BoolTest::illegal; 1.7 - if (btest == BoolTest::ne) { 1.8 - // For now, these are the only cases of btest that matter. (More later.) 1.9 - taken_btest = taken_if_true ? btest : BoolTest::eq; 1.10 - untaken_btest = taken_if_true ? BoolTest::eq : btest; 1.11 + 1.12 + if (tst->is_Bool()) { 1.13 + // Refresh c from the transformed bool node, since it may be 1.14 + // simpler than the original c. Also re-canonicalize btest. 1.15 + // This wins when (Bool ne (Conv2B p) 0) => (Bool ne (CmpP p NULL)). 1.16 + // That can arise from statements like: if (x instanceof C) ... 1.17 + if (tst != tst0) { 1.18 + // Canonicalize one more time since transform can change it. 1.19 + btest = tst->as_Bool()->_test._test; 1.20 + if (!BoolTest(btest).is_canonical()) { 1.21 + // Reverse edges one more time... 1.22 + tst = _gvn.transform( tst->as_Bool()->negate(&_gvn) ); 1.23 + btest = tst->as_Bool()->_test._test; 1.24 + assert(BoolTest(btest).is_canonical(), "sanity"); 1.25 + taken_if_true = !taken_if_true; 1.26 + } 1.27 + c = tst->in(1); 1.28 + } 1.29 + BoolTest::mask neg_btest = BoolTest(btest).negate(); 1.30 + taken_btest = taken_if_true ? btest : neg_btest; 1.31 + untaken_btest = taken_if_true ? neg_btest : btest; 1.32 } 1.33 1.34 // Generate real control flow