diff --git a/src/compiler.ts b/src/compiler.ts
index 59368a08fa..22246dde13 100644
--- a/src/compiler.ts
+++ b/src/compiler.ts
@@ -3495,6 +3495,28 @@ export class Compiler extends DiagnosticEmitter {
     // not dealing with references from here on
     assert(!fromType.isReference && !toType.isReference);
 
+    // Early return if we have same types
+    if (toType.kind == fromType.kind) {
+      this.currentType = toType;
+      return expr;
+    }
+
+    // v128 to any / any to v128
+    // except v128 to bool
+    //
+    // NOTE:In case we would have more conversions to and from v128 type it's better
+    // to make these checks more individual and integrate in below flow.
+    if (
+      !toType.isBooleanValue &&
+      (toType.isVectorValue || fromType.isVectorValue)
+    ) {
+      this.error(
+        DiagnosticCode.Type_0_is_not_assignable_to_type_1,
+        reportNode.range, fromType.toString(), toType.toString()
+      );
+      return module.unreachable();
+    }
+
     if (!fromType.isAssignableTo(toType)) {
       if (!explicit) {
         this.error(
diff --git a/tests/compiler/simd-errors.json b/tests/compiler/simd-errors.json
new file mode 100644
index 0000000000..9a0b2ef259
--- /dev/null
+++ b/tests/compiler/simd-errors.json
@@ -0,0 +1,10 @@
+{
+  "asc_flags": [
+    "--enable", "simd"
+  ],
+  "stderr": [
+    "TS2322: Type 'f32' is not assignable to type 'v128'.",
+    "TS2322: Type 'i32' is not assignable to type 'v128'.",
+    "EOF"
+  ]
+}
diff --git a/tests/compiler/simd-errors.ts b/tests/compiler/simd-errors.ts
new file mode 100644
index 0000000000..c2de705258
--- /dev/null
+++ b/tests/compiler/simd-errors.ts
@@ -0,0 +1,15 @@
+// f32
+{
+  let a = f32x4.splat(0);
+  let b: f32 = 0;
+  v128.add<f32>(a, b);
+}
+
+// i32
+{
+  let a: i32 = 0;
+  let b = i32x4.splat(0);
+  v128.sub<i32>(a, b);
+}
+
+ERROR("EOF");