1.1 --- a/src/share/vm/opto/mulnode.cpp Mon Mar 09 13:34:00 2009 -0700 1.2 +++ b/src/share/vm/opto/mulnode.cpp Thu Mar 12 18:16:36 2009 -0700 1.3 @@ -486,20 +486,23 @@ 1.4 return new (phase->C, 3) AndINode(ldus, phase->intcon(mask&0xFFFF)); 1.5 } 1.6 1.7 - // Masking sign bits off of a Byte? Let the matcher use an unsigned load 1.8 - if( lop == Op_LoadB && 1.9 - (!in(0) && load->in(0)) && 1.10 - (mask == 0x000000FF) ) { 1.11 - // Associate this node with the LoadB, so the matcher can see them together. 1.12 - // If we don't do this, it is common for the LoadB to have one control 1.13 - // edge, and the store or call containing this AndI to have a different 1.14 - // control edge. This will cause Label_Root to group the AndI with 1.15 - // the encoding store or call, so the matcher has no chance to match 1.16 - // this AndI together with the LoadB. Setting the control edge here 1.17 - // prevents Label_Root from grouping the AndI with the store or call, 1.18 - // if it has a control edge that is inconsistent with the LoadB. 1.19 - set_req(0, load->in(0)); 1.20 - return this; 1.21 + // Masking sign bits off of a Byte? Do an unsigned byte load. 1.22 + if (lop == Op_LoadB && mask == 0x000000FF) { 1.23 + return new (phase->C, 3) LoadUBNode(load->in(MemNode::Control), 1.24 + load->in(MemNode::Memory), 1.25 + load->in(MemNode::Address), 1.26 + load->adr_type()); 1.27 + } 1.28 + 1.29 + // Masking sign bits off of a Byte plus additional lower bits? Do 1.30 + // an unsigned byte load plus an and. 1.31 + if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) { 1.32 + Node* ldub = new (phase->C, 3) LoadUBNode(load->in(MemNode::Control), 1.33 + load->in(MemNode::Memory), 1.34 + load->in(MemNode::Address), 1.35 + load->adr_type()); 1.36 + ldub = phase->transform(ldub); 1.37 + return new (phase->C, 3) AndINode(ldub, phase->intcon(mask)); 1.38 } 1.39 1.40 // Masking off sign bits? Dont make them! 1.41 @@ -599,12 +602,21 @@ 1.42 if( !t2 || !t2->is_con() ) return MulNode::Ideal(phase, can_reshape); 1.43 const jlong mask = t2->get_con(); 1.44 1.45 - Node *rsh = in(1); 1.46 - uint rop = rsh->Opcode(); 1.47 + Node* in1 = in(1); 1.48 + uint op = in1->Opcode(); 1.49 + 1.50 + // Masking sign bits off of an integer? Do an unsigned integer to long load. 1.51 + if (op == Op_ConvI2L && in1->in(1)->Opcode() == Op_LoadI && mask == 0x00000000FFFFFFFFL) { 1.52 + Node* load = in1->in(1); 1.53 + return new (phase->C, 3) LoadUI2LNode(load->in(MemNode::Control), 1.54 + load->in(MemNode::Memory), 1.55 + load->in(MemNode::Address), 1.56 + load->adr_type()); 1.57 + } 1.58 1.59 // Masking off sign bits? Dont make them! 1.60 - if( rop == Op_RShiftL ) { 1.61 - const TypeInt *t12 = phase->type(rsh->in(2))->isa_int(); 1.62 + if (op == Op_RShiftL) { 1.63 + const TypeInt *t12 = phase->type(in1->in(2))->isa_int(); 1.64 if( t12 && t12->is_con() ) { // Shift is by a constant 1.65 int shift = t12->get_con(); 1.66 shift &= BitsPerJavaLong - 1; // semantics of Java shifts 1.67 @@ -613,7 +625,7 @@ 1.68 // bits survive. NO sign-extension bits survive the maskings. 1.69 if( (sign_bits_mask & mask) == 0 ) { 1.70 // Use zero-fill shift instead 1.71 - Node *zshift = phase->transform(new (phase->C, 3) URShiftLNode(rsh->in(1),rsh->in(2))); 1.72 + Node *zshift = phase->transform(new (phase->C, 3) URShiftLNode(in1->in(1), in1->in(2))); 1.73 return new (phase->C, 3) AndLNode( zshift, in(2) ); 1.74 } 1.75 }