@@ -504,6 +504,102 @@ Node* unsigned_div_ideal(PhaseGVN* phase, bool can_reshape, Node* div) {
504504 return nullptr ;
505505}
506506
507+ template <typename IntegerType>
508+ static const IntegerType* compute_signed_div_type (const IntegerType* i1, const IntegerType* i2) {
509+ typedef typename IntegerType::NativeType NativeType;
510+ assert (!i2->is_con () || i2->get_con () != 0 , " Can't handle zero constant divisor" );
511+ int widen = MAX2 (i1->_widen , i2->_widen );
512+
513+ // Case A: divisor range spans zero (i2->_lo < 0 < i2->_hi)
514+ // We split into two subproblems to avoid division by 0:
515+ // - negative part: [i2->_lo, −1]
516+ // - positive part: [1, i2->_hi]
517+ // Then we union the results by taking the min of all lower‐bounds and
518+ // the max of all upper‐bounds from the two halves.
519+ if (i2->_lo < 0 && i2->_hi > 0 ) {
520+ // Handle negative part of the divisor range
521+ const IntegerType* neg_part = compute_signed_div_type (i1, IntegerType::make (i2->_lo , -1 , widen));
522+ // Handle positive part of the divisor range
523+ const IntegerType* pos_part = compute_signed_div_type (i1, IntegerType::make (1 , i2->_hi , widen));
524+ // Merge results
525+ NativeType new_lo = MIN2 (neg_part->_lo , pos_part->_lo );
526+ NativeType new_hi = MAX2 (neg_part->_hi , pos_part->_hi );
527+ assert (new_hi >= new_lo, " sanity" );
528+ return IntegerType::make (new_lo, new_hi, widen);
529+ }
530+
531+ // Case B: divisor range does NOT span zero.
532+ // Here i2 is entirely negative or entirely positive.
533+ // Then i1/i2 is monotonic in i1 and i2 (when i2 keeps the same sign).
534+ // Therefore the extrema occur at the four “corners”:
535+ // (i1->_lo, i2->_hi), (i1->_lo, i2->_lo), (i1->_hi, i2->_lo), (i1->_hi, i2->_hi).
536+ // We compute all four and take the min and max.
537+ // A special case handles overflow when dividing the most‐negative value by −1.
538+
539+ // adjust i2 bounds to not include zero, as zero always throws
540+ NativeType i2_lo = i2->_lo == 0 ? 1 : i2->_lo ;
541+ NativeType i2_hi = i2->_hi == 0 ? -1 : i2->_hi ;
542+ constexpr NativeType min_val = std::numeric_limits<NativeType>::min ();
543+ static_assert (min_val == min_jint || min_val == min_jlong, " min has to be either min_jint or min_jlong" );
544+ constexpr NativeType max_val = std::numeric_limits<NativeType>::max ();
545+ static_assert (max_val == max_jint || max_val == max_jlong, " max has to be either max_jint or max_jlong" );
546+
547+ // Special overflow case: min_val / (-1) == min_val (cf. JVMS§6.5 idiv/ldiv)
548+ // We need to be careful that we never run min_val / (-1) in C++ code, as this overflow is UB there
549+ if (i1->_lo == min_val && i2_hi == -1 ) {
550+ NativeType new_lo = min_val;
551+ NativeType new_hi;
552+ // compute new_hi depending on whether divisor or dividend is non-constant.
553+ // i2 is purely in the negative domain here (as i2_hi is -1)
554+ // which means the maximum value this division can yield is either
555+ if (!i1->is_con ()) {
556+ // a) non-constant dividend: i1 could be min_val + 1.
557+ // -> i1 / i2 = (min_val + 1) / -1 = max_val is possible.
558+ new_hi = max_val;
559+ assert ((min_val + 1 ) / -1 == new_hi, " new_hi should be max_val" );
560+ } else if (i2_lo != i2_hi) {
561+ // b) i1 is constant min_val, i2 is non-constant.
562+ // if i2 = -1 -> i1 / i2 = min_val / -1 = min_val
563+ // if i2 < -1 -> i1 / i2 <= min_val / -2 = (max_val / 2) + 1
564+ new_hi = (max_val / 2 ) + 1 ;
565+ assert (min_val / -2 == new_hi, " new_hi should be (max_val / 2) + 1)" );
566+ } else {
567+ // c) i1 is constant min_val, i2 is constant -1.
568+ // -> i1 / i2 = min_val / -1 = min_val
569+ new_hi = min_val;
570+ }
571+
572+ #ifdef ASSERT
573+ // validate new_hi for non-constant divisor
574+ if (i2_lo != i2_hi) {
575+ assert (i2_lo != -1 , " Special case not possible here, as i2_lo has to be < i2_hi" );
576+ NativeType result = i1->_lo / i2_lo;
577+ assert (new_hi >= result, " computed wrong value for new_hi" );
578+ }
579+
580+ // validate new_hi for non-constant dividend
581+ if (!i1->is_con ()) {
582+ assert (i2_hi > min_val, " Special case not possible here, as i1->_hi has to be > min" );
583+ NativeType result1 = i1->_hi / i2_lo;
584+ NativeType result2 = i1->_hi / i2_hi;
585+ assert (new_hi >= result1 && new_hi >= result2, " computed wrong value for new_hi" );
586+ }
587+ #endif
588+
589+ return IntegerType::make (new_lo, new_hi, widen);
590+ }
591+ assert ((i1->_lo != min_val && i1->_hi != min_val) || (i2_hi != -1 && i2_lo != -1 ), " should have filtered out before" );
592+
593+ // Special case not possible here, calculate all corners normally
594+ NativeType corner1 = i1->_lo / i2_lo;
595+ NativeType corner2 = i1->_lo / i2_hi;
596+ NativeType corner3 = i1->_hi / i2_lo;
597+ NativeType corner4 = i1->_hi / i2_hi;
598+
599+ NativeType new_lo = MIN4 (corner1, corner2, corner3, corner4);
600+ NativeType new_hi = MAX4 (corner1, corner2, corner3, corner4);
601+ return IntegerType::make (new_lo, new_hi, widen);
602+ }
507603
508604// =============================================================================
509605// ------------------------------Identity---------------------------------------
@@ -549,65 +645,26 @@ Node *DivINode::Ideal(PhaseGVN *phase, bool can_reshape) {
549645// prevent hoisting the divide above an unsafe test.
550646const Type* DivINode::Value (PhaseGVN* phase) const {
551647 // Either input is TOP ==> the result is TOP
552- const Type *t1 = phase->type ( in (1 ) );
553- const Type *t2 = phase->type ( in (2 ) );
554- if ( t1 == Type::TOP ) return Type::TOP;
555- if ( t2 == Type::TOP ) return Type::TOP;
648+ const Type* t1 = phase->type (in (1 ));
649+ const Type* t2 = phase->type (in (2 ));
650+ if (t1 == Type::TOP || t2 == Type::TOP) {
651+ return Type::TOP;
652+ }
653+
654+ if (t2 == TypeInt::ZERO) {
655+ // this division will always throw an exception
656+ return Type::TOP;
657+ }
556658
557659 // x/x == 1 since we always generate the dynamic divisor check for 0.
558660 if (in (1 ) == in (2 )) {
559661 return TypeInt::ONE;
560662 }
561663
562- // Either input is BOTTOM ==> the result is the local BOTTOM
563- const Type *bot = bottom_type ();
564- if ( (t1 == bot) || (t2 == bot) ||
565- (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) )
566- return bot;
664+ const TypeInt* i1 = t1->is_int ();
665+ const TypeInt* i2 = t2->is_int ();
567666
568- // Divide the two numbers. We approximate.
569- // If divisor is a constant and not zero
570- const TypeInt *i1 = t1->is_int ();
571- const TypeInt *i2 = t2->is_int ();
572- int widen = MAX2 (i1->_widen , i2->_widen );
573-
574- if ( i2->is_con () && i2->get_con () != 0 ) {
575- int32_t d = i2->get_con (); // Divisor
576- jint lo, hi;
577- if ( d >= 0 ) {
578- lo = i1->_lo /d;
579- hi = i1->_hi /d;
580- } else {
581- if ( d == -1 && i1->_lo == min_jint ) {
582- // 'min_jint/-1' throws arithmetic exception during compilation
583- lo = min_jint;
584- // do not support holes, 'hi' must go to either min_jint or max_jint:
585- // [min_jint, -10]/[-1,-1] ==> [min_jint] UNION [10,max_jint]
586- hi = i1->_hi == min_jint ? min_jint : max_jint;
587- } else {
588- lo = i1->_hi /d;
589- hi = i1->_lo /d;
590- }
591- }
592- return TypeInt::make (lo, hi, widen);
593- }
594-
595- // If the dividend is a constant
596- if ( i1->is_con () ) {
597- int32_t d = i1->get_con ();
598- if ( d < 0 ) {
599- if ( d == min_jint ) {
600- // (-min_jint) == min_jint == (min_jint / -1)
601- return TypeInt::make (min_jint, max_jint/2 + 1 , widen);
602- } else {
603- return TypeInt::make (d, -d, widen);
604- }
605- }
606- return TypeInt::make (-d, d, widen);
607- }
608-
609- // Otherwise we give up all hope
610- return TypeInt::INT;
667+ return compute_signed_div_type<TypeInt>(i1, i2);
611668}
612669
613670
@@ -655,65 +712,26 @@ Node *DivLNode::Ideal( PhaseGVN *phase, bool can_reshape) {
655712// prevent hoisting the divide above an unsafe test.
656713const Type* DivLNode::Value (PhaseGVN* phase) const {
657714 // Either input is TOP ==> the result is TOP
658- const Type *t1 = phase->type ( in (1 ) );
659- const Type *t2 = phase->type ( in (2 ) );
660- if ( t1 == Type::TOP ) return Type::TOP;
661- if ( t2 == Type::TOP ) return Type::TOP;
715+ const Type* t1 = phase->type (in (1 ));
716+ const Type* t2 = phase->type (in (2 ));
717+ if (t1 == Type::TOP || t2 == Type::TOP) {
718+ return Type::TOP;
719+ }
720+
721+ if (t2 == TypeLong::ZERO) {
722+ // this division will always throw an exception
723+ return Type::TOP;
724+ }
662725
663726 // x/x == 1 since we always generate the dynamic divisor check for 0.
664727 if (in (1 ) == in (2 )) {
665728 return TypeLong::ONE;
666729 }
667730
668- // Either input is BOTTOM ==> the result is the local BOTTOM
669- const Type *bot = bottom_type ();
670- if ( (t1 == bot) || (t2 == bot) ||
671- (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) )
672- return bot;
673-
674- // Divide the two numbers. We approximate.
675- // If divisor is a constant and not zero
676- const TypeLong *i1 = t1->is_long ();
677- const TypeLong *i2 = t2->is_long ();
678- int widen = MAX2 (i1->_widen , i2->_widen );
679-
680- if ( i2->is_con () && i2->get_con () != 0 ) {
681- jlong d = i2->get_con (); // Divisor
682- jlong lo, hi;
683- if ( d >= 0 ) {
684- lo = i1->_lo /d;
685- hi = i1->_hi /d;
686- } else {
687- if ( d == CONST64 (-1 ) && i1->_lo == min_jlong ) {
688- // 'min_jlong/-1' throws arithmetic exception during compilation
689- lo = min_jlong;
690- // do not support holes, 'hi' must go to either min_jlong or max_jlong:
691- // [min_jlong, -10]/[-1,-1] ==> [min_jlong] UNION [10,max_jlong]
692- hi = i1->_hi == min_jlong ? min_jlong : max_jlong;
693- } else {
694- lo = i1->_hi /d;
695- hi = i1->_lo /d;
696- }
697- }
698- return TypeLong::make (lo, hi, widen);
699- }
731+ const TypeLong* i1 = t1->is_long ();
732+ const TypeLong* i2 = t2->is_long ();
700733
701- // If the dividend is a constant
702- if ( i1->is_con () ) {
703- jlong d = i1->get_con ();
704- if ( d < 0 ) {
705- if ( d == min_jlong ) {
706- // (-min_jlong) == min_jlong == (min_jlong / -1)
707- return TypeLong::make (min_jlong, max_jlong/2 + 1 , widen);
708- } else {
709- return TypeLong::make (d, -d, widen);
710- }
711- }
712- return TypeLong::make (-d, d, widen);
713- }
714-
715- // Otherwise we give up all hope
716- return TypeLong::LONG;
734+ return compute_signed_div_type<TypeLong>(i1, i2);
717735}
718736
719737
0 commit comments