From ac5e48f8338d7ce44a94d55d0bda2f8252c01fa6 Mon Sep 17 00:00:00 2001 From: TAKAI Kousuke <62541129+t-a-k@users.noreply.github.com> Date: Wed, 7 May 2025 23:34:13 +0900 Subject: [PATCH 1/3] sv.h: Make SvIsUV() return 1 (rather than 0x80000000) for true condition This would make it easier to receive the result with `bool` type. Note that (implicit) casting to C99 `_Bool` automatically converts any nonzero scalar values to 1, so that this change is technically not necessary in C99 which perl now requires to compile. But I think it will keep the code less surprising. --- sv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sv.h b/sv.h index 69cb8e2a99d8..29f81f907c18 100644 --- a/sv.h +++ b/sv.h @@ -1045,7 +1045,7 @@ Set the size of the string buffer for the SV. See C>. #define BOOL_INTERNALS_sv_isbool_false(sv) (SvIsCOW_static(sv) && \ (SvPVX_const(sv) == PL_No)) -#define SvIsUV(sv) (SvFLAGS(sv) & SVf_IVisUV) +#define SvIsUV(sv) ((SvFLAGS(sv) & SVf_IVisUV) != 0) #define SvIsUV_on(sv) (SvFLAGS(sv) |= SVf_IVisUV) #define SvIsUV_off(sv) (SvFLAGS(sv) &= ~SVf_IVisUV) From 9a330bd0d92fa6de483c3c79726dbd1defe40223 Mon Sep 17 00:00:00 2001 From: TAKAI Kousuke <62541129+t-a-k@users.noreply.github.com> Date: Thu, 8 May 2025 01:11:28 +0900 Subject: [PATCH 2/3] pp.c, pp_hot.c: Use SvIsUV rather than SvUOK after SvIV_please_nomg SvUOK(x) inside a block guarded by SvIV_please_nomg(x) can be replaced by SvIsUV(x) because SvIV_please_nomg implies SvIOK. This will save a few code size and runtime CPU cycles, because many CPUs can do single-bit tests like SvIsUV in fewer instructions than multi-bit tests like SvUOK. --- pp.c | 26 +++++++++++++------------- pp_hot.c | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/pp.c b/pp.c index bcfa2744e44b..c23d9671cf09 100644 --- a/pp.c +++ b/pp.c @@ -1154,7 +1154,7 @@ PP(pp_pow) bool baseuok; UV baseuv; - if (SvUOK(svr)) { + if (SvIsUV(svr)) { power = SvUVX(svr); } else { const IV iv = SvIVX(svr); @@ -1165,7 +1165,7 @@ PP(pp_pow) } } - baseuok = SvUOK(svl); + baseuok = SvIsUV(svl); if (baseuok) { baseuv = SvUVX(svl); } else { @@ -1375,8 +1375,8 @@ PP(pp_multiply) we know the left is integer. */ /* Left operand is defined, so is it IV? */ if (SvIV_please_nomg(svl)) { - bool auvok = SvUOK(svl); - bool buvok = SvUOK(svr); + bool auvok = SvIsUV(svl); + bool buvok = SvIsUV(svr); UV alow; UV blow; UV product; @@ -1469,8 +1469,8 @@ PP(pp_divide) #ifdef PERL_TRY_UV_DIVIDE if (SvIV_please_nomg(svr) && SvIV_please_nomg(svl)) { - bool left_non_neg = SvUOK(svl); - bool right_non_neg = SvUOK(svr); + bool left_non_neg = SvIsUV(svl); + bool right_non_neg = SvIsUV(svr); UV left; UV right; @@ -1588,7 +1588,7 @@ PP(pp_modulo) SV * const svr = PL_stack_sp[0]; SV * const svl = PL_stack_sp[-1]; if (SvIV_please_nomg(svr)) { - right_neg = !SvUOK(svr); + right_neg = !SvIsUV(svr); if (!right_neg) { right = SvUVX(svr); } else { @@ -1618,7 +1618,7 @@ PP(pp_modulo) a UV. In range NV has been rounded down to nearest UV and use_double false. */ if (!use_double && SvIV_please_nomg(svl)) { - left_neg = !SvUOK(svl); + left_neg = !SvIsUV(svl); if (!left_neg) { left = SvUVX(svl); } else { @@ -1911,7 +1911,7 @@ PP(pp_subtract) } else { /* Left operand is defined, so is it IV? */ if (SvIV_please_nomg(svl)) { - if ((auvok = SvUOK(svl))) + if ((auvok = SvIsUV(svl))) auv = SvUVX(svl); else { const IV aiv = SvIVX(svl); @@ -1929,7 +1929,7 @@ PP(pp_subtract) bool result_good = 0; UV result; UV buv; - bool buvok = SvUOK(svr); + bool buvok = SvIsUV(svr); /* svr is always IOK here */ if (buvok) buv = SvUVX(svr); @@ -2248,9 +2248,9 @@ Perl_do_ncmp(pTHX_ SV* const left, SV * const right) #ifdef PERL_PRESERVE_IVUV /* Fortunately it seems NaN isn't IOK */ if (SvIV_please_nomg(right) && SvIV_please_nomg(left)) { - if (!SvUOK(left)) { + if (!SvIsUV(left)) { const IV leftiv = SvIVX(left); - if (!SvUOK(right)) { + if (!SvIsUV(right)) { /* ## IV <=> IV ## */ const IV rightiv = SvIVX(right); return (leftiv > rightiv) - (leftiv < rightiv); @@ -2265,7 +2265,7 @@ Perl_do_ncmp(pTHX_ SV* const left, SV * const right) } } - if (SvUOK(right)) { + if (SvIsUV(right)) { /* ## UV <=> UV ## */ const UV leftuv = SvUVX(left); const UV rightuv = SvUVX(right); diff --git a/pp_hot.c b/pp_hot.c index 89e0c8cbf9e2..b8ec0eb46875 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -1920,7 +1920,7 @@ PP(pp_add) } else { /* Left operand is defined, so is it IV? */ if (SvIV_please_nomg(svl)) { - if ((auvok = SvUOK(svl))) + if ((auvok = SvIsUV(svl))) auv = SvUVX(svl); else { const IV aiv = SvIVX(svl); @@ -1938,7 +1938,7 @@ PP(pp_add) bool result_good = 0; UV result; UV buv; - bool buvok = SvUOK(svr); + bool buvok = SvIsUV(svr); /* svr is always IOK here */ if (buvok) buv = SvUVX(svr); From 0b5d78ab5c976d5657ccdd321409467735fde326 Mon Sep 17 00:00:00 2001 From: TAKAI Kousuke <62541129+t-a-k@users.noreply.github.com> Date: Thu, 8 May 2025 01:21:10 +0900 Subject: [PATCH 3/3] hv.c: Use SvIsUV instead of SvUOK in the block where SvIOK holds true. Because SvUOK is essentially (SvIOK && SvIsUV), SvUOK is redundant in the block where SvIOK is guaranteed to hold true. --- hv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hv.c b/hv.c index 7959ec10acfb..e7bc0898b114 100644 --- a/hv.c +++ b/hv.c @@ -3856,7 +3856,7 @@ Perl_refcounted_he_new_pvn(pTHX_ struct refcounted_he *parent, } else if (SvPOK(value)) { value_type = HVrhek_PV; } else if (SvIOK(value)) { - value_type = SvUOK((const SV *)value) ? HVrhek_UV : HVrhek_IV; + value_type = SvIsUV(value) ? HVrhek_UV : HVrhek_IV; } else if (!SvOK(value)) { value_type = HVrhek_undef; } else {