Skip to content

Commit 07b0630

Browse files
EgorBoCopilot
andauthored
Improve RangeOps::Merge (#129390)
Fold more bound checks with up to -110k [diffs](https://dev.azure.com/dnceng-public/public/_build/results?buildId=1463553&view=ms.vss-build-web.run-extensions-tab) RangeOps::Merge is typically used when we merge ranges from PHI args, e,g, `[0..1] U [10..10]` becomes` [0..10]` > [!NOTE] > This PR was authored with assistance from GitHub Copilot CLI (AI). The change was validated locally via SuperPMI asmdiffs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent d04703b commit 07b0630

1 file changed

Lines changed: 9 additions & 5 deletions

File tree

src/coreclr/jit/rangecheck.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -616,23 +616,27 @@ struct RangeOps
616616
// and we have to be careful by not masking possible overflows.
617617

618618
// Widen Upper Limit => Max(k, ($bnd + n)) yields ($bnd + n),
619-
// This is correct if k >= 0 and n >= k, since $bnd always >= 0
619+
// This is correct if n >= k, since $bnd always >= 0 (so $bnd + n >= n >= k).
620620
// ($bnd + n) could overflow, but the result ($bnd + n) also
621621
// preserves the overflow.
622622
//
623-
if (r1hi.IsConstant() && r1hi.GetConstant() >= 0 && r2hi.IsBinOpArray() &&
624-
r2hi.GetConstant() >= r1hi.GetConstant())
623+
if (r1hi.IsConstant() && r2hi.IsBinOpArray() && r2hi.GetConstant() >= r1hi.GetConstant())
625624
{
626625
result.uLimit = r2hi;
627626
}
628-
if (r2hi.IsConstant() && r2hi.GetConstant() >= 0 && r1hi.IsBinOpArray() &&
629-
r1hi.GetConstant() >= r2hi.GetConstant())
627+
if (r2hi.IsConstant() && r1hi.IsBinOpArray() && r1hi.GetConstant() >= r2hi.GetConstant())
630628
{
631629
result.uLimit = r1hi;
632630
}
633631

634632
// Rule: <$bnd + cns1, ...> U <cns2, ...> = <min(cns1, cns2), ...> when cns1 <= 0
635633
//
634+
// $bnd is always >= 0, so when cns1 <= 0 the expression ($bnd + cns1) cannot overflow and
635+
// its smallest value is exactly cns1, making min(cns1, cns2) a sound lower bound. We must
636+
// keep the cns1 <= 0 guard: for cns1 > 0, ($bnd + cns1) can overflow (e.g. a Span length is
637+
// bounded by INT_MAX, so $bnd + 1 may wrap to INT_MIN), which would make the collapsed
638+
// constant an unsound (too-high) lower bound.
639+
//
636640
// Example: <$bnd - 3, ...> U <0, ...> = <-3, ...>
637641
//
638642
if (r1lo.IsBinOpArray() && r2lo.IsConstant() && (r1lo.cns <= 0))

0 commit comments

Comments
 (0)