Skip to content

Commit 7b7e13b

Browse files
MaxGraeydcodeIO
authored andcommitted
Fix fast path for Math.pow (#1055)
(-0) ** 0.5 should be 0 instead of -0
1 parent 38362a8 commit 7b7e13b

12 files changed

+1893
-2409
lines changed

std/assembly/math.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,13 +1182,15 @@ export namespace NativeMath {
11821182
export function pow(x: f64, y: f64): f64 { // see: musl/src/math/pow.c and SUN COPYRIGHT NOTICE above
11831183
// TODO: remove this fast pathes after introduced own mid-end IR with "stdlib call simplify" transforms
11841184
if (builtin_abs<f64>(y) <= 2) {
1185-
if (y == 2.0) return x * x;
1186-
if (y == 0.5) return select<f64>(Infinity, builtin_sqrt<f64>(x), builtin_abs<f64>(x) == Infinity);
1187-
if (y == -1.0) return 1 / x;
1188-
if (y == -0.5) {
1189-
if (x == 0.0) return Infinity;
1190-
return select<f64>(0, 1 / builtin_sqrt<f64>(x), builtin_abs<f64>(x) == Infinity);
1185+
if (y == 2.0) return x * x;
1186+
if (y == 0.5) {
1187+
return select<f64>(
1188+
builtin_abs<f64>(builtin_sqrt<f64>(x)),
1189+
Infinity,
1190+
x != -Infinity
1191+
);
11911192
}
1193+
if (y == -1.0) return 1 / x;
11921194
if (y == 1.0) return x;
11931195
if (y == 0.0) return 1.0;
11941196
}
@@ -2578,13 +2580,15 @@ export namespace NativeMathf {
25782580
export function pow(x: f32, y: f32): f32 { // see: musl/src/math/powf.c and SUN COPYRIGHT NOTICE above
25792581
// TODO: remove this fast pathes after introduced own mid-end IR with "stdlib call simplify" transforms
25802582
if (builtin_abs<f32>(y) <= 2) {
2581-
if (y == 2.0) return x * x;
2582-
if (y == 0.5) return select<f32>(Infinity, builtin_sqrt<f32>(x), builtin_abs<f32>(x) == Infinity);
2583-
if (y == -1.0) return 1 / x;
2584-
if (y == -0.5) {
2585-
if (x == 0.0) return Infinity;
2586-
return select<f32>(0, 1 / builtin_sqrt<f32>(x), builtin_abs<f32>(x) == Infinity);
2583+
if (y == 2.0) return x * x;
2584+
if (y == 0.5) {
2585+
return select<f32>(
2586+
builtin_abs<f32>(builtin_sqrt<f32>(x)),
2587+
Infinity,
2588+
x != -Infinity
2589+
);
25872590
}
2591+
if (y == -1.0) return 1 / x;
25882592
if (y == 1.0) return x;
25892593
if (y == 0.0) return 1.0;
25902594
}

tests/compiler/binary.untouched.wat

Lines changed: 8 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,14 @@
9292
f64.const 0.5
9393
f64.eq
9494
if
95-
f64.const inf
9695
local.get $0
9796
f64.sqrt
98-
local.get $0
9997
f64.abs
10098
f64.const inf
101-
f64.eq
99+
local.get $0
100+
f64.const inf
101+
f64.neg
102+
f64.ne
102103
select
103104
return
104105
end
@@ -112,29 +113,6 @@
112113
return
113114
end
114115
local.get $1
115-
f64.const -0.5
116-
f64.eq
117-
if
118-
local.get $0
119-
f64.const 0
120-
f64.eq
121-
if
122-
f64.const inf
123-
return
124-
end
125-
f64.const 0
126-
f64.const 1
127-
local.get $0
128-
f64.sqrt
129-
f64.div
130-
local.get $0
131-
f64.abs
132-
f64.const inf
133-
f64.eq
134-
select
135-
return
136-
end
137-
local.get $1
138116
f64.const 1
139117
f64.eq
140118
if
@@ -1311,13 +1289,14 @@
13111289
f32.const 0.5
13121290
f32.eq
13131291
if
1314-
f32.const inf
13151292
local.get $0
13161293
f32.sqrt
1317-
local.get $0
13181294
f32.abs
13191295
f32.const inf
1320-
f32.eq
1296+
local.get $0
1297+
f32.const inf
1298+
f32.neg
1299+
f32.ne
13211300
select
13221301
return
13231302
end
@@ -1331,29 +1310,6 @@
13311310
return
13321311
end
13331312
local.get $1
1334-
f32.const -0.5
1335-
f32.eq
1336-
if
1337-
local.get $0
1338-
f32.const 0
1339-
f32.eq
1340-
if
1341-
f32.const inf
1342-
return
1343-
end
1344-
f32.const 0
1345-
f32.const 1
1346-
local.get $0
1347-
f32.sqrt
1348-
f32.div
1349-
local.get $0
1350-
f32.abs
1351-
f32.const inf
1352-
f32.eq
1353-
select
1354-
return
1355-
end
1356-
local.get $1
13571313
f32.const 1
13581314
f32.eq
13591315
if

tests/compiler/resolve-binary.untouched.wat

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -739,13 +739,14 @@
739739
f64.const 0.5
740740
f64.eq
741741
if
742-
f64.const inf
743742
local.get $0
744743
f64.sqrt
745-
local.get $0
746744
f64.abs
747745
f64.const inf
748-
f64.eq
746+
local.get $0
747+
f64.const inf
748+
f64.neg
749+
f64.ne
749750
select
750751
return
751752
end
@@ -759,29 +760,6 @@
759760
return
760761
end
761762
local.get $1
762-
f64.const -0.5
763-
f64.eq
764-
if
765-
local.get $0
766-
f64.const 0
767-
f64.eq
768-
if
769-
f64.const inf
770-
return
771-
end
772-
f64.const 0
773-
f64.const 1
774-
local.get $0
775-
f64.sqrt
776-
f64.div
777-
local.get $0
778-
f64.abs
779-
f64.const inf
780-
f64.eq
781-
select
782-
return
783-
end
784-
local.get $1
785763
f64.const 1
786764
f64.eq
787765
if

tests/compiler/std/array.optimized.wat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4667,7 +4667,7 @@
46674667
if
46684668
i32.const 0
46694669
i32.const 4080
4670-
i32.const 1404
4670+
i32.const 1406
46714671
i32.const 4
46724672
call $~lib/builtins/abort
46734673
unreachable
@@ -6128,7 +6128,7 @@
61286128
if
61296129
i32.const 4912
61306130
i32.const 4080
6131-
i32.const 1411
6131+
i32.const 1413
61326132
i32.const 24
61336133
call $~lib/builtins/abort
61346134
unreachable

tests/compiler/std/array.untouched.wat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7517,7 +7517,7 @@
75177517
if
75187518
i32.const 0
75197519
i32.const 4080
7520-
i32.const 1404
7520+
i32.const 1406
75217521
i32.const 4
75227522
call $~lib/builtins/abort
75237523
unreachable
@@ -9781,7 +9781,7 @@
97819781
if
97829782
i32.const 4912
97839783
i32.const 4080
9784-
i32.const 1411
9784+
i32.const 1413
97859785
i32.const 24
97869786
call $~lib/builtins/abort
97879787
unreachable

tests/compiler/std/libm.optimized.wat

Lines changed: 6 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3473,13 +3473,13 @@
34733473
f64.const 0.5
34743474
f64.eq
34753475
if
3476-
f64.const inf
34773476
local.get $0
34783477
f64.sqrt
3479-
local.get $0
34803478
f64.abs
34813479
f64.const inf
3482-
f64.eq
3480+
local.get $0
3481+
f64.const -inf
3482+
f64.ne
34833483
select
34843484
return
34853485
end
@@ -3493,29 +3493,6 @@
34933493
return
34943494
end
34953495
local.get $1
3496-
f64.const -0.5
3497-
f64.eq
3498-
if
3499-
local.get $0
3500-
f64.const 0
3501-
f64.eq
3502-
if
3503-
f64.const inf
3504-
return
3505-
end
3506-
f64.const 0
3507-
f64.const 1
3508-
local.get $0
3509-
f64.sqrt
3510-
f64.div
3511-
local.get $0
3512-
f64.abs
3513-
f64.const inf
3514-
f64.eq
3515-
select
3516-
return
3517-
end
3518-
local.get $1
35193496
f64.const 1
35203497
f64.eq
35213498
if
@@ -7833,13 +7810,13 @@
78337810
f32.const 0.5
78347811
f32.eq
78357812
if
7836-
f32.const inf
78377813
local.get $0
78387814
f32.sqrt
7839-
local.get $0
78407815
f32.abs
78417816
f32.const inf
7842-
f32.eq
7817+
local.get $0
7818+
f32.const -inf
7819+
f32.ne
78437820
select
78447821
return
78457822
end
@@ -7853,29 +7830,6 @@
78537830
return
78547831
end
78557832
local.get $1
7856-
f32.const -0.5
7857-
f32.eq
7858-
if
7859-
local.get $0
7860-
f32.const 0
7861-
f32.eq
7862-
if
7863-
f32.const inf
7864-
return
7865-
end
7866-
f32.const 0
7867-
f32.const 1
7868-
local.get $0
7869-
f32.sqrt
7870-
f32.div
7871-
local.get $0
7872-
f32.abs
7873-
f32.const inf
7874-
f32.eq
7875-
select
7876-
return
7877-
end
7878-
local.get $1
78797833
f32.const 1
78807834
f32.eq
78817835
if

0 commit comments

Comments
 (0)