@@ -467,7 +467,8 @@ dummy_func(
467467 assert (PyFloat_CheckExact (val_o ));
468468 assert (_PyObject_IsUniquelyReferenced (val_o ));
469469 STAT_INC (UNARY_NEGATIVE , hit );
470- ((PyFloatObject * )val_o )-> ob_fval = - ((PyFloatObject * )val_o )-> ob_fval ;
470+ double dres = - ((PyFloatObject * )val_o )-> ob_fval ;
471+ ((PyFloatObject * )val_o )-> ob_fval = dres ;
471472 res = value ;
472473 v = PyStackRef_NULL ;
473474 INPUTS_DEAD ();
@@ -788,14 +789,18 @@ dummy_func(
788789 // instead of allocating a new float. Tier 2 only.
789790 // The optimizer sets l to null so the following _POP_TOP_FLOAT
790791 // becomes _POP_TOP_NOP.
792+ // Note: read into a local double and write back to avoid compound
793+ // assignment (+=) on ob_fval, which generates problematic JIT
794+ // stencils on i686-pc-windows-msvc.
791795 tier2 op (_BINARY_OP_ADD_FLOAT_INPLACE , (left , right -- res , l , r )) {
792796 PyObject * left_o = PyStackRef_AsPyObjectBorrow (left );
793797 PyObject * right_o = PyStackRef_AsPyObjectBorrow (right );
794798 assert (PyFloat_CheckExact (left_o ));
795799 assert (PyFloat_CheckExact (right_o ));
796800 assert (_PyObject_IsUniquelyReferenced (left_o ));
797801 STAT_INC (BINARY_OP , hit );
798- ((PyFloatObject * )left_o )-> ob_fval += ((PyFloatObject * )right_o )-> ob_fval ;
802+ double dres = ((PyFloatObject * )left_o )-> ob_fval + ((PyFloatObject * )right_o )-> ob_fval ;
803+ ((PyFloatObject * )left_o )-> ob_fval = dres ;
799804 res = left ;
800805 l = PyStackRef_NULL ;
801806 r = right ;
@@ -809,7 +814,8 @@ dummy_func(
809814 assert (PyFloat_CheckExact (right_o ));
810815 assert (_PyObject_IsUniquelyReferenced (left_o ));
811816 STAT_INC (BINARY_OP , hit );
812- ((PyFloatObject * )left_o )-> ob_fval -= ((PyFloatObject * )right_o )-> ob_fval ;
817+ double dres = ((PyFloatObject * )left_o )-> ob_fval - ((PyFloatObject * )right_o )-> ob_fval ;
818+ ((PyFloatObject * )left_o )-> ob_fval = dres ;
813819 res = left ;
814820 l = PyStackRef_NULL ;
815821 r = right ;
@@ -823,23 +829,24 @@ dummy_func(
823829 assert (PyFloat_CheckExact (right_o ));
824830 assert (_PyObject_IsUniquelyReferenced (left_o ));
825831 STAT_INC (BINARY_OP , hit );
826- ((PyFloatObject * )left_o )-> ob_fval *= ((PyFloatObject * )right_o )-> ob_fval ;
832+ double dres = ((PyFloatObject * )left_o )-> ob_fval * ((PyFloatObject * )right_o )-> ob_fval ;
833+ ((PyFloatObject * )left_o )-> ob_fval = dres ;
827834 res = left ;
828835 l = PyStackRef_NULL ;
829836 r = right ;
830837 INPUTS_DEAD ();
831838 }
832839
833- // Inplace RIGHT variants for commutative ops (add, multiply).
834- // Mutate the uniquely-referenced right operand instead.
840+ // Inplace RIGHT variants: mutate the uniquely-referenced right operand.
835841 tier2 op (_BINARY_OP_ADD_FLOAT_INPLACE_RIGHT , (left , right -- res , l , r )) {
836842 PyObject * left_o = PyStackRef_AsPyObjectBorrow (left );
837843 PyObject * right_o = PyStackRef_AsPyObjectBorrow (right );
838844 assert (PyFloat_CheckExact (left_o ));
839845 assert (PyFloat_CheckExact (right_o ));
840846 assert (_PyObject_IsUniquelyReferenced (right_o ));
841847 STAT_INC (BINARY_OP , hit );
842- ((PyFloatObject * )right_o )-> ob_fval += ((PyFloatObject * )left_o )-> ob_fval ;
848+ double dres = ((PyFloatObject * )left_o )-> ob_fval + ((PyFloatObject * )right_o )-> ob_fval ;
849+ ((PyFloatObject * )right_o )-> ob_fval = dres ;
843850 res = right ;
844851 l = left ;
845852 r = PyStackRef_NULL ;
@@ -853,23 +860,23 @@ dummy_func(
853860 assert (PyFloat_CheckExact (right_o ));
854861 assert (_PyObject_IsUniquelyReferenced (right_o ));
855862 STAT_INC (BINARY_OP , hit );
856- ((PyFloatObject * )right_o )-> ob_fval *= ((PyFloatObject * )left_o )-> ob_fval ;
863+ double dres = ((PyFloatObject * )left_o )-> ob_fval * ((PyFloatObject * )right_o )-> ob_fval ;
864+ ((PyFloatObject * )right_o )-> ob_fval = dres ;
857865 res = right ;
858866 l = left ;
859867 r = PyStackRef_NULL ;
860868 INPUTS_DEAD ();
861869 }
862870
863- // Inplace RIGHT variant for subtract (non-commutative):
864- // right->ob_fval = left->ob_fval - right->ob_fval
865871 tier2 op (_BINARY_OP_SUBTRACT_FLOAT_INPLACE_RIGHT , (left , right -- res , l , r )) {
866872 PyObject * left_o = PyStackRef_AsPyObjectBorrow (left );
867873 PyObject * right_o = PyStackRef_AsPyObjectBorrow (right );
868874 assert (PyFloat_CheckExact (left_o ));
869875 assert (PyFloat_CheckExact (right_o ));
870876 assert (_PyObject_IsUniquelyReferenced (right_o ));
871877 STAT_INC (BINARY_OP , hit );
872- ((PyFloatObject * )right_o )-> ob_fval = ((PyFloatObject * )left_o )-> ob_fval - ((PyFloatObject * )right_o )-> ob_fval ;
878+ double dres = ((PyFloatObject * )left_o )-> ob_fval - ((PyFloatObject * )right_o )-> ob_fval ;
879+ ((PyFloatObject * )right_o )-> ob_fval = dres ;
873880 res = right ;
874881 l = left ;
875882 r = PyStackRef_NULL ;
0 commit comments