JIT: evaluate wasm localloc call args to temps - #131559
Conversation
Fixes dotnet#131557. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@adamperlin PTAL |
|
Azure Pipelines: Successfully started running 5 pipeline(s). 11 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
Pull request overview
This PR addresses a WASM-specific call-argument evaluation ordering problem when localloc (GT_LCLHEAP) appears in a call argument, ensuring the shadow stack pointer argument reflects the post-localloc stack pointer. It also adds a JIT regression test intended to detect the corruption scenario.
Changes:
- Update
CallArgs::ArgsCompleteto treatGT_LCLHEAPin arguments as requiring evaluation to a temp onTARGET_WASM. - Add a new JitBlue regression test
Runtime_131557that exercises stackalloc + subsequent frame activity to detect buffer clobbering.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/coreclr/jit/morph.cpp |
Adds WASM-specific logic in CallArgs::ArgsComplete to force GT_LCLHEAP argument evaluation into temps so the implicit shadow SP arg is correct. |
src/tests/JIT/Regression/JitBlue/Runtime_131557/Runtime_131557.cs |
Introduces a regression test for stackalloc/call interaction intended to catch shadow stack pointer mis-ordering corruption. |
|
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
adamperlin
left a comment
There was a problem hiding this comment.
LGTM overall, though I agree with Jakob's comment about unifying the ifdefs if possible. Also, I had a question about the bit pattern in the test.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
src/tests/JIT/Regression/JitBlue/Runtime_131557/Runtime_131557.cs:27
- As written, the stackalloc happens before the call (
buffer = stackalloc ...; Use(buffer, ...)), so this test may not exercise the problematic case where thelocallocis evaluated as part of argument evaluation. To make the regression robust, pass thestackallocexpression directly as the call argument.
[MethodImpl(MethodImplOptions.NoInlining)]
private static int Test()
{
byte* buffer = stackalloc byte[256];
return Use(buffer, 256);
}
src/coreclr/jit/morph.cpp:997
- The
#endifcomment doesn’t match the actual conditional block anymore: this#ifhas an#elif FEATURE_FIXED_OUT_ARGS, so the closing comment// defined(TARGET_WASM)is misleading and violates the usual “match #endif comments to the #if expression” convention in runtime C++ code.
#if defined(TARGET_WASM)
// Wasm passes the shadow stack pointer as an implicit first argument, and GT_LCLHEAP
// updates it. Arguments are pushed onto the Wasm operand stack in order, so any
// GT_LCLHEAP in an argument must be evaluated before the stack pointer is pushed.
//
const bool hasStackArgsWeCareAbout = comp->compLocallocUsed;
#elif FEATURE_FIXED_OUT_ARGS
// For Arm/x64 we only care because we can't reorder a register
// argument that uses GT_LCLHEAP. This is an optimization to
// save a check inside the below loop.
//
const bool hasStackArgsWeCareAbout = m_hasStackArgs && comp->compLocallocUsed;
#else
const bool hasStackArgsWeCareAbout = m_hasStackArgs;
#endif // defined(TARGET_WASM)
src/tests/JIT/Regression/JitBlue/Runtime_131557/Runtime_131557.cs:20
- This new regression test file is not referenced by any of the JIT Regression merged runner projects (e.g.
src/tests/JIT/Regression/Regression_o_2.csprojlists manyJitBlue\Runtime_*\*.csincludes, but does not includeRuntime_131557.cs). As a result, the test likely won’t be built or executed in CI until it’s added to the appropriateRegression_*.csprojitem list (keeping the list sorted).
public unsafe class Runtime_131557
{
private static int s_sink;
[Fact]
public static void TestEntryPoint()
{
Assert.Equal(0, Test());
}
|
/ba-g build and helix timeouts |
Fixes #131557.