From 4a8e1be495054b13204f49f985332e56492afaf2 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Fri, 5 Jun 2026 16:17:09 -0700 Subject: [PATCH] JIT/wasm: don't mark CORINFO_HELP_GETREFANY pure on wasm The wasm ABI passes any struct without a single scalar lowering by implicit byref (WasmClassifier::Classify -> passByRef = true for CORINFO_WASM_TYPE_VOID). TypedReference is two pointers and has no scalar lowering, so its struct arg to GETREFANY is implicit byref -- the same situation as win-x64 that #80292 already guarded against. Marking the helper pure in this case violates the contract enforced by fgValueNumberHelperCallFunc's default branch and trips: Assertion failed '!arg.AbiInfo.IsPassedByReference() && "Helpers taking implicit byref arguments should not be marked as pure"' in 'JitTest_array2_refany_il.Test:TestRef(System.TypedReference)' during 'Do value numbering' (valuenum.cpp:14328) Affects refanyval users JIT/Methodical/refany/array2_{d,r} and array3_{d,r}. Fix: exclude TARGET_WASM from the pure-marking guard alongside WINDOWS_AMD64_ABI, and expand the comment so future ports know to re-evaluate. Other FEATURE_IMPLICIT_BYREFS targets (arm64, riscv64, loongarch64) pass the 16-byte aggregate in two registers and are not affected. Verified: with the fix, crossgen2 emits array2_d.wasm and array3_r.wasm successfully (no assert), and both tests pass at runtime under R2R. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/coreclr/jit/utils.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index 3f3b49dc55b933..86300e47383b0f 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -1596,9 +1596,12 @@ void HelperCallProperties::init() break; // GETREFANY is pure up to the value of the struct argument. We - // only support that when it is not an implicit byref. + // only support that when it is not an implicit byref. The + // TypedReference struct (two pointers) is passed by implicit + // byref on win-x64 and on wasm (the wasm ABI passes any struct + // without a single scalar lowering by reference). case CORINFO_HELP_GETREFANY: -#ifndef WINDOWS_AMD64_ABI +#if !defined(WINDOWS_AMD64_ABI) && !defined(TARGET_WASM) isPure = true; #endif break;