Skip to content
Snippets Groups Projects
Unverified Commit d6b1a36e authored by Sam Yates's avatar Sam Yates Committed by GitHub
Browse files

Replace `isnan()` with fp equality test in neon code (#925)

* Replace serialized isnan(x) calls with cmp_eq(x,x) (changing sense of associated tests accordingly).
parent 599be0d6
No related branches found
No related tags found
No related merge requests found
...@@ -395,12 +395,7 @@ struct neon_double2 : implbase<neon_double2> { ...@@ -395,12 +395,7 @@ struct neon_double2 : implbase<neon_double2> {
auto is_large = cmp_gt(x, broadcast(exp_maxarg)); auto is_large = cmp_gt(x, broadcast(exp_maxarg));
auto is_small = cmp_lt(x, broadcast(exp_minarg)); auto is_small = cmp_lt(x, broadcast(exp_minarg));
auto is_not_nan = cmp_eq(x, x);
bool a[2];
a[0] = isnan(vgetq_lane_f64(x, 0)) == 0 ? 0 : 1;
a[1] = isnan(vgetq_lane_f64(x, 1)) == 0 ? 0 : 1;
auto is_nan = mask_copy_from(a);
// Compute n and g. // Compute n and g.
...@@ -430,7 +425,7 @@ struct neon_double2 : implbase<neon_double2> { ...@@ -430,7 +425,7 @@ struct neon_double2 : implbase<neon_double2> {
return ifelse(is_large, broadcast(HUGE_VAL), return ifelse(is_large, broadcast(HUGE_VAL),
ifelse(is_small, broadcast(0), ifelse(is_small, broadcast(0),
ifelse(is_nan, broadcast(NAN), result))); ifelse(is_not_nan, result, broadcast(NAN))));
} }
// Use same rational polynomial expansion as for exp(x), without // Use same rational polynomial expansion as for exp(x), without
...@@ -443,12 +438,7 @@ struct neon_double2 : implbase<neon_double2> { ...@@ -443,12 +438,7 @@ struct neon_double2 : implbase<neon_double2> {
static float64x2_t expm1(const float64x2_t& x) { static float64x2_t expm1(const float64x2_t& x) {
auto is_large = cmp_gt(x, broadcast(exp_maxarg)); auto is_large = cmp_gt(x, broadcast(exp_maxarg));
auto is_small = cmp_lt(x, broadcast(expm1_minarg)); auto is_small = cmp_lt(x, broadcast(expm1_minarg));
auto is_not_nan = cmp_eq(x, x);
bool a[2];
a[0] = isnan(vgetq_lane_f64(x, 0)) == 0 ? 0 : 1;
a[1] = isnan(vgetq_lane_f64(x, 1)) == 0 ? 0 : 1;
auto is_nan = mask_copy_from(a);
auto half = broadcast(0.5); auto half = broadcast(0.5);
auto one = broadcast(1.); auto one = broadcast(1.);
...@@ -484,9 +474,7 @@ struct neon_double2 : implbase<neon_double2> { ...@@ -484,9 +474,7 @@ struct neon_double2 : implbase<neon_double2> {
return ifelse(is_large, broadcast(HUGE_VAL), return ifelse(is_large, broadcast(HUGE_VAL),
ifelse(is_small, broadcast(-1), ifelse(is_small, broadcast(-1),
ifelse(is_nan, broadcast(NAN), ifelse(is_not_nan, ifelse(nzero, expgm1, scaled), broadcast(NAN))));
ifelse(nzero, expgm1, scaled))));
}
// Natural logarithm: // Natural logarithm:
// //
...@@ -514,11 +502,7 @@ struct neon_double2 : implbase<neon_double2> { ...@@ -514,11 +502,7 @@ struct neon_double2 : implbase<neon_double2> {
auto is_small = cmp_lt(x, broadcast(log_minarg)); auto is_small = cmp_lt(x, broadcast(log_minarg));
auto is_domainerr = cmp_lt(x, broadcast(0)); auto is_domainerr = cmp_lt(x, broadcast(0));
bool a[2]; auto is_nan = logical_not(cmp_eq(x, x));
a[0] = isnan(vgetq_lane_f64(x, 0)) == 0 ? 0 : 1;
a[1] = isnan(vgetq_lane_f64(x, 0)) == 0 ? 0 : 1;
auto is_nan = mask_copy_from(a);
is_domainerr = logical_or(is_nan, is_domainerr); is_domainerr = logical_or(is_nan, is_domainerr);
float64x2_t g = vcvt_f64_f32(vcvt_f32_s32(logb_normal(x))); float64x2_t g = vcvt_f64_f32(vcvt_f32_s32(logb_normal(x)));
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment