Skip to content

Commit 6a23f1c

Browse files
authored
JIT: Changes from #113440 with diffs (#113559)
1 parent 7e69df0 commit 6a23f1c

File tree

2 files changed

+43
-162
lines changed

2 files changed

+43
-162
lines changed

src/coreclr/jit/assertionprop.cpp

Lines changed: 42 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -755,8 +755,8 @@ void Compiler::optPrintAssertion(AssertionDsc* curAssertion, AssertionIndex asse
755755
{
756756
printf("Copy ");
757757
}
758-
else if ((curAssertion->op2.kind == O2K_CONST_INT) || (curAssertion->op2.kind == O2K_CONST_LONG) ||
759-
(curAssertion->op2.kind == O2K_CONST_DOUBLE) || (curAssertion->op2.kind == O2K_ZEROOBJ))
758+
else if ((curAssertion->op2.kind == O2K_CONST_INT) || (curAssertion->op2.kind == O2K_CONST_DOUBLE) ||
759+
(curAssertion->op2.kind == O2K_ZEROOBJ))
760760
{
761761
printf("Constant ");
762762
}
@@ -950,10 +950,6 @@ void Compiler::optPrintAssertion(AssertionDsc* curAssertion, AssertionIndex asse
950950
}
951951
break;
952952

953-
case O2K_CONST_LONG:
954-
printf("0x%016llx", curAssertion->op2.lconVal);
955-
break;
956-
957953
case O2K_CONST_DOUBLE:
958954
if (FloatingPointUtils::isNegativeZero(curAssertion->op2.dconVal))
959955
{
@@ -1232,10 +1228,6 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1, GenTree* op2, optAsser
12321228
}
12331229
goto CNS_COMMON;
12341230

1235-
case GT_CNS_LNG:
1236-
op2Kind = O2K_CONST_LONG;
1237-
goto CNS_COMMON;
1238-
12391231
case GT_CNS_DBL:
12401232
op2Kind = O2K_CONST_DOUBLE;
12411233
goto CNS_COMMON;
@@ -1258,9 +1250,8 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1, GenTree* op2, optAsser
12581250
goto DONE_ASSERTION; // Don't make an assertion
12591251
}
12601252

1261-
assertion.op2.kind = op2Kind;
1262-
assertion.op2.lconVal = 0;
1263-
assertion.op2.vn = optConservativeNormalVN(op2);
1253+
assertion.op2.kind = op2Kind;
1254+
assertion.op2.vn = optConservativeNormalVN(op2);
12641255

12651256
if (op2->gtOper == GT_CNS_INT)
12661257
{
@@ -1276,10 +1267,6 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1, GenTree* op2, optAsser
12761267
assertion.op2.u1.iconVal = iconVal;
12771268
assertion.op2.SetIconFlag(op2->GetIconHandleFlag(), op2->AsIntCon()->gtFieldSeq);
12781269
}
1279-
else if (op2->gtOper == GT_CNS_LNG)
1280-
{
1281-
assertion.op2.lconVal = op2->AsLngCon()->gtLconVal;
1282-
}
12831270
else
12841271
{
12851272
noway_assert(op2->gtOper == GT_CNS_DBL);
@@ -1444,12 +1431,6 @@ AssertionIndex Compiler::optFinalizeCreatingAssertion(AssertionDsc* assertion)
14441431
{
14451432
return NO_ASSERTION_INDEX;
14461433
}
1447-
1448-
// TODO: only copy assertions rely on valid SSA number so we could generate more assertions here
1449-
if (assertion->op1.lcl.ssaNum == SsaConfig::RESERVED_SSA_NUM)
1450-
{
1451-
return NO_ASSERTION_INDEX;
1452-
}
14531434
}
14541435

14551436
// Now add the assertion to our assertion table
@@ -1731,10 +1712,6 @@ void Compiler::optDebugCheckAssertion(AssertionDsc* assertion)
17311712

