8142314: Bug in C1 ControlFlowOptimizer::delete_unnecessary_jumps with bytecode profiling
Reviewed-by: kvn
Contributed-by: gunter.haug@sap.com
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp Wed Nov 11 01:27:36 2015 +0300
+++ b/hotspot/src/share/vm/c1/c1_LIR.cpp Tue Nov 10 11:01:28 2015 +0100
@@ -2004,7 +2004,7 @@
// LIR_Op2
void LIR_Op2::print_instr(outputStream* out) const {
- if (code() == lir_cmove) {
+ if (code() == lir_cmove || code() == lir_cmp) {
print_condition(out, condition()); out->print(" ");
}
in_opr1()->print(out); out->print(" ");
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp Wed Nov 11 01:27:36 2015 +0300
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp Tue Nov 10 11:01:28 2015 +0100
@@ -6233,9 +6233,19 @@
if (prev_branch->stub() == NULL) {
LIR_Op2* prev_cmp = NULL;
+ // There might be a cmove inserted for profiling which depends on the same
+ // compare. If we change the condition of the respective compare, we have
+ // to take care of this cmove as well.
+ LIR_Op2* prev_cmove = NULL;
for(int j = instructions->length() - 3; j >= 0 && prev_cmp == NULL; j--) {
prev_op = instructions->at(j);
+ // check for the cmove
+ if (prev_op->code() == lir_cmove) {
+ assert(prev_op->as_Op2() != NULL, "cmove must be of type LIR_Op2");
+ prev_cmove = (LIR_Op2*)prev_op;
+ assert(prev_branch->cond() == prev_cmove->condition(), "should be the same");
+ }
if (prev_op->code() == lir_cmp) {
assert(prev_op->as_Op2() != NULL, "branch must be of type LIR_Op2");
prev_cmp = (LIR_Op2*)prev_op;
@@ -6252,6 +6262,13 @@
prev_branch->negate_cond();
prev_cmp->set_condition(prev_branch->cond());
instructions->truncate(instructions->length() - 1);
+ // if we do change the condition, we have to change the cmove as well
+ if (prev_cmove != NULL) {
+ prev_cmove->set_condition(prev_branch->cond());
+ LIR_Opr t = prev_cmove->in_opr1();
+ prev_cmove->set_in_opr1(prev_cmove->in_opr2());
+ prev_cmove->set_in_opr2(t);
+ }
}
}
}