summaryrefslogtreecommitdiff
path: root/src/jit
diff options
context:
space:
mode:
authorAndy Ayers <andya@microsoft.com>2020-01-14 10:36:18 -0800
committerAnirudh Agnihotry <anirudhagnihotry098@gmail.com>2020-01-14 10:36:18 -0800
commit2f99ca8652bd31755aac431dc1bff8a4dda888eb (patch)
treedb156299e8836296244968c2b06f3443c030d5cf /src/jit
parent1e0eabe8ed5ca2d5fc8fef89a60e59f5a641bb6f (diff)
downloadcoreclr-2f99ca8652bd31755aac431dc1bff8a4dda888eb.tar.gz
coreclr-2f99ca8652bd31755aac431dc1bff8a4dda888eb.tar.bz2
coreclr-2f99ca8652bd31755aac431dc1bff8a4dda888eb.zip
[release/3.1] Port fix for JIT silent bad code (#27972)
* [release/3.1] Port fix for JIT silent bad code Release/3.1 port of https://github.com/dotnet/runtime/pull/797. Fixes https://github.com/dotnet/runtime/issues/764 The jit might incorrectly order a read from a struct field with an operation that modifies the field, so that the read returns the wrong value. Silent bad code; program behaves incorrectly. Yes, introduced in the 3.0 cycle. Verified the user's test case now passes; no diffs seen in any existing framework or test code. **Low**: the jit is now spilling the eval stack entries to temps in cases where it did not before; this should be conservatively safe. cc: @brucefo ____ If we're appending an assignment whose LHS is is a location within a local struct, we need to spill all references to that struct from the eval stack. Update the existing logic for this to handle the case where the LHS is a field of a local struct, and the field is updated by unusual means (here, `initobj`). Fixes dotnet/runtime#764. * Fix test
Diffstat (limited to 'src/jit')
-rw-r--r--src/jit/importer.cpp21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp
index bbb0d14e97..50ddc58d89 100644
--- a/src/jit/importer.cpp
+++ b/src/jit/importer.cpp
@@ -10837,11 +10837,22 @@ void Compiler::impImportBlockCode(BasicBlock* block)
}
else if (lhs->OperIsBlk())
{
- // Check for ADDR(LCL_VAR), or ADD(ADDR(LCL_VAR),CNS_INT))
- // (the latter may appear explicitly in the IL).
- // Local field stores will cause the stack to be spilled when
- // they are encountered.
- lclVar = lhs->AsBlk()->Addr()->IsLocalAddrExpr();
+ // Check if LHS address is within some struct local, to catch
+ // cases where we're updating the struct by something other than a stfld
+ GenTree* addr = lhs->AsBlk()->Addr();
+
+ // Catches ADDR(LCL_VAR), or ADD(ADDR(LCL_VAR),CNS_INT))
+ lclVar = addr->IsLocalAddrExpr();
+
+ // Catches ADDR(FIELD(... ADDR(LCL_VAR)))
+ if (lclVar == nullptr)
+ {
+ GenTree* lclTree = nullptr;
+ if (impIsAddressInLocal(addr, &lclTree))
+ {
+ lclVar = lclTree->AsLclVarCommon();
+ }
+ }
}
if (lclVar != nullptr)
{