Skip to content

Commit c31a801

Browse files
committed
[GR-23621] Fix operator '**' for operand types (Integer, PInt).
PullRequest: graalpython/975
2 parents e5224aa + 3a9f446 commit c31a801

File tree

2 files changed

+51
-11
lines changed

2 files changed

+51
-11
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_binary_arithmetic.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,3 +290,8 @@ def test_lshift():
290290
assert 1 << 32 == 0x100000000
291291
assert 1 << 64 == 0x10000000000000000
292292
assert 1 << 128 == 0x100000000000000000000000000000000
293+
294+
295+
def test_pow():
296+
# (0xffffffffffffffff >> 63) is used to produce a non-narrowed int
297+
assert 2**(0xffffffffffffffff >> 63) == 2

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/IntBuiltins.java

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,7 @@ protected static PowNode create() {
756756
}
757757

758758
@Specialization(guards = "right >= 0", rewriteOn = ArithmeticException.class)
759-
int doIntegerFast(int left, int right, @SuppressWarnings("unused") PNone none) {
759+
static int doIntegerFast(int left, int right, @SuppressWarnings("unused") PNone none) {
760760
int result = 1;
761761
int exponent = right;
762762
int base = left;
@@ -770,13 +770,13 @@ int doIntegerFast(int left, int right, @SuppressWarnings("unused") PNone none) {
770770
return result;
771771
}
772772

773-
@Specialization(guards = "right >= 0")
774-
PInt doInteger(int left, int right, @SuppressWarnings("unused") PNone none) {
775-
return factory().createInt(op(PInt.longToBigInteger(left), right));
773+
@Specialization(guards = "right >= 0", replaces = "doIntegerFast", rewriteOn = ArithmeticException.class)
774+
static long doInteger(int left, int right, PNone none) {
775+
return doLongFast((long) left, (long) right, none);
776776
}
777777

778778
@Specialization(guards = "right >= 0", rewriteOn = ArithmeticException.class)
779-
long doLongFast(long left, int right, PNone none) {
779+
static long doLongFast(long left, int right, PNone none) {
780780
return doLongFast(left, (long) right, none);
781781
}
782782

@@ -786,7 +786,7 @@ PInt doLong(long left, int right, PNone none) {
786786
}
787787

788788
@Specialization(guards = "right >= 0", rewriteOn = ArithmeticException.class)
789-
long doLongFast(int left, long right, PNone none) {
789+
static long doLongFast(int left, long right, PNone none) {
790790
return doLongFast((long) left, right, none);
791791
}
792792

@@ -796,7 +796,7 @@ PInt doLong(int left, long right, PNone none) {
796796
}
797797

798798
@Specialization(guards = "right >= 0", rewriteOn = ArithmeticException.class)
799-
long doLongFast(long left, long right, @SuppressWarnings("unused") PNone none) {
799+
static long doLongFast(long left, long right, @SuppressWarnings("unused") PNone none) {
800800
long result = 1;
801801
long exponent = right;
802802
long base = left;
@@ -810,21 +810,56 @@ long doLongFast(long left, long right, @SuppressWarnings("unused") PNone none) {
810810
return result;
811811
}
812812

813-
@Specialization(guards = "right >= 0")
813+
@Specialization(guards = "right >= 0", replaces = "doLongFast")
814814
PInt doLong(long left, long right, @SuppressWarnings("unused") PNone none) {
815815
return factory().createInt(op(PInt.longToBigInteger(left), right));
816816
}
817817

818-
@Specialization
819-
double doInt(long left, long right, @SuppressWarnings("unused") PNone none) {
818+
@Specialization(guards = "right < 0")
819+
static double doInt(long left, long right, @SuppressWarnings("unused") PNone none) {
820820
return Math.pow(left, right);
821821
}
822822

823823
@Specialization
824-
double doInt(long left, double right, @SuppressWarnings("unused") PNone none) {
824+
static double doInt(long left, double right, @SuppressWarnings("unused") PNone none) {
825825
return Math.pow(left, right);
826826
}
827827

828+
@Specialization(rewriteOn = ArithmeticException.class)
829+
static Object doLongPIntNarrow(long left, PInt right, PNone none) {
830+
long lright = right.longValueExact();
831+
if (lright >= 0) {
832+
return doLongFast(left, lright, none);
833+
}
834+
return doInt(left, lright, none);
835+
}
836+
837+
@Specialization(replaces = "doLongPIntNarrow")
838+
PInt doLongPInt(long left, PInt right, @SuppressWarnings("unused") PNone none) {
839+
try {
840+
return factory().createInt(op(PInt.longToBigInteger(left), right.longValueExact()));
841+
} catch (ArithmeticException e) {
842+
// fall through to normal computation
843+
}
844+
double value = Math.pow(left, right.doubleValue());
845+
return factory().createInt((long) value);
846+
}
847+
848+
@Specialization(guards = "right >= 0", rewriteOn = ArithmeticException.class)
849+
long doPIntLongNarrow(PInt left, long right, @SuppressWarnings("unused") PNone none) {
850+
return PInt.longValueExact(op(left.getValue(), right));
851+
}
852+
853+
@Specialization(guards = "right >= 0", replaces = "doPIntLongNarrow")
854+
PInt doPIntLongPositive(PInt left, long right, @SuppressWarnings("unused") PNone none) {
855+
return factory().createInt(op(left.getValue(), right));
856+
}
857+
858+
@Specialization(guards = "right < 0")
859+
double doPIntLongNegative(PInt left, long right, @SuppressWarnings("unused") PNone none) {
860+
return TrueDivNode.op(BigInteger.ONE, op(left.getValue(), -right));
861+
}
862+
828863
@Specialization
829864
PInt doPInt(PInt left, PInt right, @SuppressWarnings("unused") PNone none) {
830865
try {

0 commit comments

Comments
 (0)