diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 50da645363704..f495acf2c07e6 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -4979,7 +4979,7 @@ void CodeGen::genCodeForIndir(GenTreeIndir* tree) emitter* emit = GetEmitter(); GenTree* addr = tree->Addr(); - if (addr->IsCnsIntOrI() && addr->IsIconHandle(GTF_ICON_TLS_HDL)) + if (addr->IsIconHandle(GTF_ICON_TLS_HDL)) { noway_assert(EA_ATTR(genTypeSize(targetType)) == EA_PTRSIZE); emit->emitIns_R_C(ins_Load(TYP_I_IMPL), EA_PTRSIZE, tree->GetRegNum(), FLD_GLOBAL_FS, diff --git a/src/coreclr/jit/earlyprop.cpp b/src/coreclr/jit/earlyprop.cpp index 2424e89b2878c..e9b9eabd6d6c5 100644 --- a/src/coreclr/jit/earlyprop.cpp +++ b/src/coreclr/jit/earlyprop.cpp @@ -221,7 +221,7 @@ GenTree* Compiler::optEarlyPropRewriteTree(GenTree* tree, LocalNumberToNullCheck if (actualVal != nullptr) { assert(propKind == optPropKind::OPK_ARRAYLEN); - assert(actualVal->IsCnsIntOrI() && !actualVal->AsIntCon()->IsIconHandle()); + assert(actualVal->IsCnsIntOrI() && !actualVal->IsIconHandle()); assert(actualVal->GetNodeSize() == TREE_NODE_SZ_SMALL); ssize_t actualConstVal = actualVal->AsIntCon()->IconValue(); diff --git a/src/coreclr/jit/fgdiagnostic.cpp b/src/coreclr/jit/fgdiagnostic.cpp index d5b3cb54683e1..508164f7a1205 100644 --- a/src/coreclr/jit/fgdiagnostic.cpp +++ b/src/coreclr/jit/fgdiagnostic.cpp @@ -2998,7 +2998,7 @@ void Compiler::fgDebugCheckFlags(GenTree* tree) case GT_IND: // Do we have a constant integer address as op1 that is also a handle? - if (op1->IsCnsIntOrI() && op1->IsIconHandle()) + if (op1->IsIconHandle()) { if ((tree->gtFlags & GTF_IND_INVARIANT) != 0) { diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp index 3bc6250b1d5fa..9e94792313e84 100644 --- a/src/coreclr/jit/flowgraph.cpp +++ b/src/coreclr/jit/flowgraph.cpp @@ -937,7 +937,7 @@ GenTreeCall* Compiler::fgGetSharedCCtor(CORINFO_CLASS_HANDLE cls) bool Compiler::fgAddrCouldBeNull(GenTree* addr) { addr = addr->gtEffectiveVal(); - if ((addr->gtOper == GT_CNS_INT) && addr->IsIconHandle()) + if (addr->IsIconHandle()) { return false; } diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index a1d1c27dcbd6d..3574d3c258698 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -9726,7 +9726,7 @@ void Compiler::gtDispNodeName(GenTree* tree) char buf[32]; char* bufp = &buf[0]; - if ((tree->gtOper == GT_CNS_INT) && tree->IsIconHandle()) + if (tree->IsIconHandle()) { sprintf_s(bufp, sizeof(buf), " %s(h)%c", name, 0); } @@ -16674,7 +16674,7 @@ unsigned GenTreeIndir::Size() const bool GenTreeIntConCommon::ImmedValNeedsReloc(Compiler* comp) { - return comp->opts.compReloc && (gtOper == GT_CNS_INT) && IsIconHandle(); + return comp->opts.compReloc && IsIconHandle(); } //------------------------------------------------------------------------ @@ -16817,7 +16817,7 @@ bool GenTree::IsFieldAddr(Compiler* comp, GenTree** pBaseAddr, FieldSeqNode** pF { // If one operand has a field sequence, the other operand must not have one // as the order of fields in that case would not be well-defined. - if (AsOp()->gtOp1->IsCnsIntOrI() && AsOp()->gtOp1->IsIconHandle()) + if (AsOp()->gtOp1->IsIconHandle()) { assert(!AsOp()->gtOp2->IsCnsIntOrI() || !AsOp()->gtOp2->IsIconHandle()); baseAddr = AsOp()->gtOp2; @@ -16838,7 +16838,7 @@ bool GenTree::IsFieldAddr(Compiler* comp, GenTree** pBaseAddr, FieldSeqNode** pF assert(!baseAddr->TypeIs(TYP_REF) || !comp->GetZeroOffsetFieldMap()->Lookup(baseAddr)); } - else if (IsCnsIntOrI() && IsIconHandle(GTF_ICON_STATIC_HDL)) + else if (IsIconHandle(GTF_ICON_STATIC_HDL)) { assert(!comp->GetZeroOffsetFieldMap()->Lookup(this) && (AsIntCon()->gtFieldSeq != nullptr)); baseAddr = this; diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index f65e5d765bfe7..c724b1a5909b3 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -2112,25 +2112,22 @@ struct GenTree bool IsIconHandle() const { - assert(gtOper == GT_CNS_INT); - return (gtFlags & GTF_ICON_HDL_MASK) ? true : false; + return (gtOper == GT_CNS_INT) && ((gtFlags & GTF_ICON_HDL_MASK) != 0); } bool IsIconHandle(GenTreeFlags handleType) const { - assert(gtOper == GT_CNS_INT); - assert((handleType & GTF_ICON_HDL_MASK) != 0); // check that handleType is one of the valid GTF_ICON_* values + // check that handleType is one of the valid GTF_ICON_* values + assert((handleType & GTF_ICON_HDL_MASK) != 0); assert((handleType & ~GTF_ICON_HDL_MASK) == 0); - return (gtFlags & GTF_ICON_HDL_MASK) == handleType; + return (gtOper == GT_CNS_INT) && ((gtFlags & GTF_ICON_HDL_MASK) == handleType); } - // Return just the part of the flags corresponding to the GTF_ICON_*_HDL flag. For example, - // GTF_ICON_SCOPE_HDL. The tree node must be a const int, but it might not be a handle, in which - // case we'll return zero. + // Return just the part of the flags corresponding to the GTF_ICON_*_HDL flag. + // For non-icon handle trees, returns GTF_EMPTY. GenTreeFlags GetIconHandleFlag() const { - assert(gtOper == GT_CNS_INT); - return (gtFlags & GTF_ICON_HDL_MASK); + return (gtOper == GT_CNS_INT) ? (gtFlags & GTF_ICON_HDL_MASK) : GTF_EMPTY; } // Mark this node as no longer being a handle; clear its GTF_ICON_*_HDL bits. @@ -2140,12 +2137,6 @@ struct GenTree gtFlags &= ~GTF_ICON_HDL_MASK; } - // Return true if the two GT_CNS_INT trees have the same handle flag (GTF_ICON_*_HDL). - static bool SameIconHandleFlag(GenTree* t1, GenTree* t2) - { - return t1->GetIconHandleFlag() == t2->GetIconHandleFlag(); - } - bool IsCall() const { return OperGet() == GT_CALL; diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 838b6f1076d4e..648310b8de43d 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -14519,7 +14519,7 @@ GenTree* Compiler::fgMorphTree(GenTree* tree, MorphAddrContext* mac) #if defined(LATE_DISASM) // GT_CNS_INT is considered small, so ReplaceWith() won't copy all fields - if ((tree->gtOper == GT_CNS_INT) && tree->IsIconHandle()) + if (tree->IsIconHandle()) { copy->AsIntCon()->gtCompileTimeHandle = tree->AsIntCon()->gtCompileTimeHandle; } diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 7d7a7fd4362d5..b771b6285fddc 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -7890,7 +7890,7 @@ void Compiler::fgValueNumberTreeConst(GenTree* tree) case TYP_BYTE: case TYP_UBYTE: case TYP_BOOL: - if (tree->IsCnsIntOrI() && tree->IsIconHandle()) + if (tree->IsIconHandle()) { tree->gtVNPair.SetBoth( vnStore->VNForHandle(ssize_t(tree->AsIntConCommon()->IconValue()), tree->GetIconHandleFlag())); @@ -8672,7 +8672,7 @@ void Compiler::fgValueNumberTree(GenTree* tree) // the address of the static itself. Here we will use "nullptr" for the // field sequence and assume the actual static field will be appended to // it later, as part of numbering the method table pointer offset addition. - if (addr->IsCnsIntOrI() && addr->IsIconHandle(GTF_ICON_STATIC_BOX_PTR)) + if (addr->IsIconHandle(GTF_ICON_STATIC_BOX_PTR)) { assert(addrNvnp.BothEqual() && (addrXvnp == vnStore->VNPForEmptyExcSet())); ValueNum boxAddrVN = addrNvnp.GetLiberal(); diff --git a/src/tests/JIT/opt/OSR/Runtime_69032.cs b/src/tests/JIT/opt/OSR/Runtime_69032.cs new file mode 100644 index 0000000000000..93bdc1db91b30 --- /dev/null +++ b/src/tests/JIT/opt/OSR/Runtime_69032.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Linq; +using System.Runtime.CompilerServices; + +// Assert in F() with OSR+PGO + +class Runtime_69032 +{ + [MethodImpl(MethodImplOptions.NoInlining)] + static int F(int n) + { + var cwt = new ConditionalWeakTable(); + for (int i = 0; i < n; i++) + { + cwt.Add(i.ToString(), i.ToString()); + if (i % 1000 == 0) GC.Collect(); + } + return n; + } + + public static int Main() + { + return F(10_000) / 100; + } +} diff --git a/src/tests/JIT/opt/OSR/Runtime_69032.csproj b/src/tests/JIT/opt/OSR/Runtime_69032.csproj new file mode 100644 index 0000000000000..a49b7786a2be7 --- /dev/null +++ b/src/tests/JIT/opt/OSR/Runtime_69032.csproj @@ -0,0 +1,26 @@ + + + Exe + + True + + + + + + + + +