@@ -620,14 +620,36 @@ public boolean counterNeverOverflows() {
620
620
}
621
621
622
622
public boolean ivCanNeverOverflow (InductionVariable iv ) {
623
- if (iv == getLimitCheckedIV ()) {
624
- if (!isLimitIncluded && iv .isConstantStride () && Loop .absStrideIsOne (iv )) {
625
- return true ;
626
- }
627
- if (loop .loopBegin ().isProtectedNonOverflowingUnsigned ()) {
628
- return true ;
623
+ if (iv != getLimitCheckedIV ()) {
624
+ /*
625
+ * All non-limit checked IVs: This IV is not compared against limit and thus we cannot
626
+ * play the trick comparing against the end stamp. We have to compute (if possible) the
627
+ * extremum value and use that.
628
+ */
629
+ if (iv .isConstantInit () && isConstantMaxTripCount () && iv .isConstantStride ()) {
630
+ try {
631
+ final int bits = IntegerStamp .getBits (iv .valueNode ().stamp (NodeView .DEFAULT ));
632
+ long tripCountMinus1 = LoopUtility .subtractExact (bits , LoopUtility .tripCountSignedExact (this ), 1 );
633
+ long stripTimesTripCount = LoopUtility .multiplyExact (bits , iv .constantStride (), tripCountMinus1 );
634
+ @ SuppressWarnings ("unused" )
635
+ long extremum = LoopUtility .addExact (bits , stripTimesTripCount , iv .initNode ().asJavaConstant ().asLong ());
636
+ return true ;
637
+ } catch (ArithmeticException e ) {
638
+ // overflow
639
+ return false ;
640
+ }
629
641
}
630
- // @formatter:off
642
+ }
643
+
644
+ // BELOW: limitCheckedIV case
645
+
646
+ if (!isLimitIncluded && iv .isConstantStride () && Loop .absStrideIsOne (iv )) {
647
+ return true ;
648
+ }
649
+ if (loop .loopBegin ().isProtectedNonOverflowingUnsigned ()) {
650
+ return true ;
651
+ }
652
+ // @formatter:off
631
653
/*
632
654
* Following comment reasons about the simplest possible loop form:
633
655
*
@@ -675,37 +697,16 @@ public boolean ivCanNeverOverflow(InductionVariable iv) {
675
697
* reasons.
676
698
*/
677
699
// @formatter:on
678
- IntegerStamp endStamp = (IntegerStamp ) getTripCountLimit ().stamp (NodeView .DEFAULT );
679
- ValueNode strideNode = getLimitCheckedIV ().strideNode ();
680
- IntegerStamp strideStamp = (IntegerStamp ) strideNode .stamp (NodeView .DEFAULT );
681
- IntegerHelper integerHelper = getCounterIntegerHelper ();
682
- if (getDirection () == InductionVariable .Direction .Up ) {
683
- long max = integerHelper .maxValue ();
684
- return integerHelper .compare (endStamp .upperBound (), max - (strideStamp .upperBound () - 1 ) - (isLimitIncluded ? 1 : 0 )) <= 0 ;
685
- } else if (getDirection () == InductionVariable .Direction .Down ) {
686
- long min = integerHelper .minValue ();
687
- return integerHelper .compare (min + (1 - strideStamp .lowerBound ()) + (isLimitIncluded ? 1 : 0 ), endStamp .lowerBound ()) <= 0 ;
688
- }
689
- return false ;
690
- } else {
691
- /*
692
- * All over IVs: This IV is not compared against limit and thus we cannot play the trick
693
- * comparing against the end stamp. We have to compute (if possible) the extremum value
694
- * and use that.
695
- */
696
- if (iv .isConstantInit () && isConstantMaxTripCount () && iv .isConstantStride ()) {
697
- try {
698
- final int bits = IntegerStamp .getBits (iv .valueNode ().stamp (NodeView .DEFAULT ));
699
- long tripCountMinus1 = LoopUtility .subtractExact (bits , LoopUtility .tripCountSignedExact (this ), 1 );
700
- long stripTimesTripCount = LoopUtility .multiplyExact (bits , iv .constantStride (), tripCountMinus1 );
701
- @ SuppressWarnings ("unused" )
702
- long extremum = LoopUtility .addExact (bits , stripTimesTripCount , iv .initNode ().asJavaConstant ().asLong ());
703
- return true ;
704
- } catch (ArithmeticException e ) {
705
- // overflow
706
- return false ;
707
- }
708
- }
700
+ IntegerStamp endStamp = (IntegerStamp ) getTripCountLimit ().stamp (NodeView .DEFAULT );
701
+ ValueNode strideNode = getLimitCheckedIV ().strideNode ();
702
+ IntegerStamp strideStamp = (IntegerStamp ) strideNode .stamp (NodeView .DEFAULT );
703
+ IntegerHelper integerHelper = getCounterIntegerHelper ();
704
+ if (getDirection () == InductionVariable .Direction .Up ) {
705
+ long max = integerHelper .maxValue ();
706
+ return integerHelper .compare (endStamp .upperBound (), max - (strideStamp .upperBound () - 1 ) - (isLimitIncluded ? 1 : 0 )) <= 0 ;
707
+ } else if (getDirection () == InductionVariable .Direction .Down ) {
708
+ long min = integerHelper .minValue ();
709
+ return integerHelper .compare (min + (1 - strideStamp .lowerBound ()) + (isLimitIncluded ? 1 : 0 ), endStamp .lowerBound ()) <= 0 ;
709
710
}
710
711
return false ;
711
712
}
0 commit comments