From d90c4f63362b9aa94a840b0072b0a3bd0bc36898 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 28 Jan 2026 15:11:24 -0800 Subject: [PATCH 01/11] Checkpoint block stores Add insns for memory copy and fill Remove NYIs so stuff can flow through Cleanup Checkpoint Fix opcodes Fix WasmLowering.GetSignature Maybe-working codegen for zeroing a struct jit-format Remove unused local Consume operands Fix erroneous fallthrough Address PR feedback Remove dead call NotImplementedException ArrayBuilder and comment Make initblk loop work --- src/coreclr/jit/codegenwasm.cpp | 76 +++++++++++++++++++ src/coreclr/jit/emitfmtswasm.h | 1 + src/coreclr/jit/emitwasm.cpp | 21 ++++- src/coreclr/jit/gentree.cpp | 6 ++ src/coreclr/jit/gentree.h | 3 + src/coreclr/jit/instrswasm.h | 3 + src/coreclr/jit/lowerwasm.cpp | 65 +++++++++++++++- .../tools/Common/JitInterface/WasmLowering.cs | 41 ++++------ 8 files changed, 188 insertions(+), 28 deletions(-) diff --git a/src/coreclr/jit/codegenwasm.cpp b/src/coreclr/jit/codegenwasm.cpp index a23105ca5b1a1b..e61062fdb3e13d 100644 --- a/src/coreclr/jit/codegenwasm.cpp +++ b/src/coreclr/jit/codegenwasm.cpp @@ -599,6 +599,10 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) genLeaInstruction(treeNode->AsAddrMode()); break; + case GT_STORE_BLK: + genCodeForStoreBlk(treeNode->AsBlk()); + break; + case GT_MEMORYBARRIER: // No-op for single-threaded wasm. assert(!WASM_THREAD_SUPPORT); @@ -1964,6 +1968,78 @@ void CodeGen::genCompareFloat(GenTreeOp* treeNode) WasmProduceReg(treeNode); } +//------------------------------------------------------------------------ +// genCodeForStoreBlk: Produce code for a GT_STORE_BLK node. +// +// Arguments: +// tree - the node +// +void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp) +{ + assert(blkOp->OperIs(GT_STORE_BLK)); + + if (blkOp->gtBlkOpGcUnsafe) + { + GetEmitter()->emitDisableGC(); + } + bool isCopyBlk = blkOp->OperIsCopyBlkOp(); + + switch (blkOp->gtBlkOpKind) + { + case GenTreeBlk::BlkOpKindCpObjUnroll: + assert(!blkOp->gtBlkOpGcUnsafe); + genCodeForCpObj(blkOp->AsBlk()); + break; + + case GenTreeBlk::BlkOpKindLoop: + assert(!isCopyBlk); + genCodeForInitBlkLoop(blkOp); + break; + + case GenTreeBlk::BlkOpKindNativeOpcode: + genConsumeOperands(blkOp); + // Emit the size constant expected by the memory.copy and memory.fill opcodes + GetEmitter()->emitIns_I(INS_i32_const, EA_4BYTE, blkOp->Size()); + GetEmitter()->emitIns_I(isCopyBlk ? INS_memory_copy : INS_memory_fill, EA_8BYTE, /* memory index */ 0); + break; + + default: + unreached(); + } + + if (blkOp->gtBlkOpGcUnsafe) + { + GetEmitter()->emitEnableGC(); + } +} + +void CodeGen::genCodeForCpObj(GenTreeBlk* cpObjNode) +{ + NYI_WASM("genCodeForCpObj"); +} + +//------------------------------------------------------------------------ +// genCodeForInitBlkLoop - Generate code for an InitBlk using an inlined for-loop. +// It's needed for cases when size is too big to unroll and we're not allowed +// to use memset call due to atomicity requirements. +// +// Arguments: +// initBlkNode - the GT_STORE_BLK node +// +void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* blkOp) +{ + // TODO-WASM: In multi-threaded wasm we will need to generate a for loop that atomically zeroes one GC ref + // at a time. Right now we're single-threaded, so we can just use memory.fill. + assert(!WASM_THREAD_SUPPORT); + + genConsumeOperands(blkOp); + // Emit the value constant expected by the memory.fill opcode (zero) + GetEmitter()->emitIns_I(INS_i32_const, EA_4BYTE, 0); + // Emit the size constant expected by the memory.copy and memory.fill opcodes + GetEmitter()->emitIns_I(INS_i32_const, EA_4BYTE, blkOp->Size()); + GetEmitter()->emitIns_I(INS_memory_fill, EA_8BYTE, /* memory index */ 0); +} + BasicBlock* CodeGen::genCallFinally(BasicBlock* block) { assert(block->KindIs(BBJ_CALLFINALLY)); diff --git a/src/coreclr/jit/emitfmtswasm.h b/src/coreclr/jit/emitfmtswasm.h index e10b45828ba996..06b86ba1bca517 100644 --- a/src/coreclr/jit/emitfmtswasm.h +++ b/src/coreclr/jit/emitfmtswasm.h @@ -40,6 +40,7 @@ IF_DEF(F64, IS_NONE, NONE) // ( ) IF_DEF(LOCAL_DECL, IS_NONE, NONE) // IF_DEF(CALL_INDIRECT, IS_NONE, NONE) // +IF_DEF(MEMCPY, IS_NONE, NONE) // #undef IF_DEF #endif // !DEFINE_ID_OPS diff --git a/src/coreclr/jit/emitwasm.cpp b/src/coreclr/jit/emitwasm.cpp index 5f3f5df1fdf842..55ebd3cbaceed2 100644 --- a/src/coreclr/jit/emitwasm.cpp +++ b/src/coreclr/jit/emitwasm.cpp @@ -430,6 +430,12 @@ unsigned emitter::instrDesc::idCodeSize() const size += idIsCnsReloc() ? PADDED_RELOC_SIZE : SizeOfULEB128(emitGetInsSC(this)); break; } + case IF_MEMCPY: + { + size += idIsCnsReloc() ? PADDED_RELOC_SIZE : SizeOfULEB128(emitGetInsSC(this)); + size += idIsCnsReloc() ? PADDED_RELOC_SIZE : SizeOfULEB128(emitGetInsSC(this)); + break; + } default: unreached(); } @@ -651,6 +657,14 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) dst += emitOutputByte(dst, valType); break; } + case IF_MEMCPY: + { + dst += emitOutputOpcode(dst, ins); + cnsval_ssize_t constant = emitGetInsSC(id); + dst += emitOutputULEB128(dst, (uint64_t)constant); + dst += emitOutputULEB128(dst, (uint64_t)constant); + break; + } default: NYI_WASM("emitOutputInstr"); break; @@ -792,7 +806,12 @@ void emitter::emitDispIns( dispHandleIfAny(); } break; - + case IF_MEMCPY: + { + cnsval_ssize_t imm = emitGetInsSC(id); + printf(" %llu %llu", (uint64_t)imm, (uint64_t)imm); + } + break; case IF_LOCAL_DECL: { unsigned int count = emitGetLclVarDeclCount(id); diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 036014e4baaaa0..f708de8ebf4178 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -12846,6 +12846,12 @@ void Compiler::gtDispTree(GenTree* tree, printf(" (Loop)"); break; +#ifdef TARGET_WASM + case GenTreeBlk::BlkOpKindNativeOpcode: + printf(" (memory.copy|fill)"); + break; +#endif + default: unreached(); } diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index b1e84c28e55aee..8f5503a909d49f 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -8098,6 +8098,9 @@ struct GenTreeBlk : public GenTreeIndir BlkOpKindLoop, BlkOpKindUnroll, BlkOpKindUnrollMemmove, +#ifdef TARGET_WASM + BlkOpKindNativeOpcode, +#endif } gtBlkOpKind; bool gtBlkOpGcUnsafe; diff --git a/src/coreclr/jit/instrswasm.h b/src/coreclr/jit/instrswasm.h index 4b179c8566ef24..2b2a3358fa35bd 100644 --- a/src/coreclr/jit/instrswasm.h +++ b/src/coreclr/jit/instrswasm.h @@ -228,6 +228,9 @@ INST(i64_trunc_sat_f32_u, "i64.trunc_sat_f32_u", 0, IF_OPCODE, 0x05FC) INST(i64_trunc_sat_f64_s, "i64.trunc_sat_f64_s", 0, IF_OPCODE, 0x06FC) INST(i64_trunc_sat_f64_u, "i64.trunc_sat_f64_u", 0, IF_OPCODE, 0x07FC) +INST(memory_copy, "memory.copy", 0, IF_MEMCPY, 0x0AFC) +INST(memory_fill, "memory.fill", 0, IF_ULEB128, 0x0BFC) + // clang-format on #undef INST diff --git a/src/coreclr/jit/lowerwasm.cpp b/src/coreclr/jit/lowerwasm.cpp index 9f68ac04f3843b..b9353b7c4c348e 100644 --- a/src/coreclr/jit/lowerwasm.cpp +++ b/src/coreclr/jit/lowerwasm.cpp @@ -195,7 +195,63 @@ void Lowering::LowerDivOrMod(GenTreeOp* divMod) // void Lowering::LowerBlockStore(GenTreeBlk* blkNode) { - NYI_WASM("LowerBlockStore"); + GenTree* dstAddr = blkNode->Addr(); + GenTree* src = blkNode->Data(); + + if (blkNode->OperIsInitBlkOp()) + { + if (src->OperIs(GT_INIT_VAL)) + { + src->SetContained(); + src = src->AsUnOp()->gtGetOp1(); + } + + if (blkNode->IsZeroingGcPointersOnHeap()) + { + blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindLoop; + src->SetContained(); + } + else + { + // memory.fill + blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindNativeOpcode; + } + } + else + { + assert(src->OperIs(GT_IND, GT_LCL_VAR, GT_LCL_FLD)); + src->SetContained(); + + if (src->OperIs(GT_LCL_VAR)) + { + // TODO-1stClassStructs: for now we can't work with STORE_BLOCK source in register. + // TODO-WASM: Is this true for wasm as well? + const unsigned srcLclNum = src->AsLclVar()->GetLclNum(); + m_compiler->lvaSetVarDoNotEnregister(srcLclNum DEBUGARG(DoNotEnregisterReason::StoreBlkSrc)); + } + + ClassLayout* layout = blkNode->GetLayout(); + bool doCpObj = layout->HasGCPtr(); + + // CopyObj or CopyBlk + if (doCpObj) + { + // Try to use bulk copy helper + if (TryLowerBlockStoreAsGcBulkCopyCall(blkNode)) + { + return; + } + + assert(dstAddr->TypeIs(TYP_BYREF, TYP_I_IMPL)); + blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindCpObjUnroll; + } + else + { + assert(blkNode->OperIs(GT_STORE_BLK)); + // memory.copy + blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindNativeOpcode; + } + } } //------------------------------------------------------------------------ @@ -440,6 +496,13 @@ void Lowering::AfterLowerBlock() // rare, introduced in lowering only. All HIR-induced cases (such as from "gtSetEvalOrder") should // instead be ifdef-ed out for WASM. m_anyChanges = true; +#ifdef DEBUG + printf("node=="); + Compiler::printTreeID(node); + printf(" prev=="); + Compiler::printTreeID(prev); + printf("\n"); +#endif NYI_WASM("IR not in a stackified form"); } diff --git a/src/coreclr/tools/Common/JitInterface/WasmLowering.cs b/src/coreclr/tools/Common/JitInterface/WasmLowering.cs index 606c305a8a616e..5490b4e49bd851 100644 --- a/src/coreclr/tools/Common/JitInterface/WasmLowering.cs +++ b/src/coreclr/tools/Common/JitInterface/WasmLowering.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections.Generic; using System.Diagnostics; using Internal.TypeSystem; using ILCompiler.ObjectWriter; @@ -148,17 +149,8 @@ public static WasmFuncType GetSignature(MethodDesc method) returnIsVoid = true; } - int parameterCount = signature.Length; - - if (hasReturnBuffer) - { - parameterCount++; // return buffer - } - - if (!method.IsUnmanagedCallersOnly) - { - parameterCount += 2; // sp and pe - } + // Reserve space for potential implicit this, stack pointer parameter, portable entrypoint parameter, and return buffer + ArrayBuilder result = new(signature.Length + 4); if (!signature.IsStatic) { @@ -170,46 +162,43 @@ public static WasmFuncType GetSignature(MethodDesc method) } else { - parameterCount += 1; // implicit this + throw new NotImplementedException("Implicit this"); } } - Span wasmParameters = new WasmValueType[parameterCount]; - - int index = 0; - if (method.IsUnmanagedCallersOnly) // reverse P/Invoke { if (hasReturnBuffer) { - wasmParameters[index++] = pointerType; + result.Add(pointerType); } } else // managed call { - wasmParameters[0] = pointerType; // Stack pointer parameter - - // Return buffer is first after this. + result.Add(pointerType); // Stack pointer parameter if (hasThis) { - wasmParameters[index++] = pointerType; + result.Add(pointerType); } if (hasReturnBuffer) { - wasmParameters[index++] = pointerType; + result.Add(pointerType); } - - wasmParameters[wasmParameters.Length - 1] = pointerType; // PE entrypoint parameter } for (int i = explicitThis ? 1 : 0; i < signature.Length; i++) { - wasmParameters[index++] = LowerType(signature[i]); + result.Add(LowerType(signature[i])); + } + + if (!method.IsUnmanagedCallersOnly) + { + result.Add(pointerType); // PE entrypoint parameter } - WasmResultType ps = new(wasmParameters.ToArray()); + WasmResultType ps = new(result.ToArray()); WasmResultType ret = returnIsVoid ? new(Array.Empty()) : new([LowerType(loweredReturnType)]); From e90242046aad6340fb2dde4f1e3bffd932cacca4 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Thu, 19 Feb 2026 14:43:28 -0800 Subject: [PATCH 02/11] Only print stackified failure nodes when verbose --- src/coreclr/jit/lowerwasm.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/coreclr/jit/lowerwasm.cpp b/src/coreclr/jit/lowerwasm.cpp index b9353b7c4c348e..9ad4be474363c4 100644 --- a/src/coreclr/jit/lowerwasm.cpp +++ b/src/coreclr/jit/lowerwasm.cpp @@ -497,11 +497,14 @@ void Lowering::AfterLowerBlock() // instead be ifdef-ed out for WASM. m_anyChanges = true; #ifdef DEBUG - printf("node=="); - Compiler::printTreeID(node); - printf(" prev=="); - Compiler::printTreeID(prev); - printf("\n"); + if (JitTls::GetCompiler()->verbose) + { + printf("node=="); + Compiler::printTreeID(node); + printf(" prev=="); + Compiler::printTreeID(prev); + printf("\n"); + } #endif NYI_WASM("IR not in a stackified form"); } From b1935c46f9c1cd1c2b5cf08b81b7f709eef282cd Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Thu, 19 Feb 2026 15:01:48 -0800 Subject: [PATCH 03/11] Improve logging Remove else case --- src/coreclr/jit/lowerwasm.cpp | 12 ++---------- .../tools/Common/JitInterface/WasmLowering.cs | 4 ---- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/coreclr/jit/lowerwasm.cpp b/src/coreclr/jit/lowerwasm.cpp index 9ad4be474363c4..77bb29b7fb6f58 100644 --- a/src/coreclr/jit/lowerwasm.cpp +++ b/src/coreclr/jit/lowerwasm.cpp @@ -496,16 +496,8 @@ void Lowering::AfterLowerBlock() // rare, introduced in lowering only. All HIR-induced cases (such as from "gtSetEvalOrder") should // instead be ifdef-ed out for WASM. m_anyChanges = true; -#ifdef DEBUG - if (JitTls::GetCompiler()->verbose) - { - printf("node=="); - Compiler::printTreeID(node); - printf(" prev=="); - Compiler::printTreeID(prev); - printf("\n"); - } -#endif + + JITDUMP("node==[%06u] prev==[%06u]\n", Compiler::dspTreeID(node), Compiler::dspTreeID(prev)); NYI_WASM("IR not in a stackified form"); } diff --git a/src/coreclr/tools/Common/JitInterface/WasmLowering.cs b/src/coreclr/tools/Common/JitInterface/WasmLowering.cs index 5490b4e49bd851..961686f5d27c64 100644 --- a/src/coreclr/tools/Common/JitInterface/WasmLowering.cs +++ b/src/coreclr/tools/Common/JitInterface/WasmLowering.cs @@ -160,10 +160,6 @@ public static WasmFuncType GetSignature(MethodDesc method) { explicitThis = true; } - else - { - throw new NotImplementedException("Implicit this"); - } } if (method.IsUnmanagedCallersOnly) // reverse P/Invoke From b9ac6d9c31d130a4ed332bde26ac8770d00ffd52 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Thu, 19 Feb 2026 19:24:14 -0800 Subject: [PATCH 04/11] Remove gtBlkOpGcUnsafe handling --- src/coreclr/jit/codegenwasm.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/coreclr/jit/codegenwasm.cpp b/src/coreclr/jit/codegenwasm.cpp index e61062fdb3e13d..a65ad281ec07c2 100644 --- a/src/coreclr/jit/codegenwasm.cpp +++ b/src/coreclr/jit/codegenwasm.cpp @@ -1977,11 +1977,8 @@ void CodeGen::genCompareFloat(GenTreeOp* treeNode) void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp) { assert(blkOp->OperIs(GT_STORE_BLK)); + assert(!blkOp->gtBlkOpGcUnsafe); - if (blkOp->gtBlkOpGcUnsafe) - { - GetEmitter()->emitDisableGC(); - } bool isCopyBlk = blkOp->OperIsCopyBlkOp(); switch (blkOp->gtBlkOpKind) @@ -2006,11 +2003,6 @@ void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp) default: unreached(); } - - if (blkOp->gtBlkOpGcUnsafe) - { - GetEmitter()->emitEnableGC(); - } } void CodeGen::genCodeForCpObj(GenTreeBlk* cpObjNode) From 5f0e66b92186479c1cfd90f4c9e5c31933a74c67 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 20 Feb 2026 18:41:03 -0800 Subject: [PATCH 05/11] Apply suggestion from @SingleAccretion Co-authored-by: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> --- src/coreclr/jit/lowerwasm.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/jit/lowerwasm.cpp b/src/coreclr/jit/lowerwasm.cpp index 77bb29b7fb6f58..89b69d5c5eb45e 100644 --- a/src/coreclr/jit/lowerwasm.cpp +++ b/src/coreclr/jit/lowerwasm.cpp @@ -225,7 +225,6 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode) if (src->OperIs(GT_LCL_VAR)) { // TODO-1stClassStructs: for now we can't work with STORE_BLOCK source in register. - // TODO-WASM: Is this true for wasm as well? const unsigned srcLclNum = src->AsLclVar()->GetLclNum(); m_compiler->lvaSetVarDoNotEnregister(srcLclNum DEBUGARG(DoNotEnregisterReason::StoreBlkSrc)); } From a762b9e7f47a098d36e51be573f0b4bb5589e494 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 20 Feb 2026 18:41:12 -0800 Subject: [PATCH 06/11] Apply suggestion from @SingleAccretion Co-authored-by: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> --- src/coreclr/jit/codegenwasm.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/jit/codegenwasm.cpp b/src/coreclr/jit/codegenwasm.cpp index a65ad281ec07c2..efc5c2dd5a4bf7 100644 --- a/src/coreclr/jit/codegenwasm.cpp +++ b/src/coreclr/jit/codegenwasm.cpp @@ -1977,7 +1977,6 @@ void CodeGen::genCompareFloat(GenTreeOp* treeNode) void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp) { assert(blkOp->OperIs(GT_STORE_BLK)); - assert(!blkOp->gtBlkOpGcUnsafe); bool isCopyBlk = blkOp->OperIsCopyBlkOp(); From 862579812925cf70550f1bde792c331aa80a5c66 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 20 Feb 2026 18:41:21 -0800 Subject: [PATCH 07/11] Apply suggestion from @SingleAccretion Co-authored-by: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> --- src/coreclr/jit/codegenwasm.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/jit/codegenwasm.cpp b/src/coreclr/jit/codegenwasm.cpp index efc5c2dd5a4bf7..451e36dc2e3851 100644 --- a/src/coreclr/jit/codegenwasm.cpp +++ b/src/coreclr/jit/codegenwasm.cpp @@ -1983,7 +1983,6 @@ void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp) switch (blkOp->gtBlkOpKind) { case GenTreeBlk::BlkOpKindCpObjUnroll: - assert(!blkOp->gtBlkOpGcUnsafe); genCodeForCpObj(blkOp->AsBlk()); break; From ff7dea57e992e9af0a0ff92952d1f20a3801916e Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 20 Feb 2026 18:41:41 -0800 Subject: [PATCH 08/11] Apply suggestion from @SingleAccretion Co-authored-by: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> --- src/coreclr/jit/lowerwasm.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/jit/lowerwasm.cpp b/src/coreclr/jit/lowerwasm.cpp index 89b69d5c5eb45e..53a6926bd6ccf8 100644 --- a/src/coreclr/jit/lowerwasm.cpp +++ b/src/coreclr/jit/lowerwasm.cpp @@ -241,7 +241,6 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode) return; } - assert(dstAddr->TypeIs(TYP_BYREF, TYP_I_IMPL)); blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindCpObjUnroll; } else From a08dea1244a1f0aca9f0c825843ce49e987762f7 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 20 Feb 2026 20:04:03 -0800 Subject: [PATCH 09/11] Update src/coreclr/jit/codegenwasm.cpp Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/coreclr/jit/codegenwasm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/codegenwasm.cpp b/src/coreclr/jit/codegenwasm.cpp index 451e36dc2e3851..2d7e5d9459ff29 100644 --- a/src/coreclr/jit/codegenwasm.cpp +++ b/src/coreclr/jit/codegenwasm.cpp @@ -2014,7 +2014,7 @@ void CodeGen::genCodeForCpObj(GenTreeBlk* cpObjNode) // to use memset call due to atomicity requirements. // // Arguments: -// initBlkNode - the GT_STORE_BLK node +// blkOp - the GT_STORE_BLK node // void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* blkOp) { From 6c57d89566610c1751c0b21f9a88c85e77c99913 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 20 Feb 2026 18:50:03 -0800 Subject: [PATCH 10/11] Address PR feedback --- src/coreclr/jit/codegenwasm.cpp | 6 ++++-- src/coreclr/jit/emitfmtswasm.h | 2 +- src/coreclr/jit/emitwasm.cpp | 6 +++--- src/coreclr/jit/instrswasm.h | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/codegenwasm.cpp b/src/coreclr/jit/codegenwasm.cpp index 2d7e5d9459ff29..e5a96fa9d051bc 100644 --- a/src/coreclr/jit/codegenwasm.cpp +++ b/src/coreclr/jit/codegenwasm.cpp @@ -10,6 +10,8 @@ #include "regallocwasm.h" #include "fgwasm.h" +static const int LINEAR_MEMORY_INDEX = 0; + #ifdef TARGET_64BIT static const instruction INS_I_const = INS_i64_const; static const instruction INS_I_add = INS_i64_add; @@ -1995,7 +1997,7 @@ void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp) genConsumeOperands(blkOp); // Emit the size constant expected by the memory.copy and memory.fill opcodes GetEmitter()->emitIns_I(INS_i32_const, EA_4BYTE, blkOp->Size()); - GetEmitter()->emitIns_I(isCopyBlk ? INS_memory_copy : INS_memory_fill, EA_8BYTE, /* memory index */ 0); + GetEmitter()->emitIns_I(isCopyBlk ? INS_memory_copy : INS_memory_fill, EA_8BYTE, LINEAR_MEMORY_INDEX); break; default: @@ -2027,7 +2029,7 @@ void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* blkOp) GetEmitter()->emitIns_I(INS_i32_const, EA_4BYTE, 0); // Emit the size constant expected by the memory.copy and memory.fill opcodes GetEmitter()->emitIns_I(INS_i32_const, EA_4BYTE, blkOp->Size()); - GetEmitter()->emitIns_I(INS_memory_fill, EA_8BYTE, /* memory index */ 0); + GetEmitter()->emitIns_I(INS_memory_fill, EA_8BYTE, LINEAR_MEMORY_INDEX); } BasicBlock* CodeGen::genCallFinally(BasicBlock* block) diff --git a/src/coreclr/jit/emitfmtswasm.h b/src/coreclr/jit/emitfmtswasm.h index 06b86ba1bca517..70bc05f6cda22f 100644 --- a/src/coreclr/jit/emitfmtswasm.h +++ b/src/coreclr/jit/emitfmtswasm.h @@ -40,7 +40,7 @@ IF_DEF(F64, IS_NONE, NONE) // ( ) IF_DEF(LOCAL_DECL, IS_NONE, NONE) // IF_DEF(CALL_INDIRECT, IS_NONE, NONE) // -IF_DEF(MEMCPY, IS_NONE, NONE) // +IF_DEF(MEMIDX_MEMIDX, IS_NONE, NONE) // #undef IF_DEF #endif // !DEFINE_ID_OPS diff --git a/src/coreclr/jit/emitwasm.cpp b/src/coreclr/jit/emitwasm.cpp index 55ebd3cbaceed2..16e78849bdd3ba 100644 --- a/src/coreclr/jit/emitwasm.cpp +++ b/src/coreclr/jit/emitwasm.cpp @@ -430,7 +430,7 @@ unsigned emitter::instrDesc::idCodeSize() const size += idIsCnsReloc() ? PADDED_RELOC_SIZE : SizeOfULEB128(emitGetInsSC(this)); break; } - case IF_MEMCPY: + case IF_MEMIDX_MEMIDX: { size += idIsCnsReloc() ? PADDED_RELOC_SIZE : SizeOfULEB128(emitGetInsSC(this)); size += idIsCnsReloc() ? PADDED_RELOC_SIZE : SizeOfULEB128(emitGetInsSC(this)); @@ -657,7 +657,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) dst += emitOutputByte(dst, valType); break; } - case IF_MEMCPY: + case IF_MEMIDX_MEMIDX: { dst += emitOutputOpcode(dst, ins); cnsval_ssize_t constant = emitGetInsSC(id); @@ -806,7 +806,7 @@ void emitter::emitDispIns( dispHandleIfAny(); } break; - case IF_MEMCPY: + case IF_MEMIDX_MEMIDX: { cnsval_ssize_t imm = emitGetInsSC(id); printf(" %llu %llu", (uint64_t)imm, (uint64_t)imm); diff --git a/src/coreclr/jit/instrswasm.h b/src/coreclr/jit/instrswasm.h index 2b2a3358fa35bd..d3fc9c0392809d 100644 --- a/src/coreclr/jit/instrswasm.h +++ b/src/coreclr/jit/instrswasm.h @@ -228,8 +228,8 @@ INST(i64_trunc_sat_f32_u, "i64.trunc_sat_f32_u", 0, IF_OPCODE, 0x05FC) INST(i64_trunc_sat_f64_s, "i64.trunc_sat_f64_s", 0, IF_OPCODE, 0x06FC) INST(i64_trunc_sat_f64_u, "i64.trunc_sat_f64_u", 0, IF_OPCODE, 0x07FC) -INST(memory_copy, "memory.copy", 0, IF_MEMCPY, 0x0AFC) -INST(memory_fill, "memory.fill", 0, IF_ULEB128, 0x0BFC) +INST(memory_copy, "memory.copy", 0, IF_MEMIDX_MEMIDX, 0x0AFC) +INST(memory_fill, "memory.fill", 0, IF_ULEB128, 0x0BFC) // clang-format on From a24be65547e39e070c1f3dd469c307fa627673d5 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 20 Feb 2026 20:13:46 -0800 Subject: [PATCH 11/11] Update comment --- src/coreclr/jit/codegenwasm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/codegenwasm.cpp b/src/coreclr/jit/codegenwasm.cpp index e5a96fa9d051bc..f37a6d866a910a 100644 --- a/src/coreclr/jit/codegenwasm.cpp +++ b/src/coreclr/jit/codegenwasm.cpp @@ -1974,7 +1974,7 @@ void CodeGen::genCompareFloat(GenTreeOp* treeNode) // genCodeForStoreBlk: Produce code for a GT_STORE_BLK node. // // Arguments: -// tree - the node +// blkOp - the node // void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp) {