Fri, 29 Jan 2010 22:51:41 -0800
6916644: C2 compiler crash on x86
Reviewed-by: kvn, twisti
1.1 --- a/src/share/vm/adlc/output_c.cpp Fri Jan 29 09:27:22 2010 -0800 1.2 +++ b/src/share/vm/adlc/output_c.cpp Fri Jan 29 22:51:41 2010 -0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * Copyright 1998-2010 Sun Microsystems, Inc. All Rights Reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -1496,7 +1496,7 @@ 1.11 unsigned i; 1.12 1.13 // Generate Expand function header 1.14 - fprintf(fp,"MachNode *%sNode::Expand(State *state, Node_List &proj_list) {\n", node->_ident); 1.15 + fprintf(fp,"MachNode *%sNode::Expand(State *state, Node_List &proj_list, Node* mem) {\n", node->_ident); 1.16 fprintf(fp,"Compile* C = Compile::current();\n"); 1.17 // Generate expand code 1.18 if( node->expands() ) { 1.19 @@ -1546,15 +1546,16 @@ 1.20 // Build a mapping from operand index to input edges 1.21 fprintf(fp," unsigned idx0 = oper_input_base();\n"); 1.22 1.23 - // The order in which inputs are added to a node is very 1.24 + // The order in which the memory input is added to a node is very 1.25 // strange. Store nodes get a memory input before Expand is 1.26 - // called and all other nodes get it afterwards so 1.27 - // oper_input_base is wrong during expansion. This code adjusts 1.28 - // is so that expansion will work correctly. 1.29 - bool missing_memory_edge = node->_matrule->needs_ideal_memory_edge(_globalNames) && 1.30 - node->is_ideal_store() == Form::none; 1.31 - if (missing_memory_edge) { 1.32 - fprintf(fp," idx0--; // Adjust base because memory edge hasn't been inserted yet\n"); 1.33 + // called and other nodes get it afterwards or before depending on 1.34 + // match order so oper_input_base is wrong during expansion. This 1.35 + // code adjusts it so that expansion will work correctly. 1.36 + int has_memory_edge = node->_matrule->needs_ideal_memory_edge(_globalNames); 1.37 + if (has_memory_edge) { 1.38 + fprintf(fp," if (mem == (Node*)1) {\n"); 1.39 + fprintf(fp," idx0--; // Adjust base because memory edge hasn't been inserted yet\n"); 1.40 + fprintf(fp," }\n"); 1.41 } 1.42 1.43 for( i = 0; i < node->num_opnds(); i++ ) { 1.44 @@ -1611,9 +1612,11 @@ 1.45 int node_mem_op = node->memory_operand(_globalNames); 1.46 assert( node_mem_op != InstructForm::NO_MEMORY_OPERAND, 1.47 "expand rule member needs memory but top-level inst doesn't have any" ); 1.48 - if (!missing_memory_edge) { 1.49 + if (has_memory_edge) { 1.50 // Copy memory edge 1.51 - fprintf(fp," n%d->add_req(_in[1]);\t// Add memory edge\n", cnt); 1.52 + fprintf(fp," if (mem != (Node*)1) {\n"); 1.53 + fprintf(fp," n%d->add_req(_in[1]);\t// Add memory edge\n", cnt); 1.54 + fprintf(fp," }\n"); 1.55 } 1.56 } 1.57 1.58 @@ -1689,7 +1692,7 @@ 1.59 } // done iterating over a new instruction's operands 1.60 1.61 // Invoke Expand() for the newly created instruction. 1.62 - fprintf(fp," result = n%d->Expand( state, proj_list );\n", cnt); 1.63 + fprintf(fp," result = n%d->Expand( state, proj_list, mem );\n", cnt); 1.64 assert( !new_inst->expands(), "Do not have complete support for recursive expansion"); 1.65 } // done iterating over new instructions 1.66 fprintf(fp,"\n");
2.1 --- a/src/share/vm/adlc/output_h.cpp Fri Jan 29 09:27:22 2010 -0800 2.2 +++ b/src/share/vm/adlc/output_h.cpp Fri Jan 29 22:51:41 2010 -0800 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved. 2.6 + * Copyright 1998-2010 Sun Microsystems, Inc. All Rights Reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -1754,7 +1754,7 @@ 2.11 instr->has_temps() || 2.12 instr->_matrule != NULL && 2.13 instr->num_opnds() != instr->num_unique_opnds() ) { 2.14 - fprintf(fp," virtual MachNode *Expand(State *state, Node_List &proj_list);\n"); 2.15 + fprintf(fp," virtual MachNode *Expand(State *state, Node_List &proj_list, Node* mem);\n"); 2.16 } 2.17 2.18 if (instr->is_pinned(_globalNames)) {
3.1 --- a/src/share/vm/opto/machnode.hpp Fri Jan 29 09:27:22 2010 -0800 3.2 +++ b/src/share/vm/opto/machnode.hpp Fri Jan 29 22:51:41 2010 -0800 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. 3.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -232,7 +232,7 @@ 3.11 // Expand method for MachNode, replaces nodes representing pseudo 3.12 // instructions with a set of nodes which represent real machine 3.13 // instructions and compute the same value. 3.14 - virtual MachNode *Expand( State *, Node_List &proj_list ) { return this; } 3.15 + virtual MachNode *Expand( State *, Node_List &proj_list, Node* mem ) { return this; } 3.16 3.17 // Bottom_type call; value comes from operand0 3.18 virtual const class Type *bottom_type() const { return _opnds[0]->type(); }
4.1 --- a/src/share/vm/opto/matcher.cpp Fri Jan 29 09:27:22 2010 -0800 4.2 +++ b/src/share/vm/opto/matcher.cpp Fri Jan 29 22:51:41 2010 -0800 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 4.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -1580,7 +1580,7 @@ 4.11 uint num_proj = _proj_list.size(); 4.12 4.13 // Perform any 1-to-many expansions required 4.14 - MachNode *ex = mach->Expand(s,_proj_list); 4.15 + MachNode *ex = mach->Expand(s,_proj_list, mem); 4.16 if( ex != mach ) { 4.17 assert(ex->ideal_reg() == mach->ideal_reg(), "ideal types should match"); 4.18 if( ex->in(1)->is_Con() )
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/compiler/6916644/Test6916644.java Fri Jan 29 22:51:41 2010 -0800 5.3 @@ -0,0 +1,50 @@ 5.4 +/* 5.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.7 + * 5.8 + * This code is free software; you can redistribute it and/or modify it 5.9 + * under the terms of the GNU General Public License version 2 only, as 5.10 + * published by the Free Software Foundation. 5.11 + * 5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.15 + * version 2 for more details (a copy is included in the LICENSE file that 5.16 + * accompanied this code). 5.17 + * 5.18 + * You should have received a copy of the GNU General Public License version 5.19 + * 2 along with this work; if not, write to the Free Software Foundation, 5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.21 + * 5.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 5.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 5.24 + * have any questions. 5.25 + * 5.26 + */ 5.27 + 5.28 +/** 5.29 + * @test 5.30 + * @bug 6916644 5.31 + * @summary C2 compiler crash on x86 5.32 + * 5.33 + * @run main/othervm -Xcomp -XX:CompileOnly=Test6916644.test Test6916644 5.34 + */ 5.35 + 5.36 +public class Test6916644 { 5.37 + static int result; 5.38 + static int i1; 5.39 + static int i2; 5.40 + 5.41 + static public void test(double d) { 5.42 + result = (d <= 0.0D) ? i1 : i2; 5.43 + } 5.44 + 5.45 + public static void main(String[] args) { 5.46 + for (int i = 0; i < 100000; i++) { 5.47 + // use an alternating value so the test doesn't always go 5.48 + // the same direction. Otherwise we won't transform it 5.49 + // into a cmove. 5.50 + test(i & 1); 5.51 + } 5.52 + } 5.53 +}