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