@@ -875,9 +875,11 @@ _Py_uop_sym_apply_predicate_narrowing(JitOptContext *ctx, JitOptRef ref, bool br
875875
876876 bool narrow = false;
877877 switch (pred .kind ) {
878+ case JIT_PRED_EQ :
878879 case JIT_PRED_IS :
879880 narrow = branch_is_true ;
880881 break ;
882+ case JIT_PRED_NE :
881883 case JIT_PRED_IS_NOT :
882884 narrow = !branch_is_true ;
883885 break ;
@@ -1300,7 +1302,7 @@ _Py_uop_symbols_test(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))
13001302 TEST_PREDICATE (_Py_uop_sym_is_const (ctx , subject ), "predicate narrowing did not const-narrow subject (None)" );
13011303 TEST_PREDICATE (_Py_uop_sym_get_const (ctx , subject ) == Py_None , "predicate narrowing did not narrow subject to None" );
13021304
1303- // Test narrowing subject to numerical constant
1305+ // Test narrowing subject to numerical constant from is comparison
13041306 subject = _Py_uop_sym_new_unknown (ctx );
13051307 PyObject * one_obj = PyLong_FromLong (1 );
13061308 JitOptRef const_one = _Py_uop_sym_new_const (ctx , one_obj );
@@ -1314,6 +1316,56 @@ _Py_uop_symbols_test(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))
13141316 _Py_uop_sym_apply_predicate_narrowing (ctx , ref , true);
13151317 TEST_PREDICATE (_Py_uop_sym_is_const (ctx , subject ), "predicate narrowing did not const-narrow subject (1)" );
13161318 TEST_PREDICATE (_Py_uop_sym_get_const (ctx , subject ) == one_obj , "predicate narrowing did not narrow subject to 1" );
1319+
1320+ // Test narrowing subject to numerical constant from EQ predicate
1321+ subject = _Py_uop_sym_new_unknown (ctx );
1322+ if (PyJitRef_IsNull (subject ) || PyJitRef_IsNull (const_one )) {
1323+ goto fail ;
1324+ }
1325+ ref = _Py_uop_sym_new_predicate (ctx , subject , const_one , JIT_PRED_EQ );
1326+ if (PyJitRef_IsNull (ref )) {
1327+ goto fail ;
1328+ }
1329+ _Py_uop_sym_apply_predicate_narrowing (ctx , ref , true);
1330+ TEST_PREDICATE (_Py_uop_sym_is_const (ctx , subject ), "predicate narrowing did not const-narrow subject (1)" );
1331+ TEST_PREDICATE (_Py_uop_sym_get_const (ctx , subject ) == one_obj , "predicate narrowing did not narrow subject to 1" );
1332+
1333+ // Resolving EQ predicate to False should not narrow subject
1334+ subject = _Py_uop_sym_new_unknown (ctx );
1335+ if (PyJitRef_IsNull (subject )) {
1336+ goto fail ;
1337+ }
1338+ ref = _Py_uop_sym_new_predicate (ctx , subject , const_one , JIT_PRED_EQ );
1339+ if (PyJitRef_IsNull (ref )) {
1340+ goto fail ;
1341+ }
1342+ _Py_uop_sym_apply_predicate_narrowing (ctx , ref , false);
1343+ TEST_PREDICATE (!_Py_uop_sym_is_const (ctx , subject ), "predicate narrowing incorrectly narrowed subject (inverted/true)" );
1344+
1345+ // Test narrowing subject to numerical constant from NE predicate
1346+ subject = _Py_uop_sym_new_unknown (ctx );
1347+ if (PyJitRef_IsNull (subject ) || PyJitRef_IsNull (const_one )) {
1348+ goto fail ;
1349+ }
1350+ ref = _Py_uop_sym_new_predicate (ctx , subject , const_one , JIT_PRED_NE );
1351+ if (PyJitRef_IsNull (ref )) {
1352+ goto fail ;
1353+ }
1354+ _Py_uop_sym_apply_predicate_narrowing (ctx , ref , false);
1355+ TEST_PREDICATE (_Py_uop_sym_is_const (ctx , subject ), "predicate narrowing did not const-narrow subject (1)" );
1356+ TEST_PREDICATE (_Py_uop_sym_get_const (ctx , subject ) == one_obj , "predicate narrowing did not narrow subject to 1" );
1357+
1358+ // Resolving NE predicate to true should not narrow subject
1359+ subject = _Py_uop_sym_new_unknown (ctx );
1360+ if (PyJitRef_IsNull (subject )) {
1361+ goto fail ;
1362+ }
1363+ ref = _Py_uop_sym_new_predicate (ctx , subject , const_one , JIT_PRED_NE );
1364+ if (PyJitRef_IsNull (ref )) {
1365+ goto fail ;
1366+ }
1367+ _Py_uop_sym_apply_predicate_narrowing (ctx , ref , true);
1368+ TEST_PREDICATE (!_Py_uop_sym_is_const (ctx , subject ), "predicate narrowing incorrectly narrowed subject (inverted/true)" );
13171369
13181370 val_big = PyNumber_Lshift (_PyLong_GetOne (), PyLong_FromLong (66 ));
13191371 if (val_big == NULL ) {
0 commit comments