Skip to content

Commit

Permalink
JIT: fix issue with assert seen in OSR+PGO tests (#69067)
Browse files Browse the repository at this point in the history
Update `IsIconHandle` to work for all tree types.

Closes #69032.
  • Loading branch information
AndyAyersMS authored May 11, 2022
1 parent b4f46ac commit 10a4986
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/earlyprop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/fgdiagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/flowgraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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();
}

//------------------------------------------------------------------------
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
23 changes: 7 additions & 16 deletions src/coreclr/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/valuenum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
Expand Down Expand Up @@ -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();
Expand Down
28 changes: 28 additions & 0 deletions src/tests/JIT/opt/OSR/Runtime_69032.cs
Original file line number Diff line number Diff line change
@@ -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<object, object>();
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;
}
}
26 changes: 26 additions & 0 deletions src/tests/JIT/opt/OSR/Runtime_69032.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<DebugType />
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
<PropertyGroup>
<CLRTestBatchPreCommands><![CDATA[
$(CLRTestBatchPreCommands)
set COMPlus_TieredCompilation=1
set COMPlus_TieredPGO=1
set COMPlus_TC_QuickJitForLoops=1
set COMPlus_TC_OnStackReplacement=1
]]></CLRTestBatchPreCommands>
<BashCLRTestPreCommands><![CDATA[
$(BashCLRTestPreCommands)
export COMPlus_TieredCompilation=1
export COMPlus_TieredPGO=1
export COMPlus_TC_QuickJitForLoops=1
export COMPlus_TC_OnStackReplacement=1
]]></BashCLRTestPreCommands>
</PropertyGroup>
</Project>

0 comments on commit 10a4986

Please sign in to comment.