diff --git a/src/coreclr/jit/fgdiagnostic.cpp b/src/coreclr/jit/fgdiagnostic.cpp index c78fe6f7124e90..10124c44b2cdf5 100644 --- a/src/coreclr/jit/fgdiagnostic.cpp +++ b/src/coreclr/jit/fgdiagnostic.cpp @@ -3390,20 +3390,17 @@ void Compiler::fgDebugCheckFlags(GenTree* tree, BasicBlock* block) GenTreeFlags handleKind = op1->GetIconHandleFlag(); // Some of these aren't handles to invariant data... - if ((handleKind == GTF_ICON_STATIC_HDL) || // Pointer to a mutable class Static variable - (handleKind == GTF_ICON_BBC_PTR) || // Pointer to a mutable basic block count value - (handleKind == GTF_ICON_FTN_ADDR) || // Pointer to a potentially mutable VM slot - (handleKind == GTF_ICON_GLOBAL_PTR)) // Pointer to mutable data from the VM state + if (GenTree::HandleKindDataIsInvariant(handleKind) && (handleKind != GTF_ICON_FTN_ADDR)) + { + expectedFlags |= GTF_IND_INVARIANT; + } + else { // For statics, we expect the GTF_GLOB_REF to be set. However, we currently // fail to set it in a number of situations, and so this check is disabled. // TODO: enable checking of GTF_GLOB_REF. // expectedFlags |= GTF_GLOB_REF; } - else // All the other handle indirections are considered invariant - { - expectedFlags |= GTF_IND_INVARIANT; - } // Currently we expect all indirections with constant addresses to be nonfaulting. expectedFlags |= GTF_IND_NONFAULTING; diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 458117f8ebfb69..2a9fd037f9c414 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -7710,8 +7710,8 @@ GenTreeFlags Compiler::gtTokenToIconFlags(unsigned token) // Returns a GT_IND node representing value at the address provided by 'addr' // // Notes: -// The GT_IND node is marked as non-faulting -// If the indType is GT_REF we also mark the indNode as GTF_GLOB_REF +// The GT_IND node is marked as non-faulting. +// If the indirection is not invariant, we also mark the indNode as GTF_GLOB_REF. // GenTree* Compiler::gtNewIndOfIconHandleNode(var_types indType, size_t addr, GenTreeFlags iconFlags, bool isInvariant) { @@ -7720,9 +7720,7 @@ GenTree* Compiler::gtNewIndOfIconHandleNode(var_types indType, size_t addr, GenT if (isInvariant) { - assert(iconFlags != GTF_ICON_STATIC_HDL); // Pointer to a mutable class Static variable - assert(iconFlags != GTF_ICON_BBC_PTR); // Pointer to a mutable basic block count value - assert(iconFlags != GTF_ICON_GLOBAL_PTR); // Pointer to mutable data from the VM state + assert(GenTree::HandleKindDataIsInvariant(iconFlags)); // This indirection also is invariant. indirFlags |= GTF_IND_INVARIANT; @@ -10796,6 +10794,27 @@ void GenTree::SetIndirExceptionFlags(Compiler* comp) } } +//------------------------------------------------------------------------------ +// HandleKindDataIsInvariant: Returns true if the data referred to by a handle +// address is guaranteed to be invariant. Note that GTF_ICON_FTN_ADDR handles may +// or may not point to invariant data. +// +// Arguments: +// flags - GenTree flags for handle. +// +/* static */ +bool GenTree::HandleKindDataIsInvariant(GenTreeFlags flags) +{ + GenTreeFlags handleKind = flags & GTF_ICON_HDL_MASK; + assert(handleKind != GTF_EMPTY); + + // All handle types are assumed invariant except those specifically listed here. + + return (handleKind != GTF_ICON_STATIC_HDL) && // Pointer to a mutable class Static variable + (handleKind != GTF_ICON_BBC_PTR) && // Pointer to a mutable basic block count value + (handleKind != GTF_ICON_GLOBAL_PTR); // Pointer to mutable data from the VM state +} + #ifdef DEBUG /* static */ int GenTree::gtDispFlags(GenTreeFlags flags, GenTreeDebugFlags debugFlags) diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index fe8cfbc1ceb9b3..4464acca18e0a0 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -2249,6 +2249,7 @@ struct GenTree } #if defined(TARGET_XARCH) && defined(FEATURE_HW_INTRINSICS) + bool IsEmbMaskOp() { return OperIsHWIntrinsic() && ((gtFlags & GTF_HW_EM_OP) != 0); @@ -2263,6 +2264,8 @@ struct GenTree #endif // TARGET_XARCH && FEATURE_HW_INTRINSICS + static bool HandleKindDataIsInvariant(GenTreeFlags flags); + bool IsCall() const { return OperGet() == GT_CALL;