@@ -585,6 +585,8 @@ _PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, PyObject *consts,
585585#define SPEC_FAIL_BINARY_OP_OR_DIFFERENT_TYPES 30
586586#define SPEC_FAIL_BINARY_OP_XOR_INT 31
587587#define SPEC_FAIL_BINARY_OP_XOR_DIFFERENT_TYPES 32
588+ #define SPEC_FAIL_BINARY_OP_LSHIFT_INT 33
589+ #define SPEC_FAIL_BINARY_OP_LSHIFT_DIFFERENT_TYPES 34
588590#define SPEC_FAIL_BINARY_OP_RSHIFT_INT 33
589591#define SPEC_FAIL_BINARY_OP_RSHIFT_DIFFERENT_TYPES 34
590592
@@ -2373,6 +2375,12 @@ binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs)
23732375 return SPEC_FAIL_BINARY_OP_FLOOR_DIVIDE ;
23742376 case NB_LSHIFT :
23752377 case NB_INPLACE_LSHIFT :
2378+ if (!Py_IS_TYPE (lhs , Py_TYPE (rhs ))) {
2379+ return SPEC_FAIL_BINARY_OP_LSHIFT_DIFFERENT_TYPES ;
2380+ }
2381+ if (PyLong_CheckExact (lhs )) {
2382+ return SPEC_FAIL_BINARY_OP_LSHIFT_INT ;
2383+ }
23762384 return SPEC_FAIL_BINARY_OP_LSHIFT ;
23772385 case NB_MATRIX_MULTIPLY :
23782386 case NB_INPLACE_MATRIX_MULTIPLY :
@@ -2461,9 +2469,13 @@ compactlongs_guard(PyObject *lhs, PyObject *rhs)
24612469}
24622470
24632471static int
2464- compactlong_compactnonnegativelong_guard (PyObject * lhs , PyObject * rhs )
2472+ shift_guard (PyObject * lhs , PyObject * rhs )
24652473{
2466- return (is_compactlong (lhs ) && is_compactnonnegativelong (rhs ));
2474+ // we could use _long_is_small_int here, which is slightly faster than is_compactnonnegativelong
2475+
2476+ // rshift with value larger the the number of bits is undefined in C
2477+ // for lshift we do not want to overflow, but we always have at least 16 bits available
2478+ return (is_compactlong (lhs ) && is_compactnonnegativelong (rhs ) && (_PyLong_CompactValue ((PyLongObject * )rhs ) <= 16 ) );
24672479}
24682480
24692481#define BITWISE_LONGS_ACTION (NAME , OP ) \
@@ -2477,6 +2489,7 @@ compactlong_compactnonnegativelong_guard(PyObject *lhs, PyObject *rhs)
24772489BITWISE_LONGS_ACTION (compactlongs_or , |)
24782490BITWISE_LONGS_ACTION (compactlongs_and , & )
24792491BITWISE_LONGS_ACTION (compactlongs_xor , ^)
2492+ BITWISE_LONGS_ACTION (compactlongs_lshift , <<)
24802493BITWISE_LONGS_ACTION (compactlongs_rshift , >>)
24812494#undef BITWISE_LONGS_ACTION
24822495
@@ -2554,11 +2567,13 @@ static _PyBinaryOpSpecializationDescr compactlongs_specs[NB_OPARG_LAST+1] = {
25542567 [NB_OR ] = {compactlongs_guard , compactlongs_or },
25552568 [NB_AND ] = {compactlongs_guard , compactlongs_and },
25562569 [NB_XOR ] = {compactlongs_guard , compactlongs_xor },
2557- [NB_RSHIFT ] = {compactlong_compactnonnegativelong_guard , compactlongs_rshift },
2570+ [NB_LSHIFT ] = {shift_guard , compactlongs_lshift },
2571+ [NB_RSHIFT ] = {shift_guard , compactlongs_rshift },
25582572 [NB_INPLACE_OR ] = {compactlongs_guard , compactlongs_or },
25592573 [NB_INPLACE_AND ] = {compactlongs_guard , compactlongs_and },
25602574 [NB_INPLACE_XOR ] = {compactlongs_guard , compactlongs_xor },
2561- [NB_INPLACE_RSHIFT ] = {compactlong_compactnonnegativelong_guard , compactlongs_rshift },
2575+ [NB_INPLACE_LSHIFT ] = {shift_guard , compactlongs_lshift },
2576+ [NB_INPLACE_RSHIFT ] = {shift_guard , compactlongs_rshift },
25622577};
25632578
25642579static _PyBinaryOpSpecializationDescr float_compactlong_specs [NB_OPARG_LAST + 1 ] = {
0 commit comments