summaryrefslogtreecommitdiff
path: root/src/jit/flowgraph.cpp
diff options
context:
space:
mode:
authorEugene Rozenfeld <erozen@microsoft.com>2018-11-19 17:08:06 -0800
committerEugene Rozenfeld <erozen@microsoft.com>2018-11-20 12:20:35 -0800
commite80e04020c3281ec675817c4fff025a3e347353e (patch)
tree5a5e180f13692770915481a4ce13ab0c349d15c5 /src/jit/flowgraph.cpp
parent382874f3d574f256cda617cdc63916cecbf231aa (diff)
downloadcoreclr-e80e04020c3281ec675817c4fff025a3e347353e.tar.gz
coreclr-e80e04020c3281ec675817c4fff025a3e347353e.tar.bz2
coreclr-e80e04020c3281ec675817c4fff025a3e347353e.zip
Fix for #21011: propagate GTF_DONT_CSE on comma returns
When a method returns a multi-reg struct, we set GTF_DONT_CSE on return local: https://github.com/dotnet/coreclr/blob/497419bf8f19c649d821295da7e225e55581cce9/src/jit/importer.cpp#L8783 Setting GTF_DONT_CSE blocks assertion propagation here: https://github.com/dotnet/coreclr/blob/9d49bf1ec6f102b89e5c2885e8f9d3d77f2ec144/src/jit/assertionprop.cpp#L2845-L2848 In the test we have a synchronized method so we change the return node to return a comma that include a call to HELPER.CORINFO_HELP_MON_EXIT. If the rightmost comma expression doesn't have GTF_DONT_CSE, assertion propagation is not blocked and we end up with this tree: ``` [000040] -----+------ /--* CNS_INT struct 0 [000043] --C-G+------ /--* COMMA struct [000036] --C-G+------ | \--* CALL help void HELPER.CORINFO_HELP_MON_EXIT [000032] L----+------ arg1 in x1 | +--* ADDR long [000031] ----G+-N---- | | \--* LCL_VAR ubyte (AX) V03 tmp1 [000033] -----+------ arg0 in x0 | \--* LCL_VAR ref V00 this [000041] -AC-G+------ * COMMA struct [000006] -----+-N---- | /--* LCL_VAR struct V01 loc0 [000039] -A---+------ \--* ASG struct (copy) [000037] D----+-N---- \--* LCL_VAR struct V05 tmp3 ``` Downstream phases can't handle struct zero return expressed as ``` [000040] -----+------ /--* CNS_INT struct 0 ``` The fix is to propagate GTF_DONT_CSE to the rightmost comma expression to block bad assertion propagation. Fixes #21011.
Diffstat (limited to 'src/jit/flowgraph.cpp')
-rw-r--r--src/jit/flowgraph.cpp9
1 files changed, 8 insertions, 1 deletions
diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp
index b2846ed7cf..bcc818f25b 100644
--- a/src/jit/flowgraph.cpp
+++ b/src/jit/flowgraph.cpp
@@ -8033,7 +8033,14 @@ GenTree* Compiler::fgCreateMonitorTree(unsigned lvaMonAcquired, unsigned lvaThis
// in turn passes it to VM to know the size of value type.
GenTree* temp = fgInsertCommaFormTemp(&retNode->gtOp.gtOp1, info.compMethodInfo->args.retTypeClass);
- GenTree* lclVar = retNode->gtOp.gtOp1->gtOp.gtOp2;
+ GenTree* lclVar = retNode->gtOp.gtOp1->gtOp.gtOp2;
+
+ // The return can't handle all of the trees that could be on the right-hand-side of an assignment,
+ // especially in the case of a struct. Therefore, we need to propagate GTF_DONT_CSE.
+ // If we don't, assertion propagation may, e.g., change a return of a local to a return of "CNS_INT struct
+ // 0",
+ // which downstream phases can't handle.
+ lclVar->gtFlags |= (retExpr->gtFlags & GTF_DONT_CSE);
retNode->gtOp.gtOp1->gtOp.gtOp2 = gtNewOperNode(GT_COMMA, retExpr->TypeGet(), tree, lclVar);
}
else