Branch: refs/heads/blead
  Home:   https://github.com/Perl/perl5
  Commit: 405e1a98a4a5172ebce2e014f040e62d0b32a0e9
      
https://github.com/Perl/perl5/commit/405e1a98a4a5172ebce2e014f040e62d0b32a0e9
  Author: Richard Leach <[email protected]>
  Date:   2026-01-20 (Tue, 20 Jan 2026)

  Changed paths:
    M pp_ctl.c

  Log Message:
  -----------
  pp_enteriter - skip fits-in-integer check for positive IVs!

`for ( X .. Y ) {}` ranges take values in IV range for X & Y.
(If X & Y are NVs or "look like numbers", the IV values are derived.)

The in-range check is performed on every call to `pp_enteriter` using
`S_outside_integer`, which derives the NV value for X & Y (calling
`sv_upgrade` if X & Y are not SVt_NV or SVt_PVNV+), and performs multiple
checks on the NV values to see if they fit within IV range.

However, if X & Y are `SvIOK_notUV` then the values fit within IV range
by definition and the whole `S_outside_integer` work is unnecessary.
This commit adds a hot branch that checks for `SvIOK_notUV` X & Y with
values `> -1` and skips `S_outside_integer` if the checks are successful.

The `> -1` checks seem like they shouldn't be necessary (again, if it's
an SvIOK_notUV, by definition the value fits in an IV), but are there
to workaround introducing test failures in t/op/range.t. (This attempts
to confirm that test values just below IV_MIN are not accepted in
parsing, but because of NV imprecision, seems to expect some wrong
results. `> -1` is an arbitrary chosen constraint that fits the bill.)

_Gcov_ of a perl build and test_harness run shows this hot branch
predominating:

```
  6056933: 2682:            if (SvIOK_notUV(sv) && SvIVX(sv) > -1 &&
  6048750: 2683:                SvIOK_notUV(right) && SvIVX(right) > -1) {
  6044776: 2684:                cx->cx_type |= CXt_LOOP_LAZYIV;
  6044776: 2685:                cx->blk_loop.state_u.lazyiv.cur = SvIVX(sv);
  6044776: 2686:                cx->blk_loop.state_u.lazyiv.end = SvIVX(right);
  6044776: 2687:                rpp_popfree_2_NN();
        -: 2688:            }
    12157: 2689:            else if (RANGE_IS_NUMERIC(sv,right)) {
    12097: 2690:                cx->cx_type |= CXt_LOOP_LAZYIV;
    24183: 2691:                if (S_outside_integer(aTHX_ sv) ||
    12086: 2692:                    S_outside_integer(aTHX_ right))
       22: 2693:                    DIE(aTHX_ "Range iterator outside integer 
range");
    12075: 2694:                cx->blk_loop.state_u.lazyiv.cur = SvIV_nomg(sv);
    12075: 2695:                cx->blk_loop.state_u.lazyiv.end = 
SvIV_nomg(right);
    12075: 2696:                rpp_popfree_2_NN();
        -: 2697:            }
```

perf confirms:
* eliminated calls to `S_outside_integer`, Perl_sv_2nv_flags, `Perl_isinfnan`
* Perl_pp_enteriter also runs slightly faster.



To unsubscribe from these emails, change your notification settings at 
https://github.com/Perl/perl5/settings/notifications

Reply via email to