src/share/vm/opto/subnode.cpp
Print this page
@@ -1205,10 +1205,44 @@
phase->type( cmp1->in(2) )->higher_equal(TypeInt::SYMINT) ) {
Node *ncmp = phase->transform( new (phase->C) CmpINode(cmp1->in(2),cmp2));
return new (phase->C) BoolNode( ncmp, _test.commute() );
}
+ // Change ((x & m) <= m) into (m >= 0)
+ // Integer expressions which perform bitwise and can be proven to
+ // be less than or equal to either operand, as long as the compared
+ // operand is non-negative.
+ if ( cop == Op_CmpI &&
+ _test._test == BoolTest::le &&
+ cmp1->Opcode() == Op_AndI &&
+ cmp1->in(2) == cmp2) {
+ Node* ncmp = phase->transform( new (phase->C) CmpINode(cmp2, phase->intcon(0)));
+ return new (phase->C) BoolNode(ncmp, BoolTest::ge);
+ }
+
+ // Change ((x & m) u<= m) to always true
+ if ( cop == Op_CmpU &&
+ _test._test == BoolTest::le &&
+ cmp1->Opcode() == Op_AndI &&
+ cmp1->in(2) == cmp2) {
+ return ConINode::make(phase->C, 1);
+ }
+
+ // Change ((x & m - 1) < m) or ((x & m - 1) u< m) into (m > 0)
+ // This is the off-by-one variant of the two patterns above
+ if ((cop == Op_CmpU || cop == Op_CmpI) &&
+ _test._test == BoolTest::lt &&
+ cmp1->Opcode() == Op_AndI &&
+ (cmp1->in(2)->Opcode() == Op_AddI && cmp1->in(2)->in(2)->find_int_con(0) == -1 ||
+ cmp1->in(2)->Opcode() == Op_SubI && cmp1->in(2)->in(2)->find_int_con(0) == 1) &&
+ cmp1->in(2)->in(1) == cmp2) {
+ Node* ncmp = phase->transform( new (phase->C) CmpINode(cmp2, phase->intcon(0)));
+ return cmp2->Opcode() == Op_LoadRange
+ ? new (phase->C) BoolNode(ncmp, BoolTest::ne) // arraylength known to be non-negative
+ : new (phase->C) BoolNode(ncmp, BoolTest::gt);
+ }
+
// The transformation below is not valid for either signed or unsigned
// comparisons due to wraparound concerns at MAX_VALUE and MIN_VALUE.
// This transformation can be resurrected when we are able to
// make inferences about the range of values being subtracted from
// (or added to) relative to the wraparound point.