diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp index 8806277cd51b3..730e237584283 100644 --- a/src/coreclr/jit/optimizer.cpp +++ b/src/coreclr/jit/optimizer.cpp @@ -4616,6 +4616,15 @@ void Compiler::optHoistLoopBlocks(FlowGraphNaturalLoop* loop, // hence this check is not present in optIsCSEcandidate(). return true; } + else if ((node->gtFlags & GTF_ORDER_SIDEEFF) != 0) + { + // If a node has an order side effect, we can't hoist it at all: we don't know what the order + // dependence actually is. For example, assertion prop might have determined a node can't throw + // an exception, and eliminated the GTF_EXCEPT flag, replacing it with GTF_ORDER_SIDEEFF. We + // can't hoist because we might then hoist above the expression that led assertion prop to make + // that decision. This can happen in JitOptRepeat, where hoisting can follow assertion prop. + return false; + } // Tree must be a suitable CSE candidate for us to be able to hoist it. return m_compiler->optIsCSEcandidate(node); @@ -4806,7 +4815,7 @@ void Compiler::optHoistLoopBlocks(FlowGraphNaturalLoop* loop, } else if (!top.m_hoistable) { - top.m_failReason = "not handled by cse"; + top.m_failReason = "not handled by hoisting or CSE"; } #endif @@ -4889,7 +4898,7 @@ void Compiler::optHoistLoopBlocks(FlowGraphNaturalLoop* loop, treeIsHoistable = IsNodeHoistable(tree); if (!treeIsHoistable) { - INDEBUG(failReason = "not handled by cse";) + INDEBUG(failReason = "not handled by hoisting or CSE";) } }