@@ -704,7 +704,9 @@ static long doLLFast(long left, long right, @SuppressWarnings("unused") PNone no
704704 result = Math .multiplyExact (result , base );
705705 }
706706 exponent >>= 1 ;
707- base = Math .multiplyExact (base , base );
707+ if (exponent != 0 ) { // prevent overflow in last iteration
708+ base = Math .multiplyExact (base , base );
709+ }
708710 }
709711 return result ;
710712 }
@@ -1313,15 +1315,13 @@ long doLL(long left, long right) {
13131315 }
13141316
13151317 @ Specialization
1316- PInt doIPi (int left , PInt right ) {
1317- raiseNegativeShiftCount (!right .isZeroOrPositive ());
1318- return factory ().createInt (op (PInt .longToBigInteger (left ), right .intValue ()));
1318+ Object doIPi (int left , PInt right ) {
1319+ return doHugeShift (PInt .longToBigInteger (left ), right );
13191320 }
13201321
13211322 @ Specialization
1322- PInt doLPi (long left , PInt right ) {
1323- raiseNegativeShiftCount (!right .isZeroOrPositive ());
1324- return factory ().createInt (op (PInt .longToBigInteger (left ), right .intValue ()));
1323+ Object doLPi (long left , PInt right ) {
1324+ return doHugeShift (PInt .longToBigInteger (left ), right );
13251325 }
13261326
13271327 @ Specialization
@@ -1331,15 +1331,20 @@ PInt doPiI(PInt left, int right) {
13311331 }
13321332
13331333 @ Specialization
1334- PInt doPiL (PInt left , long right ) {
1334+ Object doPiL (PInt left , long right ) {
13351335 raiseNegativeShiftCount (right < 0 );
1336- return factory ().createInt (op (left .getValue (), (int ) right ));
1336+ int rightI = (int ) right ;
1337+ if (rightI == right ) {
1338+ return factory ().createInt (op (left .getValue (), rightI ));
1339+ }
1340+ // right is >= 2**31, BigInteger's bitLength is at most 2**31-1
1341+ // therefore the result of shifting right is just the sign bit
1342+ return left .isNegative () ? -1 : 0 ;
13371343 }
13381344
13391345 @ Specialization
1340- PInt doPInt (PInt left , PInt right ) {
1341- raiseNegativeShiftCount (!right .isZeroOrPositive ());
1342- return factory ().createInt (op (left .getValue (), right .intValue ()));
1346+ Object doPInt (PInt left , PInt right ) {
1347+ return doHugeShift (left .getValue (), right );
13431348 }
13441349
13451350 private void raiseNegativeShiftCount (boolean cond ) {
@@ -1354,8 +1359,19 @@ PNotImplemented doGeneric(Object a, Object b) {
13541359 return PNotImplemented .NOT_IMPLEMENTED ;
13551360 }
13561361
1362+ private Object doHugeShift (BigInteger left , PInt right ) {
1363+ raiseNegativeShiftCount (!right .isZeroOrPositive ());
1364+ try {
1365+ return factory ().createInt (op (left , right .intValueExact ()));
1366+ } catch (ArithmeticException e ) {
1367+ // right is >= 2**31, BigInteger's bitLength is at most 2**31-1
1368+ // therefore the result of shifting right is just the sign bit
1369+ return left .signum () < 0 ? -1 : 0 ;
1370+ }
1371+ }
1372+
13571373 @ TruffleBoundary
1358- public static BigInteger op (BigInteger left , int right ) {
1374+ private static BigInteger op (BigInteger left , int right ) {
13591375 return left .shiftRight (right );
13601376 }
13611377
0 commit comments