17321713
switch (assertion->op1.kind)
17331714
{
1734-
case O1K_LCLVAR:
1735-
assert(optLocalAssertionProp ||
1736-
lvaGetDesc(assertion->op1.lcl.lclNum)->lvPerSsaData.IsValidSsaNum(assertion->op1.lcl.ssaNum));
1737-
break;
17381715
case O1K_ARR_BND:
17391716
// It would be good to check that bnd.vnIdx and bnd.vnLen are valid value numbers.
17401717
assert(!optLocalAssertionProp);
@@ -1772,14 +1749,6 @@ void Compiler::optDebugCheckAssertion(AssertionDsc* assertion)
17721749
}
17731750
break;
17741751

1775-
case O2K_CONST_LONG:
1776-
{
1777-
// All handles should be represented by O2K_CONST_INT,
1778-
// so no handle bits should be set here.
1779-
assert(!assertion->op2.HasIconFlag());
1780-
}
1781-
break;
1782-
17831752
case O2K_ZEROOBJ:
17841753
{
17851754
// We only make these assertion for stores (not control flow).
@@ -1852,8 +1821,8 @@ void Compiler::optCreateComplementaryAssertion(AssertionIndex assertionIndex, Ge
18521821
if ((candidateAssertion.op1.kind == O1K_LCLVAR) || (candidateAssertion.op1.kind == O1K_VN))
18531822
{
18541823
// "LCLVAR != CNS" is not a useful assertion (unless CNS is 0/1)
1855-
if (((candidateAssertion.op2.kind == O2K_CONST_INT) || (candidateAssertion.op2.kind == O2K_CONST_LONG)) &&
1856-
(candidateAssertion.op2.u1.iconVal != 0) && (candidateAssertion.op2.u1.iconVal != 1))
1824+
if (((candidateAssertion.op2.kind == O2K_CONST_INT)) && (candidateAssertion.op2.u1.iconVal != 0) &&
1825+
(candidateAssertion.op2.u1.iconVal != 1))
18571826
{
18581827
return;
18591828
}
@@ -1881,59 +1850,6 @@ void Compiler::optCreateComplementaryAssertion(AssertionIndex assertionIndex, Ge
18811850
}
18821851
}
18831852

1884-
// optAssertionGenCast: Create a tentative subrange assertion for a cast.
1885-
//
1886-
// This function will try to create an assertion that the cast's operand
1887-
// is within the "input" range for the cast, so that this assertion can
1888-
// later be proven via implication and the cast removed. Such assertions
1889-
// are only generated during global propagation, and only for LCL_VARs.
1890-
//
1891-
// Arguments:
1892-
// cast - the cast node for which to create the assertion
1893-
//
1894-
// Return Value:
1895-
// Index of the generated assertion, or NO_ASSERTION_INDEX if it was not
1896-
// legal, profitable, or possible to create one.
1897-
//
1898-
AssertionIndex Compiler::optAssertionGenCast(GenTreeCast* cast)
1899-
{
1900-
if (optLocalAssertionProp || !varTypeIsIntegral(cast) || !varTypeIsIntegral(cast->CastOp()))
1901-
{
1902-
return NO_ASSERTION_INDEX;
1903-
}
1904-
1905-
// This condition exists to preserve previous behavior.
1906-
if (!cast->CastOp()->OperIs(GT_LCL_VAR))
1907-
{
1908-
return NO_ASSERTION_INDEX;
1909-
}
1910-
1911-
GenTreeLclVar* lclVar = cast->CastOp()->AsLclVar();
1912-
LclVarDsc* varDsc = lvaGetDesc(lclVar);
1913-
1914-
// It is not useful to make assertions about address-exposed variables, they will never be proven.
1915-
if (varDsc->IsAddressExposed())
1916-
{
1917-
return NO_ASSERTION_INDEX;
1918-
}
1919-
1920-
// A representation-changing cast cannot be simplified if it is not checked.
1921-
if (!cast->gtOverflow() && (genActualType(cast) != genActualType(lclVar)))
1922-
{
1923-
return NO_ASSERTION_INDEX;
1924-
}
1925-
1926-
AssertionDsc assertion = {OAK_SUBRANGE};
1927-
assertion.op1.kind = O1K_LCLVAR;
1928-
assertion.op1.vn = vnStore->VNConservativeNormalValue(lclVar->gtVNPair);
1929-
assertion.op1.lcl.lclNum = lclVar->GetLclNum();
1930-
assertion.op1.lcl.ssaNum = lclVar->GetSsaNum();
1931-
assertion.op2.kind = O2K_SUBRANGE;
1932-
assertion.op2.u2 = IntegralRange::ForCastInput(cast);
1933-
1934-
return optFinalizeCreatingAssertion(&assertion);
1935-
}
1936-
19371853
//------------------------------------------------------------------------
19381854
// optCreateJtrueAssertions: Create assertions about a JTRUE's relop operands.
19391855
//
@@ -2139,21 +2055,21 @@ AssertionInfo Compiler::optAssertionGenJtrue(GenTree* tree)
21392055

21402056
// See if we have IND(obj) ==/!= TypeHandle
21412057
//
2142-
if (!optLocalAssertionProp && op1->OperIs(GT_IND))
2058+
if (!optLocalAssertionProp && op1->OperIs(GT_IND) && op1->gtGetOp1()->TypeIs(TYP_REF))
21432059
{
2144-
ssize_t cnsValue = 0;
2145-
GenTreeFlags iconFlags = GTF_EMPTY;
2146-
if (op1->gtGetOp1()->TypeIs(TYP_REF) &&
2147-
optIsTreeKnownIntValue(!optLocalAssertionProp, op2, &cnsValue, &iconFlags))
2060+
ValueNum objVN = optConservativeNormalVN(op1->gtGetOp1());
2061+
ValueNum typeHndVN = optConservativeNormalVN(op2);
2062+
2063+
if ((objVN != ValueNumStore::NoVN) && vnStore->IsVNTypeHandle(typeHndVN))
21482064
{
21492065
AssertionDsc assertion;
21502066
assertion.assertionKind = OAK_EQUAL;
21512067
assertion.op1.kind = O1K_EXACT_TYPE;
2152-
assertion.op1.vn = optConservativeNormalVN(op1->gtGetOp1());
2068+
assertion.op1.vn = objVN;
21532069
assertion.op2.kind = O2K_CONST_INT;
2154-
assertion.op2.u1.iconVal = cnsValue;
2155-
assertion.op2.vn = optConservativeNormalVN(op2);
2156-
assertion.op2.SetIconFlag(iconFlags);
2070+
assertion.op2.u1.iconVal = vnStore->CoercedConstantValue<ssize_t>(typeHndVN);
2071+
assertion.op2.vn = typeHndVN;
2072+
assertion.op2.SetIconFlag(GTF_ICON_CLASS_HDL);
21572073
AssertionIndex index = optAddAssertion(&assertion);
21582074

21592075
// We don't need to create a complementary assertion here. We're only interested
@@ -2260,15 +2176,18 @@ AssertionInfo Compiler::optAssertionGenJtrue(GenTree* tree)
22602176
assert(objectNode->TypeIs(TYP_REF, TYP_I_IMPL));
22612177
assert(methodTableNode->TypeIs(TYP_I_IMPL));
22622178

2263-
if (methodTableNode->OperIs(GT_CNS_INT))
2179+
ValueNum objVN = optConservativeNormalVN(objectNode);
2180+
ValueNum typeHndVN = optConservativeNormalVN(methodTableNode);
2181+
2182+
if ((objVN != ValueNumStore::NoVN) && vnStore->IsVNTypeHandle(typeHndVN))
22642183
{
22652184
AssertionDsc assertion;
22662185
assertion.op1.kind = O1K_SUBTYPE;
2267-
assertion.op1.vn = optConservativeNormalVN(objectNode);
2186+
assertion.op1.vn = objVN;
22682187
assertion.op2.kind = O2K_CONST_INT;
2269-
assertion.op2.u1.iconVal = methodTableNode->AsIntCon()->IconValue();
2270-
assertion.op2.vn = optConservativeNormalVN(methodTableNode);
2271-
assertion.op2.SetIconFlag(op2->GetIconHandleFlag());
2188+
assertion.op2.u1.iconVal = vnStore->CoercedConstantValue<ssize_t>(typeHndVN);
2189+
assertion.op2.vn = typeHndVN;
2190+
assertion.op2.SetIconFlag(GTF_ICON_CLASS_HDL);
22722191
assertion.assertionKind = OAK_EQUAL;
22732192
AssertionIndex index = optAddAssertion(&assertion);
22742193

@@ -2310,9 +2229,6 @@ void Compiler::optAssertionGen(GenTree* tree)
23102229
optAssertionPropCurrentTree = tree;
23112230
#endif
23122231

2313-
// For most of the assertions that we create below
2314-
// the assertion is true after the tree is processed
2315-
bool assertionProven = true;
23162232
AssertionInfo assertionInfo;
23172233
switch (tree->OperGet())
23182234
{
@@ -2379,14 +2295,6 @@ void Compiler::optAssertionGen(GenTree* tree)
23792295
}
23802296
break;
23812297

2382-
case GT_CAST:
2383-
// This represets an assertion that we would like to prove to be true.
2384-
// If we can prove this assertion true then we can eliminate this cast.
2385-
// We only create this assertion for global assertion propagation.
2386-
assertionInfo = optAssertionGenCast(tree->AsCast());
2387-
assertionProven = false;
2388-
break;
2389-
23902298
case GT_JTRUE:
23912299
assertionInfo = optAssertionGenJtrue(tree);
23922300
break;
@@ -2396,7 +2304,7 @@ void Compiler::optAssertionGen(GenTree* tree)
23962304
break;
23972305
}
23982306

2399-
if (assertionInfo.HasAssertion() && assertionProven)
2307+
if (assertionInfo.HasAssertion())
24002308
{
24012309
tree->SetAssertionInfo(assertionInfo);
24022310
}
@@ -3326,17 +3234,6 @@ GenTree* Compiler::optConstantAssertionProp(AssertionDsc* curAssertion,
33263234
newTree->BashToConst(curAssertion->op2.dconVal, tree->TypeGet());
33273235
break;
33283236

3329-
case O2K_CONST_LONG:
3330-
if (newTree->TypeIs(TYP_LONG))
3331-
{
3332-
newTree->BashToConst(curAssertion->op2.lconVal);
3333-
}
3334-
else
3335-
{
3336-
newTree->BashToConst(static_cast<int32_t>(curAssertion->op2.lconVal));
3337-
}
3338-
break;
3339-
33403237
case O2K_CONST_INT:
33413238

33423239
// Don't propagate handles if we need to report relocs.
@@ -3731,30 +3628,26 @@ GenTree* Compiler::optAssertionProp_LclVar(ASSERT_VALARG_TP assertions, GenTreeL
37313628
continue;
37323629
}
37333630

3734-
// Constant prop.
3735-
//
3736-
// The case where the tree type could be different than the LclVar type is caused by
3737-
// gtFoldExpr, specifically the case of a cast, where the fold operation changes the type of the LclVar
3738-
// node. In such a case is not safe to perform the substitution since later on the JIT will assert mismatching
3739-
// types between trees.
3740-
//
3741-
if (curAssertion->op1.lcl.lclNum == lclNum)
3631+
// Verify types match
3632+
if (tree->TypeGet() != lvaGetRealType(lclNum))
37423633
{
3743-
LclVarDsc* const lclDsc = lvaGetDesc(lclNum);
3744-
// Verify types match
3745-
if (tree->TypeGet() == lclDsc->lvType)
3746-
{
3747-
// If local assertion prop, just perform constant prop.
3748-
if (optLocalAssertionProp)
3749-
{
3750-
return optConstantAssertionProp(curAssertion, tree, stmt DEBUGARG(assertionIndex));
3751-
}
3634+
continue;
3635+
}
37523636

3753-
// If global assertion, perform constant propagation only if the VN's match.
3754-
if (curAssertion->op1.vn == vnStore->VNConservativeNormalValue(tree->gtVNPair))
3755-
{
3756-
return optConstantAssertionProp(curAssertion, tree, stmt DEBUGARG(assertionIndex));
3757-
}
3637+
if (optLocalAssertionProp)
3638+
{
3639+
// Check lclNum in Local Assertion Prop
3640+
if (curAssertion->op1.lcl.lclNum == lclNum)
3641+
{
3642+
return optConstantAssertionProp(curAssertion, tree, stmt DEBUGARG(assertionIndex));
3643+
}
3644+
}
3645+
else
3646+
{
3647+
// Check VN in Global Assertion Prop
3648+
if (curAssertion->op1.vn == vnStore->VNConservativeNormalValue(tree->gtVNPair))
3649+
{
3650+
return optConstantAssertionProp(curAssertion, tree, stmt DEBUGARG(assertionIndex));
37583651
}
37593652
}
37603653
}
@@ -6034,10 +5927,6 @@ void Compiler::optImpliedByCopyAssertion(AssertionDsc* copyAssertion, AssertionD
60345927
usable = op1MatchesCopy && impAssertion->op2.u2.Contains(depAssertion->op2.u2);
60355928
break;
60365929

6037-
case O2K_CONST_LONG:
6038-
usable = op1MatchesCopy && (impAssertion->op2.lconVal == depAssertion->op2.lconVal);
6039-
break;
6040-
60415930
case O2K_CONST_DOUBLE:
60425931
// Exact memory match because of positive and negative zero
60435932
usable = op1MatchesCopy &&

src/coreclr/jit/compiler.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7724,7 +7724,6 @@ class Compiler
77247724
O2K_INVALID,
77257725
O2K_LCLVAR_COPY,
77267726
O2K_CONST_INT,
7727-
O2K_CONST_LONG,
77287727
O2K_CONST_DOUBLE,
77297728
O2K_ZEROOBJ,
77307729
O2K_SUBRANGE,
@@ -7763,17 +7762,13 @@ class Compiler
77637762
ValueNum vn;
77647763
struct IntVal
77657764
{
7766-
ssize_t iconVal; // integer
7767-
#if !defined(HOST_64BIT)
7768-
unsigned padding; // unused; ensures iconFlags does not overlap lconVal
7769-
#endif
7765+
ssize_t iconVal; // integer
77707766
FieldSeq* fieldSeq;
77717767
};
77727768
union
77737769
{
77747770
SsaVar lcl;
77757771
IntVal u1;
7776-
int64_t lconVal;
77777772
double dconVal;
77787773
IntegralRange u2;
77797774
};
@@ -7915,9 +7910,6 @@ class Compiler
79157910
case O2K_CONST_INT:
79167911
return ((op2.u1.iconVal == that->op2.u1.iconVal) && (op2.GetIconFlag() == that->op2.GetIconFlag()));
79177912

7918-
case O2K_CONST_LONG:
7919-
return (op2.lconVal == that->op2.lconVal);
7920-
79217913
case O2K_CONST_DOUBLE:
79227914
// exact match because of positive and negative zero.
79237915
return (memcmp(&op2.dconVal, &that->op2.dconVal, sizeof(double)) == 0);

0 commit comments

Comments
 (0)