optimize global.gets
diff --git a/src/passes/ConstantFieldPropagation.cpp b/src/passes/ConstantFieldPropagation.cpp
index 5689f52..8bed4f8 100644
--- a/src/passes/ConstantFieldPropagation.cpp
+++ b/src/passes/ConstantFieldPropagation.cpp
@@ -580,6 +580,13 @@
       }
 
       return structInference;
+    } else if (auto* get = curr->dynCast<GlobalGet>()) {
+      // If a global is immutable, we can use information about its value,
+      // including even a precise type since it likely is a struct.new.
+      auto* global = getModule()->getGlobal(get->name);
+      if (!global->mutable_) {
+        return inferType(global->init);
+      }
     }
 
     // We didn't manage to do any better than the declared type.
diff --git a/test/lit/passes/cfp_local.wast b/test/lit/passes/cfp_local.wast
index aa25108..46e8e0b 100644
--- a/test/lit/passes/cfp_local.wast
+++ b/test/lit/passes/cfp_local.wast
@@ -1486,12 +1486,11 @@
 ;; As before, but the vtables are in immutable globals.
 (module
   ;; A function type that receives |this| and returns an i32.
-  ;; CHECK:      (type $parent (struct (field (ref $parent.vtable))))
-
   ;; CHECK:      (type $func (func (param anyref) (result i32)))
   (type $func (func (param anyref) (result i32)))
 
   ;; A parent struct type, with a vtable.
+  ;; CHECK:      (type $parent (struct (field (ref $parent.vtable))))
   (type $parent (struct (field (ref $parent.vtable))))
 
   ;; CHECK:      (type $parent.vtable (struct (field (ref $func))))
@@ -1602,18 +1601,28 @@
   ;; CHECK-NEXT:  (i32.add
   ;; CHECK-NEXT:   (call_ref
   ;; CHECK-NEXT:    (local.get $x)
-  ;; CHECK-NEXT:    (struct.get $parent.vtable 0
-  ;; CHECK-NEXT:     (struct.get $parent 0
-  ;; CHECK-NEXT:      (local.get $x)
+  ;; CHECK-NEXT:    (block (result (ref $func))
+  ;; CHECK-NEXT:     (drop
+  ;; CHECK-NEXT:      (ref.as_non_null
+  ;; CHECK-NEXT:       (struct.get $parent 0
+  ;; CHECK-NEXT:        (local.get $x)
+  ;; CHECK-NEXT:       )
+  ;; CHECK-NEXT:      )
   ;; CHECK-NEXT:     )
+  ;; CHECK-NEXT:     (ref.func $parent.func)
   ;; CHECK-NEXT:    )
   ;; CHECK-NEXT:   )
   ;; CHECK-NEXT:   (call_ref
   ;; CHECK-NEXT:    (local.get $x)
-  ;; CHECK-NEXT:    (struct.get $parent.vtable 0
-  ;; CHECK-NEXT:     (struct.get $parent 0
-  ;; CHECK-NEXT:      (local.get $x)
+  ;; CHECK-NEXT:    (block (result (ref $func))
+  ;; CHECK-NEXT:     (drop
+  ;; CHECK-NEXT:      (ref.as_non_null
+  ;; CHECK-NEXT:       (struct.get $parent 0
+  ;; CHECK-NEXT:        (local.get $x)
+  ;; CHECK-NEXT:       )
+  ;; CHECK-NEXT:      )
   ;; CHECK-NEXT:     )
+  ;; CHECK-NEXT:     (ref.func $parent.func)
   ;; CHECK-NEXT:    )
   ;; CHECK-NEXT:   )
   ;; CHECK-NEXT:  )