[llvm] [WebAssembly] Protect memory.fill and memory.copy from zero-length ranges. (PR #112617)

Heejin Ahn via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 23 18:31:58 PDT 2024


================
@@ -45,31 +54,57 @@ defm MEMORY_INIT_A#B :
          "memory.init\t$seg, $idx, $dest, $offset, $size",
          "memory.init\t$seg, $idx", 0x08>;
 
-let hasSideEffects = 1 in
-defm DATA_DROP :
-  BULK_I<(outs), (ins i32imm_op:$seg), (outs), (ins i32imm_op:$seg),
-         [],
-         "data.drop\t$seg", "data.drop\t$seg", 0x09>;
-
 let mayLoad = 1, mayStore = 1 in
-defm MEMORY_COPY_A#B :
+defm COPY_A#B :
   BULK_I<(outs), (ins i32imm_op:$src_idx, i32imm_op:$dst_idx,
                       rc:$dst, rc:$src, rc:$len),
          (outs), (ins i32imm_op:$src_idx, i32imm_op:$dst_idx),
-         [(wasm_memcpy (i32 imm:$src_idx), (i32 imm:$dst_idx),
-           rc:$dst, rc:$src, rc:$len
-         )],
+         [],
          "memory.copy\t$src_idx, $dst_idx, $dst, $src, $len",
          "memory.copy\t$src_idx, $dst_idx", 0x0a>;
 
 let mayStore = 1 in
-defm MEMORY_FILL_A#B :
+defm FILL_A#B :
   BULK_I<(outs), (ins i32imm_op:$idx, rc:$dst, I32:$value, rc:$size),
          (outs), (ins i32imm_op:$idx),
-         [(wasm_memset (i32 imm:$idx), rc:$dst, I32:$value, rc:$size)],
+         [],
          "memory.fill\t$idx, $dst, $value, $size",
          "memory.fill\t$idx", 0x0b>;
 }
 
-defm : BulkMemoryOps<I32, "32">;
-defm : BulkMemoryOps<I64, "64">;
+defm MEMORY_ : BulkMemoryOps<I32, "32">;
+defm MEMORY_ : BulkMemoryOps<I64, "64">;
+
+// A multiclass for defining `memcpy`/`memset` pseudo instructions. These have
+// the behavior the rest of LLVM CodeGen expects, and we lower them into code
+// sequences that include the Wasm `memory.fill` and `memory.copy` instructions
+// using custom inserters, because they introduce new control flow.
+multiclass BulkMemOps<WebAssemblyRegClass rc, string B> {
+
+let usesCustomInserter = 1, isCodeGenOnly = 1, mayLoad = 1, mayStore = 1 in
+defm CPY_A#B : I<(outs), (ins i32imm_op:$src_idx, i32imm_op:$dst_idx,
+                                 rc:$dst, rc:$src, rc:$len),
+                    (outs), (ins i32imm_op:$src_idx, i32imm_op:$dst_idx),
+                    [(wasm_memcpy (i32 imm:$src_idx), (i32 imm:$dst_idx),
+                      rc:$dst, rc:$src, rc:$len
+                    )],
+                    "", "", 0>,
----------------
aheejin wrote:

```suggestion
defm CPY_A#B : I<(outs), (ins i32imm_op:$src_idx, i32imm_op:$dst_idx,
                              rc:$dst, rc:$src, rc:$len),
                 (outs), (ins i32imm_op:$src_idx, i32imm_op:$dst_idx),
                 [(wasm_memcpy (i32 imm:$src_idx), (i32 imm:$dst_idx),
                   rc:$dst, rc:$src, rc:$len
                 )],
                 "", "", 0>,
```

https://github.com/llvm/llvm-project/pull/112617


More information about the llvm-commits mailing list