authorgravatar for paul.verigo@gmail.comPavel Verigo <paul.verigo@gmail.com> 2024-07-22 23:22:01+02:00
committergravatar for paul.verigo@gmail.comPavel Verigo <paul.verigo@gmail.com> 2024-07-22 23:22:01+02:00
log0c6aa44bc3c0670f3533c503ad9921c2439d8e35
tree7146183792e8241eed109c763a25558c8be08f65
parenteac7fd4da5992299a1f2fb59c5aa237c0c6c6761

compiler_rt: wasm miss float exceptions


11 files changed, 33 insertions(+), 31 deletions(-)

lib/compiler_rt/ceil.zig+4-4
...@@ -48,14 +48,14 @@ pub fn ceilf(x: f32) callconv(.C) f32 {...@@ -48,14 +48,14 @@ pub fn ceilf(x: f32) callconv(.C) f32 {
48 if (u & m == 0) {48 if (u & m == 0) {
49 return x;49 return x;
50 }50 }
51 mem.doNotOptimizeAway(x + 0x1.0p120);51 if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1.0p120);
52 if (u >> 31 == 0) {52 if (u >> 31 == 0) {
53 u += m;53 u += m;
54 }54 }
55 u &= ~m;55 u &= ~m;
56 return @bitCast(u);56 return @bitCast(u);
57 } else {57 } else {
58 mem.doNotOptimizeAway(x + 0x1.0p120);58 if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1.0p120);
59 if (u >> 31 != 0) {59 if (u >> 31 != 0) {
60 return -0.0;60 return -0.0;
61 } else {61 } else {
...@@ -82,7 +82,7 @@ pub fn ceil(x: f64) callconv(.C) f64 {...@@ -82,7 +82,7 @@ pub fn ceil(x: f64) callconv(.C) f64 {
82 }82 }
8383
84 if (e <= 0x3FF - 1) {84 if (e <= 0x3FF - 1) {
85 mem.doNotOptimizeAway(y);85 if (common.want_float_exceptions) mem.doNotOptimizeAway(y);
86 if (u >> 63 != 0) {86 if (u >> 63 != 0) {
87 return -0.0;87 return -0.0;
88 } else {88 } else {
...@@ -116,7 +116,7 @@ pub fn ceilq(x: f128) callconv(.C) f128 {...@@ -116,7 +116,7 @@ pub fn ceilq(x: f128) callconv(.C) f128 {
116 }116 }
117117
118 if (e <= 0x3FFF - 1) {118 if (e <= 0x3FFF - 1) {
119 mem.doNotOptimizeAway(y);119 if (common.want_float_exceptions) mem.doNotOptimizeAway(y);
120 if (u >> 127 != 0) {120 if (u >> 127 != 0) {
121 return -0.0;121 return -0.0;
122 } else {122 } else {
lib/compiler_rt/common.zig+2
...@@ -24,6 +24,8 @@ pub const want_aeabi = switch (builtin.abi) {...@@ -24,6 +24,8 @@ pub const want_aeabi = switch (builtin.abi) {
24};24};
25pub const want_ppc_abi = builtin.cpu.arch.isPPC() or builtin.cpu.arch.isPPC64();25pub const want_ppc_abi = builtin.cpu.arch.isPPC() or builtin.cpu.arch.isPPC64();
2626
27pub const want_float_exceptions = !builtin.cpu.arch.isWasm();
28
27// Libcalls that involve u128 on Windows x86-64 are expected by LLVM to use the29// Libcalls that involve u128 on Windows x86-64 are expected by LLVM to use the
28// calling convention of @Vector(2, u64), rather than what's standard.30// calling convention of @Vector(2, u64), rather than what's standard.
29pub const want_windows_v2u64_abi = builtin.os.tag == .windows and builtin.cpu.arch == .x86_64 and @import("builtin").object_format != .c;31pub const want_windows_v2u64_abi = builtin.os.tag == .windows and builtin.cpu.arch == .x86_64 and @import("builtin").object_format != .c;
lib/compiler_rt/cos.zig+2-2
...@@ -41,7 +41,7 @@ pub fn cosf(x: f32) callconv(.C) f32 {...@@ -41,7 +41,7 @@ pub fn cosf(x: f32) callconv(.C) f32 {
41 if (ix <= 0x3f490fda) { // |x| ~<= pi/441 if (ix <= 0x3f490fda) { // |x| ~<= pi/4
42 if (ix < 0x39800000) { // |x| < 2**-1242 if (ix < 0x39800000) { // |x| < 2**-12
43 // raise inexact if x != 043 // raise inexact if x != 0
44 mem.doNotOptimizeAway(x + 0x1p120);44 if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120);
45 return 1.0;45 return 1.0;
46 }46 }
47 return trig.__cosdf(x);47 return trig.__cosdf(x);
...@@ -92,7 +92,7 @@ pub fn cos(x: f64) callconv(.C) f64 {...@@ -92,7 +92,7 @@ pub fn cos(x: f64) callconv(.C) f64 {
92 if (ix <= 0x3fe921fb) {92 if (ix <= 0x3fe921fb) {
93 if (ix < 0x3e46a09e) { // |x| < 2**-27 * sqrt(2)93 if (ix < 0x3e46a09e) { // |x| < 2**-27 * sqrt(2)
94 // raise inexact if x!=094 // raise inexact if x!=0
95 mem.doNotOptimizeAway(x + 0x1p120);95 if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120);
96 return 1.0;96 return 1.0;
97 }97 }
98 return trig.__cos(x, 0);98 return trig.__cos(x, 0);
lib/compiler_rt/exp.zig+4-4
...@@ -59,7 +59,7 @@ pub fn expf(x_: f32) callconv(.C) f32 {...@@ -59,7 +59,7 @@ pub fn expf(x_: f32) callconv(.C) f32 {
59 return x * 0x1.0p127;59 return x * 0x1.0p127;
60 }60 }
61 if (sign != 0) {61 if (sign != 0) {
62 mem.doNotOptimizeAway(-0x1.0p-149 / x); // overflow62 if (common.want_float_exceptions) mem.doNotOptimizeAway(-0x1.0p-149 / x); // overflow
63 // x <= -103.97208463 // x <= -103.972084
64 if (hx >= 0x42CFF1B5) {64 if (hx >= 0x42CFF1B5) {
65 return 0;65 return 0;
...@@ -91,7 +91,7 @@ pub fn expf(x_: f32) callconv(.C) f32 {...@@ -91,7 +91,7 @@ pub fn expf(x_: f32) callconv(.C) f32 {
91 hi = x;91 hi = x;
92 lo = 0;92 lo = 0;
93 } else {93 } else {
94 mem.doNotOptimizeAway(0x1.0p127 + x); // inexact94 if (common.want_float_exceptions) mem.doNotOptimizeAway(0x1.0p127 + x); // inexact
95 return 1 + x;95 return 1 + x;
96 }96 }
9797
...@@ -142,7 +142,7 @@ pub fn exp(x_: f64) callconv(.C) f64 {...@@ -142,7 +142,7 @@ pub fn exp(x_: f64) callconv(.C) f64 {
142 }142 }
143 if (x < -708.39641853226410622) {143 if (x < -708.39641853226410622) {
144 // underflow if x != -inf144 // underflow if x != -inf
145 // mem.doNotOptimizeAway(@as(f32, -0x1.0p-149 / x));145 // if (common.want_float_exceptions) mem.doNotOptimizeAway(@as(f32, -0x1.0p-149 / x));
146 if (x < -745.13321910194110842) {146 if (x < -745.13321910194110842) {
147 return 0;147 return 0;
148 }148 }
...@@ -175,7 +175,7 @@ pub fn exp(x_: f64) callconv(.C) f64 {...@@ -175,7 +175,7 @@ pub fn exp(x_: f64) callconv(.C) f64 {
175 lo = 0;175 lo = 0;
176 } else {176 } else {
177 // inexact if x != 0177 // inexact if x != 0
178 // mem.doNotOptimizeAway(0x1.0p1023 + x);178 // if (common.want_float_exceptions) mem.doNotOptimizeAway(0x1.0p1023 + x);
179 return 1 + x;179 return 1 + x;
180 }180 }
181181
lib/compiler_rt/exp2.zig+2-2
...@@ -55,7 +55,7 @@ pub fn exp2f(x: f32) callconv(.C) f32 {...@@ -55,7 +55,7 @@ pub fn exp2f(x: f32) callconv(.C) f32 {
55 // x < -12655 // x < -126
56 if (u >= 0x80000000) {56 if (u >= 0x80000000) {
57 if (u >= 0xC3160000 or u & 0x000FFFF != 0) {57 if (u >= 0xC3160000 or u & 0x000FFFF != 0) {
58 mem.doNotOptimizeAway(-0x1.0p-149 / x);58 if (common.want_float_exceptions) mem.doNotOptimizeAway(-0x1.0p-149 / x);
59 }59 }
60 // x <= -15060 // x <= -150
61 if (u >= 0x3160000) {61 if (u >= 0x3160000) {
...@@ -120,7 +120,7 @@ pub fn exp2(x: f64) callconv(.C) f64 {...@@ -120,7 +120,7 @@ pub fn exp2(x: f64) callconv(.C) f64 {
120 if (ux >> 63 != 0) {120 if (ux >> 63 != 0) {
121 // underflow121 // underflow
122 if (x <= -1075 or x - 0x1.0p52 + 0x1.0p52 != x) {122 if (x <= -1075 or x - 0x1.0p52 + 0x1.0p52 != x) {
123 mem.doNotOptimizeAway(@as(f32, @floatCast(-0x1.0p-149 / x)));123 if (common.want_float_exceptions) mem.doNotOptimizeAway(@as(f32, @floatCast(-0x1.0p-149 / x)));
124 }124 }
125 if (x <= -1075) {125 if (x <= -1075) {
126 return 0;126 return 0;
lib/compiler_rt/floor.zig+6-6
...@@ -45,13 +45,13 @@ pub fn __floorh(x: f16) callconv(.C) f16 {...@@ -45,13 +45,13 @@ pub fn __floorh(x: f16) callconv(.C) f16 {
45 if (u & m == 0) {45 if (u & m == 0) {
46 return x;46 return x;
47 }47 }
48 mem.doNotOptimizeAway(x + 0x1.0p120);48 if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1.0p120);
49 if (u >> 15 != 0) {49 if (u >> 15 != 0) {
50 u += m;50 u += m;
51 }51 }
52 return @bitCast(u & ~m);52 return @bitCast(u & ~m);
53 } else {53 } else {
54 mem.doNotOptimizeAway(x + 0x1.0p120);54 if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1.0p120);
55 if (u >> 15 == 0) {55 if (u >> 15 == 0) {
56 return 0.0;56 return 0.0;
57 } else {57 } else {
...@@ -79,13 +79,13 @@ pub fn floorf(x: f32) callconv(.C) f32 {...@@ -79,13 +79,13 @@ pub fn floorf(x: f32) callconv(.C) f32 {
79 if (u & m == 0) {79 if (u & m == 0) {
80 return x;80 return x;
81 }81 }
82 mem.doNotOptimizeAway(x + 0x1.0p120);82 if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1.0p120);
83 if (u >> 31 != 0) {83 if (u >> 31 != 0) {
84 u += m;84 u += m;
85 }85 }
86 return @bitCast(u & ~m);86 return @bitCast(u & ~m);
87 } else {87 } else {
88 mem.doNotOptimizeAway(x + 0x1.0p120);88 if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1.0p120);
89 if (u >> 31 == 0) {89 if (u >> 31 == 0) {
90 return 0.0;90 return 0.0;
91 } else {91 } else {
...@@ -112,7 +112,7 @@ pub fn floor(x: f64) callconv(.C) f64 {...@@ -112,7 +112,7 @@ pub fn floor(x: f64) callconv(.C) f64 {
112 }112 }
113113
114 if (e <= 0x3FF - 1) {114 if (e <= 0x3FF - 1) {
115 mem.doNotOptimizeAway(y);115 if (common.want_float_exceptions) mem.doNotOptimizeAway(y);
116 if (u >> 63 != 0) {116 if (u >> 63 != 0) {
117 return -1.0;117 return -1.0;
118 } else {118 } else {
...@@ -146,7 +146,7 @@ pub fn floorq(x: f128) callconv(.C) f128 {...@@ -146,7 +146,7 @@ pub fn floorq(x: f128) callconv(.C) f128 {
146 }146 }
147147
148 if (e <= 0x3FFF - 1) {148 if (e <= 0x3FFF - 1) {
149 mem.doNotOptimizeAway(y);149 if (common.want_float_exceptions) mem.doNotOptimizeAway(y);
150 if (u >> 127 != 0) {150 if (u >> 127 != 0) {
151 return -1.0;151 return -1.0;
152 } else {152 } else {
lib/compiler_rt/round.zig+3-3
...@@ -46,7 +46,7 @@ pub fn roundf(x_: f32) callconv(.C) f32 {...@@ -46,7 +46,7 @@ pub fn roundf(x_: f32) callconv(.C) f32 {
46 x = -x;46 x = -x;
47 }47 }
48 if (e < 0x7F - 1) {48 if (e < 0x7F - 1) {
49 mem.doNotOptimizeAway(x + f32_toint);49 if (common.want_float_exceptions) mem.doNotOptimizeAway(x + f32_toint);
50 return 0 * @as(f32, @bitCast(u));50 return 0 * @as(f32, @bitCast(u));
51 }51 }
5252
...@@ -81,7 +81,7 @@ pub fn round(x_: f64) callconv(.C) f64 {...@@ -81,7 +81,7 @@ pub fn round(x_: f64) callconv(.C) f64 {
81 x = -x;81 x = -x;
82 }82 }
83 if (e < 0x3ff - 1) {83 if (e < 0x3ff - 1) {
84 mem.doNotOptimizeAway(x + f64_toint);84 if (common.want_float_exceptions) mem.doNotOptimizeAway(x + f64_toint);
85 return 0 * @as(f64, @bitCast(u));85 return 0 * @as(f64, @bitCast(u));
86 }86 }
8787
...@@ -121,7 +121,7 @@ pub fn roundq(x_: f128) callconv(.C) f128 {...@@ -121,7 +121,7 @@ pub fn roundq(x_: f128) callconv(.C) f128 {
121 x = -x;121 x = -x;
122 }122 }
123 if (e < 0x3FFF - 1) {123 if (e < 0x3FFF - 1) {
124 mem.doNotOptimizeAway(x + f128_toint);124 if (common.want_float_exceptions) mem.doNotOptimizeAway(x + f128_toint);
125 return 0 * @as(f128, @bitCast(u));125 return 0 * @as(f128, @bitCast(u));
126 }126 }
127127
lib/compiler_rt/sin.zig+2-2
...@@ -49,7 +49,7 @@ pub fn sinf(x: f32) callconv(.C) f32 {...@@ -49,7 +49,7 @@ pub fn sinf(x: f32) callconv(.C) f32 {
49 if (ix <= 0x3f490fda) { // |x| ~<= pi/449 if (ix <= 0x3f490fda) { // |x| ~<= pi/4
50 if (ix < 0x39800000) { // |x| < 2**-1250 if (ix < 0x39800000) { // |x| < 2**-12
51 // raise inexact if x!=0 and underflow if subnormal51 // raise inexact if x!=0 and underflow if subnormal
52 mem.doNotOptimizeAway(if (ix < 0x00800000) x / 0x1p120 else x + 0x1p120);52 if (common.want_float_exceptions) mem.doNotOptimizeAway(if (ix < 0x00800000) x / 0x1p120 else x + 0x1p120);
53 return x;53 return x;
54 }54 }
55 return trig.__sindf(x);55 return trig.__sindf(x);
...@@ -98,7 +98,7 @@ pub fn sin(x: f64) callconv(.C) f64 {...@@ -98,7 +98,7 @@ pub fn sin(x: f64) callconv(.C) f64 {
98 if (ix <= 0x3fe921fb) {98 if (ix <= 0x3fe921fb) {
99 if (ix < 0x3e500000) { // |x| < 2**-2699 if (ix < 0x3e500000) { // |x| < 2**-26
100 // raise inexact if x != 0 and underflow if subnormal100 // raise inexact if x != 0 and underflow if subnormal
101 mem.doNotOptimizeAway(if (ix < 0x00100000) x / 0x1p120 else x + 0x1p120);101 if (common.want_float_exceptions) mem.doNotOptimizeAway(if (ix < 0x00100000) x / 0x1p120 else x + 0x1p120);
102 return x;102 return x;
103 }103 }
104 return trig.__sin(x, 0.0, 0);104 return trig.__sin(x, 0.0, 0);
lib/compiler_rt/sincos.zig+3-3
...@@ -46,7 +46,7 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.C) void {...@@ -46,7 +46,7 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.C) void {
46 // |x| < 2**-1246 // |x| < 2**-12
47 if (ix < 0x39800000) {47 if (ix < 0x39800000) {
48 // raise inexact if x!=0 and underflow if subnormal48 // raise inexact if x!=0 and underflow if subnormal
49 mem.doNotOptimizeAway(if (ix < 0x00100000) x / 0x1p120 else x + 0x1p120);49 if (common.want_float_exceptions) mem.doNotOptimizeAway(if (ix < 0x00100000) x / 0x1p120 else x + 0x1p120);
50 r_sin.* = x;50 r_sin.* = x;
51 r_cos.* = 1.0;51 r_cos.* = 1.0;
52 return;52 return;
...@@ -134,7 +134,7 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.C) void {...@@ -134,7 +134,7 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.C) void {
134 // if |x| < 2**-27 * sqrt(2)134 // if |x| < 2**-27 * sqrt(2)
135 if (ix < 0x3e46a09e) {135 if (ix < 0x3e46a09e) {
136 // raise inexact if x != 0 and underflow if subnormal136 // raise inexact if x != 0 and underflow if subnormal
137 mem.doNotOptimizeAway(if (ix < 0x00100000) x / 0x1p120 else x + 0x1p120);137 if (common.want_float_exceptions) mem.doNotOptimizeAway(if (ix < 0x00100000) x / 0x1p120 else x + 0x1p120);
138 r_sin.* = x;138 r_sin.* = x;
139 r_cos.* = 1.0;139 r_cos.* = 1.0;
140 return;140 return;
...@@ -232,7 +232,7 @@ inline fn sincos_generic(comptime F: type, x: F, r_sin: *F, r_cos: *F) void {...@@ -232,7 +232,7 @@ inline fn sincos_generic(comptime F: type, x: F, r_sin: *F, r_cos: *F) void {
232 if (se < 0x3fff - math.floatFractionalBits(F) - 1) {232 if (se < 0x3fff - math.floatFractionalBits(F) - 1) {
233 // raise underflow if subnormal233 // raise underflow if subnormal
234 if (se == 0) {234 if (se == 0) {
235 mem.doNotOptimizeAway(x * 0x1p-120);235 if (common.want_float_exceptions) mem.doNotOptimizeAway(x * 0x1p-120);
236 }236 }
237 r_sin.* = x;237 r_sin.* = x;
238 // raise inexact if x!=0238 // raise inexact if x!=0
lib/compiler_rt/tan.zig+2-2
...@@ -51,7 +51,7 @@ pub fn tanf(x: f32) callconv(.C) f32 {...@@ -51,7 +51,7 @@ pub fn tanf(x: f32) callconv(.C) f32 {
51 if (ix <= 0x3f490fda) { // |x| ~<= pi/451 if (ix <= 0x3f490fda) { // |x| ~<= pi/4
52 if (ix < 0x39800000) { // |x| < 2**-1252 if (ix < 0x39800000) { // |x| < 2**-12
53 // raise inexact if x!=0 and underflow if subnormal53 // raise inexact if x!=0 and underflow if subnormal
54 mem.doNotOptimizeAway(if (ix < 0x00800000) x / 0x1p120 else x + 0x1p120);54 if (common.want_float_exceptions) mem.doNotOptimizeAway(if (ix < 0x00800000) x / 0x1p120 else x + 0x1p120);
55 return x;55 return x;
56 }56 }
57 return kernel.__tandf(x, false);57 return kernel.__tandf(x, false);
...@@ -89,7 +89,7 @@ pub fn tan(x: f64) callconv(.C) f64 {...@@ -89,7 +89,7 @@ pub fn tan(x: f64) callconv(.C) f64 {
89 if (ix <= 0x3fe921fb) {89 if (ix <= 0x3fe921fb) {
90 if (ix < 0x3e400000) { // |x| < 2**-2790 if (ix < 0x3e400000) { // |x| < 2**-27
91 // raise inexact if x!=0 and underflow if subnormal91 // raise inexact if x!=0 and underflow if subnormal
92 mem.doNotOptimizeAway(if (ix < 0x00100000) x / 0x1p120 else x + 0x1p120);92 if (common.want_float_exceptions) mem.doNotOptimizeAway(if (ix < 0x00100000) x / 0x1p120 else x + 0x1p120);
93 return x;93 return x;
94 }94 }
95 return kernel.__tan(x, 0.0, false);95 return kernel.__tan(x, 0.0, false);
lib/compiler_rt/trunc.zig+3-3
...@@ -47,7 +47,7 @@ pub fn truncf(x: f32) callconv(.C) f32 {...@@ -47,7 +47,7 @@ pub fn truncf(x: f32) callconv(.C) f32 {
47 if (u & m == 0) {47 if (u & m == 0) {
48 return x;48 return x;
49 } else {49 } else {
50 mem.doNotOptimizeAway(x + 0x1p120);50 if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120);
51 return @bitCast(u & ~m);51 return @bitCast(u & ~m);
52 }52 }
53}53}
...@@ -68,7 +68,7 @@ pub fn trunc(x: f64) callconv(.C) f64 {...@@ -68,7 +68,7 @@ pub fn trunc(x: f64) callconv(.C) f64 {
68 if (u & m == 0) {68 if (u & m == 0) {
69 return x;69 return x;
70 } else {70 } else {
71 mem.doNotOptimizeAway(x + 0x1p120);71 if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120);
72 return @bitCast(u & ~m);72 return @bitCast(u & ~m);
73 }73 }
74}74}
...@@ -94,7 +94,7 @@ pub fn truncq(x: f128) callconv(.C) f128 {...@@ -94,7 +94,7 @@ pub fn truncq(x: f128) callconv(.C) f128 {
94 if (u & m == 0) {94 if (u & m == 0) {
95 return x;95 return x;
96 } else {96 } else {
97 mem.doNotOptimizeAway(x + 0x1p120);97 if (common.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120);
98 return @bitCast(u & ~m);98 return @bitCast(u & ~m);
99 }99 }
100}100}