Skip to content

Commit b1c0fb0

Browse files
authored
JIT: don't allow negative edge weights (#52884)
If the solver wants to set the edge weight below zero, set it to zero if within slop, or disallow if not. Addresses assert seen in #52785.
1 parent 53735f7 commit b1c0fb0

File tree

1 file changed

+60
-31
lines changed

1 file changed

+60
-31
lines changed

src/coreclr/jit/fgprofile.cpp

Lines changed: 60 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2577,7 +2577,26 @@ bool flowList::setEdgeWeightMinChecked(BasicBlock::weight_t newWeight,
25772577
BasicBlock::weight_t slop,
25782578
bool* wbUsedSlop)
25792579
{
2580+
// Negative weights are nonsensical.
2581+
//
2582+
// If we can't cover the deficit with slop, fail.
2583+
// If we can, set the new weight to zero.
2584+
//
2585+
bool usedSlop = false;
2586+
2587+
if (newWeight < BB_ZERO_WEIGHT)
2588+
{
2589+
if ((newWeight + slop) < BB_ZERO_WEIGHT)
2590+
{
2591+
return false;
2592+
}
2593+
2594+
newWeight = BB_ZERO_WEIGHT;
2595+
usedSlop = true;
2596+
}
2597+
25802598
bool result = false;
2599+
25812600
if ((newWeight <= flEdgeWeightMax) && (newWeight >= flEdgeWeightMin))
25822601
{
25832602
flEdgeWeightMin = newWeight;
@@ -2592,19 +2611,15 @@ bool flowList::setEdgeWeightMinChecked(BasicBlock::weight_t newWeight,
25922611
// is less than newWeight, so we just allow for the slop
25932612
if (newWeight <= (flEdgeWeightMax + slop))
25942613
{
2595-
result = true;
2614+
result = true;
2615+
usedSlop = true;
25962616

25972617
if (flEdgeWeightMax != BB_ZERO_WEIGHT)
25982618
{
25992619
// We will raise flEdgeWeightMin and Max towards newWeight
26002620
flEdgeWeightMin = flEdgeWeightMax;
26012621
flEdgeWeightMax = newWeight;
26022622
}
2603-
2604-
if (wbUsedSlop != nullptr)
2605-
{
2606-
*wbUsedSlop = true;
2607-
}
26082623
}
26092624
}
26102625
else if (flEdgeWeightMin > newWeight)
@@ -2613,33 +2628,34 @@ bool flowList::setEdgeWeightMinChecked(BasicBlock::weight_t newWeight,
26132628
// is more than newWeight, so we just allow for the slop
26142629
if ((newWeight + slop) >= flEdgeWeightMin)
26152630
{
2616-
result = true;
2631+
result = true;
2632+
usedSlop = true;
26172633

26182634
if (flEdgeWeightMax != BB_ZERO_WEIGHT)
26192635
{
26202636
// We will lower flEdgeWeightMin towards newWeight
2621-
flEdgeWeightMin = newWeight;
2622-
}
2623-
2624-
if (wbUsedSlop != nullptr)
2625-
{
2626-
*wbUsedSlop = true;
2637+
// But not below zero.
2638+
//
2639+
flEdgeWeightMin = max(BB_ZERO_WEIGHT, newWeight);
26272640
}
26282641
}
26292642
}
26302643

26312644
// If we are returning true then we should have adjusted the range so that
26322645
// the newWeight is in new range [Min..Max] or fgEdgeWeightMax is zero.
2633-
// Also we should have set wbUsedSlop to true.
2646+
//
26342647
if (result)
26352648
{
26362649
assert((flEdgeWeightMax == BB_ZERO_WEIGHT) ||
26372650
((newWeight <= flEdgeWeightMax) && (newWeight >= flEdgeWeightMin)));
2638-
2639-
assert((wbUsedSlop == nullptr) || (*wbUsedSlop));
26402651
}
26412652
}
26422653

2654+
if (result && usedSlop && (wbUsedSlop != nullptr))
2655+
{
2656+
*wbUsedSlop = true;
2657+
}
2658+
26432659
#if DEBUG
26442660
if (result)
26452661
{
@@ -2677,7 +2693,26 @@ bool flowList::setEdgeWeightMaxChecked(BasicBlock::weight_t newWeight,
26772693
BasicBlock::weight_t slop,
26782694
bool* wbUsedSlop)
26792695
{
2696+
// Negative weights are nonsensical.
2697+
//
2698+
// If we can't cover the deficit with slop, fail.
2699+
// If we can, set the new weight to zero.
2700+
//
2701+
bool usedSlop = false;
2702+
2703+
if (newWeight < BB_ZERO_WEIGHT)
2704+
{
2705+
if ((newWeight + slop) < BB_ZERO_WEIGHT)
2706+
{
2707+
return false;
2708+
}
2709+
2710+
newWeight = BB_ZERO_WEIGHT;
2711+
usedSlop = true;
2712+
}
2713+
26802714
bool result = false;
2715+
26812716
if ((newWeight >= flEdgeWeightMin) && (newWeight <= flEdgeWeightMax))
26822717
{
26832718
flEdgeWeightMax = newWeight;
@@ -2692,18 +2727,14 @@ bool flowList::setEdgeWeightMaxChecked(BasicBlock::weight_t newWeight,
26922727
// is less than newWeight, so we just allow for the slop
26932728
if (newWeight <= (flEdgeWeightMax + slop))
26942729
{
2695-
result = true;
2730+
result = true;
2731+
usedSlop = true;
26962732

26972733
if (flEdgeWeightMax != BB_ZERO_WEIGHT)
26982734
{
26992735
// We will allow this to raise flEdgeWeightMax towards newWeight
27002736
flEdgeWeightMax = newWeight;
27012737
}
2702-
2703-
if (wbUsedSlop != nullptr)
2704-
{
2705-
*wbUsedSlop = true;
2706-
}
27072738
}
27082739
}
27092740
else if (flEdgeWeightMin > newWeight)
@@ -2712,34 +2743,32 @@ bool flowList::setEdgeWeightMaxChecked(BasicBlock::weight_t newWeight,
27122743
// is more than newWeight, so we just allow for the slop
27132744
if ((newWeight + slop) >= flEdgeWeightMin)
27142745
{
2715-
result = true;
2746+
result = true;
2747+
usedSlop = true;
27162748

27172749
if (flEdgeWeightMax != BB_ZERO_WEIGHT)
27182750
{
27192751
// We will allow this to lower flEdgeWeightMin and Max towards newWeight
27202752
flEdgeWeightMax = flEdgeWeightMin;
27212753
flEdgeWeightMin = newWeight;
27222754
}
2723-
2724-
if (wbUsedSlop != nullptr)
2725-
{
2726-
*wbUsedSlop = true;
2727-
}
27282755
}
27292756
}
27302757

27312758
// If we are returning true then we should have adjusted the range so that
27322759
// the newWeight is in new range [Min..Max] or fgEdgeWeightMax is zero
2733-
// Also we should have set wbUsedSlop to true, unless it is NULL
27342760
if (result)
27352761
{
27362762
assert((flEdgeWeightMax == BB_ZERO_WEIGHT) ||
27372763
((newWeight <= flEdgeWeightMax) && (newWeight >= flEdgeWeightMin)));
2738-
2739-
assert((wbUsedSlop == nullptr) || (*wbUsedSlop));
27402764
}
27412765
}
27422766

2767+
if (result && usedSlop && (wbUsedSlop != nullptr))
2768+
{
2769+
*wbUsedSlop = true;
2770+
}
2771+
27432772
#if DEBUG
27442773
if (result)
27452774
{

0 commit comments

Comments
 (0)