@@ -1210,20 +1210,30 @@ func (z *Float) uadd(x, y *Float) {
1210
1210
ex := int64 (x .exp ) - int64 (len (x .mant ))* _W
1211
1211
ey := int64 (y .exp ) - int64 (len (y .mant ))* _W
1212
1212
1213
+ al := alias (z .mant , x .mant ) || alias (z .mant , y .mant )
1214
+
1213
1215
// TODO(gri) having a combined add-and-shift primitive
1214
1216
// could make this code significantly faster
1215
1217
switch {
1216
1218
case ex < ey :
1217
- // cannot re-use z.mant w/o testing for aliasing
1218
- t := nat (nil ).shl (y .mant , uint (ey - ex ))
1219
- z .mant = z .mant .add (x .mant , t )
1219
+ if al {
1220
+ t := nat (nil ).shl (y .mant , uint (ey - ex ))
1221
+ z .mant = z .mant .add (x .mant , t )
1222
+ } else {
1223
+ z .mant = z .mant .shl (y .mant , uint (ey - ex ))
1224
+ z .mant = z .mant .add (x .mant , z .mant )
1225
+ }
1220
1226
default :
1221
1227
// ex == ey, no shift needed
1222
1228
z .mant = z .mant .add (x .mant , y .mant )
1223
1229
case ex > ey :
1224
- // cannot re-use z.mant w/o testing for aliasing
1225
- t := nat (nil ).shl (x .mant , uint (ex - ey ))
1226
- z .mant = z .mant .add (t , y .mant )
1230
+ if al {
1231
+ t := nat (nil ).shl (x .mant , uint (ex - ey ))
1232
+ z .mant = z .mant .add (t , y .mant )
1233
+ } else {
1234
+ z .mant = z .mant .shl (x .mant , uint (ex - ey ))
1235
+ z .mant = z .mant .add (z .mant , y .mant )
1236
+ }
1227
1237
ex = ey
1228
1238
}
1229
1239
// len(z.mant) > 0
@@ -1247,18 +1257,28 @@ func (z *Float) usub(x, y *Float) {
1247
1257
ex := int64 (x .exp ) - int64 (len (x .mant ))* _W
1248
1258
ey := int64 (y .exp ) - int64 (len (y .mant ))* _W
1249
1259
1260
+ al := alias (z .mant , x .mant ) || alias (z .mant , y .mant )
1261
+
1250
1262
switch {
1251
1263
case ex < ey :
1252
- // cannot re-use z.mant w/o testing for aliasing
1253
- t := nat (nil ).shl (y .mant , uint (ey - ex ))
1254
- z .mant = t .sub (x .mant , t )
1264
+ if al {
1265
+ t := nat (nil ).shl (y .mant , uint (ey - ex ))
1266
+ z .mant = t .sub (x .mant , t )
1267
+ } else {
1268
+ z .mant = z .mant .shl (y .mant , uint (ey - ex ))
1269
+ z .mant = z .mant .sub (x .mant , z .mant )
1270
+ }
1255
1271
default :
1256
1272
// ex == ey, no shift needed
1257
1273
z .mant = z .mant .sub (x .mant , y .mant )
1258
1274
case ex > ey :
1259
- // cannot re-use z.mant w/o testing for aliasing
1260
- t := nat (nil ).shl (x .mant , uint (ex - ey ))
1261
- z .mant = t .sub (t , y .mant )
1275
+ if al {
1276
+ t := nat (nil ).shl (x .mant , uint (ex - ey ))
1277
+ z .mant = t .sub (t , y .mant )
1278
+ } else {
1279
+ z .mant = z .mant .shl (x .mant , uint (ex - ey ))
1280
+ z .mant = z .mant .sub (z .mant , y .mant )
1281
+ }
1262
1282
ex = ey
1263
1283
}
1264
1284
0 commit comments