Skip to content

Commit 9545f62

Browse files
committed
Improve RangeOps::Merge and tightenLimit
1 parent 659321f commit 9545f62

2 files changed

Lines changed: 44 additions & 8 deletions

File tree

src/coreclr/jit/rangecheck.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -996,8 +996,9 @@ void RangeCheck::MergeEdgeAssertions(Compiler* comp,
996996
return l2;
997997
}
998998

999-
// Otherwise, prefer the BinOpArray(preferredBound) over the constant.
1000-
return l1;
999+
// Otherwise, prefer the BinOpArray(preferredBound) over the constant for the upper bound
1000+
// and the constant for the lower bound.
1001+
return isLower ? l2 : l1;
10011002
}
10021003
unreached();
10031004
};

src/coreclr/jit/rangecheck.h

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -524,14 +524,49 @@ struct RangeOps
524524
{
525525
result.uLimit = r1hi;
526526
}
527+
528+
// <$bnd + cns1, ...> U <cns2, ...> = <min(cns1, cns2), ...> when cns1 <= 0
529+
// where "cns1 <= 0" to avoid masking possible overflow.
530+
// We rely on the fact that $bnd is always >= 0.
531+
//
532+
// Example: <$bnd - 3, ...> U <0, ...> = <-3, ...>
533+
if (r1lo.IsBinOpArray() && r2lo.IsConstant() && (r1lo.cns <= 0))
534+
{
535+
result.lLimit = Limit(Limit::keConstant, min(r1lo.cns, r2lo.cns));
536+
}
537+
if (r2lo.IsBinOpArray() && r1lo.IsConstant() && (r2lo.cns <= 0))
538+
{
539+
result.lLimit = Limit(Limit::keConstant, min(r2lo.cns, r1lo.cns));
540+
}
541+
542+
// <$bnd + cns1, ...> U <cns2, ...> = <$bnd + cns1, ...> when cns1 >= cns2
543+
// Possible overflow is preserved in the result.
544+
// We rely on the fact that $bnd is always >= 0.
545+
//
546+
// Example: <$bnd + 10, ...> U <1, ...> = <$bnd + 10, ...>
547+
if (r1lo.IsBinOpArray() && r2lo.IsConstant() && (r1lo.cns >= r2lo.cns))
548+
{
549+
result.lLimit = r1lo;
550+
}
551+
if (r2lo.IsBinOpArray() && r1lo.IsConstant() && (r2lo.cns >= r1lo.cns))
552+
{
553+
result.lLimit = r2lo;
554+
}
555+
556+
// <..., $bnd + cns1> U <..., $bnd + cns2> = <..., $bnd + max(cns1, cns2)>
557+
//
558+
// Example: <..., $bnd + 10> U <..., $bnd + 20> = <..., $bnd + 20>
527559
if (r1hi.IsBinOpArray() && r2hi.IsBinOpArray() && r1hi.vn == r2hi.vn)
528560
{
529-
result.uLimit = r1hi;
530-
// Widen the upper bound if the other constant is greater.
531-
if (r2hi.GetConstant() > r1hi.GetConstant())
532-
{
533-
result.uLimit = r2hi;
534-
}
561+
result.uLimit.cns = max(r1hi.cns, r2hi.cns);
562+
}
563+
564+
// <$bnd + cns1, ...> U <$bnd + cns2, ...> = <$bnd + min(cns1, cns2), ...>
565+
//
566+
// Example: <$bnd + 10, ...> U <$bnd + 20, ...> = <$bnd + 10, ...>
567+
if (r1lo.IsBinOpArray() && r2lo.IsBinOpArray() && r1lo.vn == r2lo.vn)
568+
{
569+
result.lLimit.cns = min(r1lo.cns, r2lo.cns);
535570
}
536571
return result;
537572
}

0 commit comments

Comments
 (0)