Try fixing DAE
diff --git a/src/passes/param-utils.cpp b/src/passes/param-utils.cpp
index 6861756..f4381a0 100644
--- a/src/passes/param-utils.cpp
+++ b/src/passes/param-utils.cpp
@@ -262,6 +262,19 @@
       continue;
     }
 
+    // If the parameter is not used in any of the functions, writing the
+    // constant value to it is redundant and creates a dead local set.
+    bool used = false;
+    for (auto* func : funcs) {
+      if (getUsedParams(func, module).count(i)) {
+        used = true;
+        break;
+      }
+    }
+    if (!used) {
+      continue;
+    }
+
     // Optimize: write the constant value in the function bodies, making them
     // ignore the parameter's value.
     Builder builder(*module);
diff --git a/test/lit/passes/dae-gc.wast b/test/lit/passes/dae-gc.wast
index ec0136a..b4abdd4 100644
--- a/test/lit/passes/dae-gc.wast
+++ b/test/lit/passes/dae-gc.wast
@@ -17,22 +17,15 @@
  )
  ;; CHECK:      (func $bar (type $0)
  ;; CHECK-NEXT:  (local $0 i31ref)
- ;; CHECK-NEXT:  (local.set $0
- ;; CHECK-NEXT:   (ref.i31
- ;; CHECK-NEXT:    (i32.const 1)
- ;; CHECK-NEXT:   )
- ;; CHECK-NEXT:  )
- ;; CHECK-NEXT:  (block
- ;; CHECK-NEXT:   (drop
- ;; CHECK-NEXT:    (local.tee $0
- ;; CHECK-NEXT:     (ref.i31
- ;; CHECK-NEXT:      (i32.const 2)
- ;; CHECK-NEXT:     )
+ ;; CHECK-NEXT:  (drop
+ ;; CHECK-NEXT:   (local.tee $0
+ ;; CHECK-NEXT:    (ref.i31
+ ;; CHECK-NEXT:     (i32.const 2)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
- ;; CHECK-NEXT:   (local.set $0
- ;; CHECK-NEXT:    (unreachable)
- ;; CHECK-NEXT:   )
+ ;; CHECK-NEXT:  )
+ ;; CHECK-NEXT:  (local.set $0
+ ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $bar (param $0 i31ref)
@@ -186,15 +179,7 @@
  ;; CHECK:      (func $1 (type $0)
  ;; CHECK-NEXT:  (local $0 (ref string))
  ;; CHECK-NEXT:  (local $1 (ref string))
- ;; CHECK-NEXT:  (local.set $0
- ;; CHECK-NEXT:   (string.const "929")
- ;; CHECK-NEXT:  )
- ;; CHECK-NEXT:  (block
- ;; CHECK-NEXT:   (local.set $1
- ;; CHECK-NEXT:    (string.const "310")
- ;; CHECK-NEXT:   )
- ;; CHECK-NEXT:   (nop)
- ;; CHECK-NEXT:  )
+ ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $1 (param $0 (ref string)) (param $1 (ref string))
   ;; The parameters here will be removed, and the constant values placed in the
diff --git a/test/lit/passes/dae-typessa-repeat-types.wast b/test/lit/passes/dae-typessa-repeat-types.wast
index 7072d21..a50300f 100644
--- a/test/lit/passes/dae-typessa-repeat-types.wast
+++ b/test/lit/passes/dae-typessa-repeat-types.wast
@@ -11,11 +11,11 @@
   ;; Trigger TypeSSA
   ;; CHECK:      (type $2 (func))
 
-  ;; CHECK:      (type $3 (func (result i32 (ref (exact $struct)))))
-
   ;; CHECK:      (type $array_1 (sub $array (array (mut i32))))
 
-  ;; CHECK:      (type $5 (func (result i32 (ref $struct))))
+  ;; CHECK:      (type $4 (func (result i32 (ref $struct))))
+
+  ;; CHECK:      (type $5 (func (result i32 (ref (exact $struct)))))
 
   ;; CHECK:      (global $array (ref $array) (array.new $array_1
   ;; CHECK-NEXT:  (i32.const 0)
@@ -43,15 +43,10 @@
   ;; CHECK:      (func $callee (type $2)
   ;; CHECK-NEXT:  (local $0 anyref)
   ;; CHECK-NEXT:  (tuple.drop 2
-  ;; CHECK-NEXT:   (block (type $3) (result i32 (ref (exact $struct)))
-  ;; CHECK-NEXT:    (local.set $0
-  ;; CHECK-NEXT:     (ref.null none)
-  ;; CHECK-NEXT:    )
-  ;; CHECK-NEXT:    (block (type $3) (result i32 (ref (exact $struct)))
-  ;; CHECK-NEXT:     (tuple.make 2
-  ;; CHECK-NEXT:      (i32.const 0)
-  ;; CHECK-NEXT:      (struct.new_default $struct)
-  ;; CHECK-NEXT:     )
+  ;; CHECK-NEXT:   (block (type $5) (result i32 (ref (exact $struct)))
+  ;; CHECK-NEXT:    (tuple.make 2
+  ;; CHECK-NEXT:     (i32.const 0)
+  ;; CHECK-NEXT:     (struct.new_default $struct)
   ;; CHECK-NEXT:    )
   ;; CHECK-NEXT:   )
   ;; CHECK-NEXT:  )
@@ -67,7 +62,7 @@
     )
   )
 
-  ;; CHECK:      (func $other (type $5) (result i32 (ref $struct))
+  ;; CHECK:      (func $other (type $4) (result i32 (ref $struct))
   ;; CHECK-NEXT:  (unreachable)
   ;; CHECK-NEXT: )
   (func $other (result i32 (ref $struct))
diff --git a/test/lit/passes/dae_all-features.wast b/test/lit/passes/dae_all-features.wast
index 41bcb73..5cb0f03 100644
--- a/test/lit/passes/dae_all-features.wast
+++ b/test/lit/passes/dae_all-features.wast
@@ -30,11 +30,6 @@
   (elem (i32.const 0) $a9 $c8)
   ;; CHECK:      (func $a (type $0)
   ;; CHECK-NEXT:  (local $0 i32)
-  ;; CHECK-NEXT:  (local.set $0
-  ;; CHECK-NEXT:   (i32.const 1)
-  ;; CHECK-NEXT:  )
-  ;; CHECK-NEXT:  (block
-  ;; CHECK-NEXT:  )
   ;; CHECK-NEXT: )
   (func $a (param $x i32))
   ;; CHECK:      (func $b (type $0)
@@ -45,9 +40,6 @@
   )
   ;; CHECK:      (func $a1 (type $0)
   ;; CHECK-NEXT:  (local $0 i32)
-  ;; CHECK-NEXT:  (local.set $0
-  ;; CHECK-NEXT:   (i32.const 2)
-  ;; CHECK-NEXT:  )
   ;; CHECK-NEXT:  (unreachable)
   ;; CHECK-NEXT: )
   (func $a1 (param $x i32)
@@ -112,11 +104,6 @@
   )
   ;; CHECK:      (func $a4 (type $0)
   ;; CHECK-NEXT:  (local $0 i32)
-  ;; CHECK-NEXT:  (local.set $0
-  ;; CHECK-NEXT:   (i32.const 4)
-  ;; CHECK-NEXT:  )
-  ;; CHECK-NEXT:  (block
-  ;; CHECK-NEXT:  )
   ;; CHECK-NEXT: )
   (func $a4 (param $x i32)
     ;; This function is called with one constant and one unreachable. We can
@@ -244,13 +231,8 @@
   )
   ;; CHECK:      (func $a10 (type $0)
   ;; CHECK-NEXT:  (local $0 i32)
-  ;; CHECK-NEXT:  (local.set $0
-  ;; CHECK-NEXT:   (i32.const 1)
-  ;; CHECK-NEXT:  )
-  ;; CHECK-NEXT:  (block
-  ;; CHECK-NEXT:   (call $a10)
-  ;; CHECK-NEXT:   (call $a10)
-  ;; CHECK-NEXT:  )
+  ;; CHECK-NEXT:  (call $a10)
+  ;; CHECK-NEXT:  (call $a10)
   ;; CHECK-NEXT: )
   (func $a10 (param $x i32) ;; recursion
     (call $a10 (i32.const 1))
@@ -417,9 +399,6 @@
   )
   ;; CHECK:      (func $bar (type $1) (result i32)
   ;; CHECK-NEXT:  (local $0 i32)
-  ;; CHECK-NEXT:  (local.set $0
-  ;; CHECK-NEXT:   (i32.const 0)
-  ;; CHECK-NEXT:  )
   ;; CHECK-NEXT:  (i32.const 7)
   ;; CHECK-NEXT: )
   (func $bar (param $x i32) (result i32)
@@ -436,9 +415,6 @@
 
   ;; CHECK:      (func $foo (type $T) (result i32)
   ;; CHECK-NEXT:  (local $0 i32)
-  ;; CHECK-NEXT:  (local.set $0
-  ;; CHECK-NEXT:   (i32.const 42)
-  ;; CHECK-NEXT:  )
   ;; CHECK-NEXT:  (drop
   ;; CHECK-NEXT:   (return_call_indirect $0 (type $T)
   ;; CHECK-NEXT:    (i32.const 0)
@@ -537,11 +513,6 @@
 
  ;; CHECK:      (func $0 (type $0)
  ;; CHECK-NEXT:  (local $0 i31ref)
- ;; CHECK-NEXT:  (local.set $0
- ;; CHECK-NEXT:   (ref.i31
- ;; CHECK-NEXT:    (i32.const 0)
- ;; CHECK-NEXT:   )
- ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $0 (param $x i31ref)
@@ -674,22 +645,17 @@
 
  ;; CHECK:      (func $0 (type $0)
  ;; CHECK-NEXT:  (local $0 i32)
- ;; CHECK-NEXT:  (local.set $0
- ;; CHECK-NEXT:   (i32.const 1)
- ;; CHECK-NEXT:  )
- ;; CHECK-NEXT:  (block
- ;; CHECK-NEXT:   (drop
+ ;; CHECK-NEXT:  (drop
+ ;; CHECK-NEXT:   (block
  ;; CHECK-NEXT:    (block
- ;; CHECK-NEXT:     (block
- ;; CHECK-NEXT:      (drop
- ;; CHECK-NEXT:       (i32.const 1)
- ;; CHECK-NEXT:      )
- ;; CHECK-NEXT:      (return)
+ ;; CHECK-NEXT:     (drop
+ ;; CHECK-NEXT:      (i32.const 1)
  ;; CHECK-NEXT:     )
+ ;; CHECK-NEXT:     (return)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
- ;; CHECK-NEXT:   (return)
  ;; CHECK-NEXT:  )
+ ;; CHECK-NEXT:  (return)
  ;; CHECK-NEXT: )
  (func $0 (param $0 i32) (result i32)
   ;; The returns here are nested in each other, and one is a recursive call to
@@ -840,15 +806,7 @@
  ;; CHECK-NEXT:  (local $0 i64)
  ;; CHECK-NEXT:  (local $1 i64)
  ;; CHECK-NEXT:  (local $2 v128)
- ;; CHECK-NEXT:  (local.set $0
- ;; CHECK-NEXT:   (i64.const 0)
- ;; CHECK-NEXT:  )
- ;; CHECK-NEXT:  (block
- ;; CHECK-NEXT:   (local.set $1
- ;; CHECK-NEXT:    (i64.const 0)
- ;; CHECK-NEXT:   )
- ;; CHECK-NEXT:   (unreachable)
- ;; CHECK-NEXT:  )
+ ;; CHECK-NEXT:  (unreachable)
  ;; CHECK-NEXT: )
  (func $target (param $0 i64) (param $1 v128) (param $2 i64) (result f32)
   ;; All parameters here should vanish.
diff --git a/test/lit/passes/dae_tnh.wast b/test/lit/passes/dae_tnh.wast
index 6e78283..b1f9d91 100644
--- a/test/lit/passes/dae_tnh.wast
+++ b/test/lit/passes/dae_tnh.wast
@@ -116,9 +116,6 @@
 
   ;; CHECK:      (func $target (type $0) (param $0 i32)
   ;; CHECK-NEXT:  (local $1 f64)
-  ;; CHECK-NEXT:  (local.set $1
-  ;; CHECK-NEXT:   (f64.const 4.2)
-  ;; CHECK-NEXT:  )
   ;; CHECK-NEXT:  (drop
   ;; CHECK-NEXT:   (local.get $0)
   ;; CHECK-NEXT:  )
diff --git a/test/lit/passes/signature-pruning.wast b/test/lit/passes/signature-pruning.wast
index d86e855..c2ffc51 100644
--- a/test/lit/passes/signature-pruning.wast
+++ b/test/lit/passes/signature-pruning.wast
@@ -1309,9 +1309,6 @@
 
   ;; CHECK:      (func $other (type $other)
   ;; CHECK-NEXT:  (local $0 anyref)
-  ;; CHECK-NEXT:  (local.set $0
-  ;; CHECK-NEXT:   (ref.null none)
-  ;; CHECK-NEXT:  )
   ;; CHECK-NEXT:  (nop)
   ;; CHECK-NEXT: )
   (func $other (type $other) (param anyref)