Skip to content

Commit 8363e9d

Browse files
committed
Address Irit's review && Add guards for NaN
1 parent 131b92a commit 8363e9d

File tree

2 files changed

+51
-19
lines changed

2 files changed

+51
-19
lines changed

Lib/test/test_opcache.py

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,19 +1362,47 @@ def binary_op_add_extend():
13621362
self.assert_specialized(binary_op_add_extend, "BINARY_OP_EXTEND")
13631363
self.assert_no_opcode(binary_op_add_extend, "BINARY_OP")
13641364

1365-
def compactlong_lhs(arg):
1366-
42 / arg
1367-
def float_lhs(arg):
1368-
42.0 / arg
1369-
1370-
with self.assertRaises(ZeroDivisionError):
1371-
compactlong_lhs(0)
1372-
with self.assertRaises(ZeroDivisionError):
1373-
compactlong_lhs(0.0)
1374-
with self.assertRaises(ZeroDivisionError):
1375-
float_lhs(0.0)
1376-
with self.assertRaises(ZeroDivisionError):
1377-
float_lhs(0)
1365+
def binary_op_zero_division():
1366+
def compactlong_lhs(arg):
1367+
42 / arg
1368+
def float_lhs(arg):
1369+
42.0 / arg
1370+
1371+
with self.assertRaises(ZeroDivisionError):
1372+
compactlong_lhs(0)
1373+
with self.assertRaises(ZeroDivisionError):
1374+
compactlong_lhs(0.0)
1375+
with self.assertRaises(ZeroDivisionError):
1376+
float_lhs(0.0)
1377+
with self.assertRaises(ZeroDivisionError):
1378+
float_lhs(0)
1379+
1380+
self.assert_no_opcode(compactlong_lhs, "BINARY_OP_EXTEND")
1381+
self.assert_no_opcode(float_lhs, "BINARY_OP_EXTEND")
1382+
1383+
binary_op_zero_division()
1384+
1385+
def binary_op_nan():
1386+
def compactlong_lhs(arg):
1387+
42 + arg
1388+
42 - arg
1389+
42 * arg
1390+
42 / arg
1391+
def compactlong_rhs(arg):
1392+
arg + 42
1393+
arg - 42
1394+
arg * 42
1395+
arg / 42
1396+
1397+
compactlong_lhs(1.0)
1398+
compactlong_lhs(float('nan'))
1399+
compactlong_rhs(1.0)
1400+
compactlong_rhs(float('nan'))
1401+
1402+
self.assert_no_opcode(compactlong_lhs, "BINARY_OP_EXTEND")
1403+
self.assert_no_opcode(compactlong_rhs, "BINARY_OP_EXTEND")
1404+
1405+
binary_op_nan()
13781406

13791407
@cpython_only
13801408
@requires_specialization_ft

Python/specialize.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2416,25 +2416,28 @@ binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs)
24162416

24172417
/* float-long */
24182418

2419+
// Guards should check that the float part is not NaN.
2420+
// Guards for / (aka true_div) should check for 0 or 0.0 as the rhs.
24192421
static int
24202422
float_compactlong_guard(PyObject *lhs, PyObject *rhs)
24212423
{
24222424
return (
24232425
PyFloat_CheckExact(lhs) &&
24242426
PyLong_CheckExact(rhs) &&
2425-
_PyLong_IsCompact((PyLongObject *)rhs)
2427+
_PyLong_IsCompact((PyLongObject *)rhs) &&
2428+
!isnan(PyFloat_AsDouble(lhs))
24262429
);
24272430
}
24282431

24292432
static int
24302433
float_compactlong_guard_true_div(PyObject *lhs, PyObject *rhs)
24312434
{
2432-
// guards should check if rhs has a non-zero value
24332435
return (
24342436
PyFloat_CheckExact(lhs) &&
24352437
PyLong_CheckExact(rhs) &&
24362438
_PyLong_IsCompact((PyLongObject *)rhs) &&
2437-
!PyLong_IsZero(rhs)
2439+
!PyLong_IsZero(rhs) &&
2440+
!isnan(PyFloat_AsDouble(lhs))
24382441
);
24392442
}
24402443

@@ -2460,19 +2463,20 @@ compactlong_float_guard(PyObject *lhs, PyObject *rhs)
24602463
return (
24612464
PyFloat_CheckExact(rhs) &&
24622465
PyLong_CheckExact(lhs) &&
2463-
_PyLong_IsCompact((PyLongObject *)lhs)
2466+
_PyLong_IsCompact((PyLongObject *)lhs) &&
2467+
!isnan(PyFloat_AsDouble(rhs))
24642468
);
24652469
}
24662470

24672471
static int
24682472
compactlong_float_guard_true_div(PyObject *lhs, PyObject *rhs)
24692473
{
2470-
// guards should check if rhs has a non-zero value
24712474
return (
24722475
PyFloat_CheckExact(rhs) &&
24732476
PyLong_CheckExact(lhs) &&
24742477
_PyLong_IsCompact((PyLongObject *)lhs) &&
2475-
PyFloat_AsDouble(rhs) != 0.0
2478+
PyFloat_AsDouble(rhs) != 0.0 &&
2479+
!isnan(PyFloat_AsDouble(rhs))
24762480
);
24772481
}
24782482

0 commit comments

Comments
 (0)