summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2024-02-21 10:55:15 -0800
committerGitHub <noreply@github.com>2024-02-21 10:55:15 -0800
commit30828d4144c3bce2b2547dff3660826fbd7c307b (patch)
treeba0a5a5a36814ba774577330b05c459f4e77cd95
parent1441bcbb33a5354432daf1edc4bc3a72d0bd7687 (diff)
downloadbinaryen-30828d4144c3bce2b2547dff3660826fbd7c307b.tar.gz
binaryen-30828d4144c3bce2b2547dff3660826fbd7c307b.tar.bz2
binaryen-30828d4144c3bce2b2547dff3660826fbd7c307b.zip
[NFC] DeNaN: Avoid calls on constants (#6326)
A constant is either fixed up immediately, or does not need a call. This makes us slightly faster in the fuzzer, but does not change behavior as before those calls all ended up doing nothing (as the numbers were not nans).
-rw-r--r--src/passes/DeNaN.cpp6
-rw-r--r--test/lit/passes/denan-simd.wast7
-rw-r--r--test/lit/passes/denan.wast34
3 files changed, 40 insertions, 7 deletions
diff --git a/src/passes/DeNaN.cpp b/src/passes/DeNaN.cpp
index b0bd5fb60..0251a0c58 100644
--- a/src/passes/DeNaN.cpp
+++ b/src/passes/DeNaN.cpp
@@ -58,20 +58,20 @@ struct DeNaN : public WalkerPass<
if (expr->type == Type::f32) {
if (c && c->value.isNaN()) {
replacement = builder.makeConst(float(0));
- } else {
+ } else if (!c) {
replacement = builder.makeCall(deNan32, {expr}, Type::f32);
}
} else if (expr->type == Type::f64) {
if (c && c->value.isNaN()) {
replacement = builder.makeConst(double(0));
- } else {
+ } else if (!c) {
replacement = builder.makeCall(deNan64, {expr}, Type::f64);
}
} else if (expr->type == Type::v128) {
if (c && hasNaNLane(c)) {
uint8_t zero[16] = {};
replacement = builder.makeConst(Literal(zero));
- } else {
+ } else if (!c) {
replacement = builder.makeCall(deNan128, {expr}, Type::v128);
}
}
diff --git a/test/lit/passes/denan-simd.wast b/test/lit/passes/denan-simd.wast
index 3ab4e9120..6508b36eb 100644
--- a/test/lit/passes/denan-simd.wast
+++ b/test/lit/passes/denan-simd.wast
@@ -16,9 +16,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (call $deNan128
- ;; CHECK-NEXT: (v128.const i32x4 0x00000001 0x00000002 0x00000003 0x00000004)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (v128.const i32x4 0x00000001 0x00000002 0x00000003 0x00000004)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
@@ -35,7 +33,7 @@
(func $foo128 (param $x v128) (result v128)
;; The incoming param will be de-naned.
- ;; This is not a NaN. (We do still emit a call for it atm, FIXME)
+ ;; This is not a NaN.
(drop
(v128.const i32x4 0x00000001 0x00000002 0x00000003 0x00000004)
)
@@ -48,6 +46,7 @@
(v128.const i32x4 0x00000001 0xffffffff 0x00000003 0x00000004)
)
+ ;; The result here will be de-naned.
(call $foo128 (local.get $x))
)
)
diff --git a/test/lit/passes/denan.wast b/test/lit/passes/denan.wast
index 7baabc369..bc42ab04e 100644
--- a/test/lit/passes/denan.wast
+++ b/test/lit/passes/denan.wast
@@ -12,6 +12,8 @@
;; CHECK: (type $3 (func (param f32 f64)))
+ ;; CHECK: (type $4 (func))
+
;; CHECK: (global $global$1 (mut f32) (f32.const 0))
(global $global$1 (mut f32) (f32.const nan))
;; CHECK: (global $global$2 (mut f32) (f32.const 12.34000015258789))
@@ -139,6 +141,38 @@
(drop (local.get $f))
(drop (local.get $d))
)
+
+ ;; CHECK: (func $constants
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (f32.const 12.34000015258789)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (f32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (f64.const 12.34)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (f64.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $constants
+ ;; Constants can be fixed up or left alone - we never need to add a call on
+ ;; them.
+ (drop
+ (f32.const 12.34)
+ )
+ (drop
+ (f32.const nan)
+ )
+ (drop
+ (f64.const 12.34)
+ )
+ (drop
+ (f64.const nan)
+ )
+ )
+
;; CHECK: (func $tees (param $x f32) (result f32)
;; CHECK-NEXT: (local.set $x
;; CHECK-NEXT: (call $deNan32