@@ -3999,30 +3999,7 @@ x_mul(PyLongObject *a, PyLongObject *b)
39993999 }
40004000 }
40014001 else { /* a is not the same as b -- gradeschool int mult */
4002- /* No digit of z needs to start out zeroed: the i == 0 pass stores
4003- * z[0:size_b+1] outright, pass i only reads z[i:i+size_b], which
4004- * earlier passes have already written, and each pass stores its final
4005- * carry into z[i+size_b], which no earlier pass has touched.
4006- */
4007- assert (size_a >= 1 );
4008- {
4009- twodigits carry = 0 ;
4010- twodigits f = a -> long_value .ob_digit [0 ];
4011- digit * pz = z -> long_value .ob_digit ;
4012- digit * pb = b -> long_value .ob_digit ;
4013- digit * pbend = b -> long_value .ob_digit + size_b ;
4014-
4015- while (pb < pbend ) {
4016- carry += * pb ++ * f ;
4017- * pz ++ = (digit )(carry & PyLong_MASK );
4018- carry >>= PyLong_SHIFT ;
4019- assert (carry <= PyLong_MASK );
4020- }
4021- /* The final carry fits in a digit, so no masking is needed. */
4022- * pz = (digit )carry ;
4023- assert ((carry >> PyLong_SHIFT ) == 0 );
4024- }
4025- for (i = 1 ; i < size_a ; ++ i ) {
4002+ for (i = 0 ; i < size_a ; ++ i ) {
40264003 twodigits carry = 0 ;
40274004 twodigits f = a -> long_value .ob_digit [i ];
40284005 digit * pz = z -> long_value .ob_digit + i ;
@@ -4034,15 +4011,17 @@ x_mul(PyLongObject *a, PyLongObject *b)
40344011 return NULL ;
40354012 });
40364013
4014+ /* Row 0 has nothing to add to yet (z is not zeroed); every
4015+ later row only reads digits that the previous row wrote.
4016+ Compilers split the i == 0 row off into its own loop. */
40374017 while (pb < pbend ) {
4038- carry += * pz + * pb ++ * f ;
4018+ carry += ( i ? * pz : 0 ) + * pb ++ * f ;
40394019 * pz ++ = (digit )(carry & PyLong_MASK );
40404020 carry >>= PyLong_SHIFT ;
40414021 assert (carry <= PyLong_MASK );
40424022 }
4043- /* The final carry fits in a digit, so no masking is needed. */
4044- * pz = (digit )carry ;
40454023 assert ((carry >> PyLong_SHIFT ) == 0 );
4024+ * pz = (digit )carry ;
40464025 }
40474026 }
40484027 return long_normalize (z );
0 commit comments