summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorTAKAI Kousuke <62541129+t-a-k@users.noreply.github.com>2021-10-08 22:58:54 +0900
committerTony Cook <tony@develop-help.com>2021-12-09 11:05:49 +1100
commit51c06fb2bfe238bf76b0ec0da3175c04f4bea2f2 (patch)
tree786e21dced5eb3f795ea12571003aae2b8622935 /pp.c
parent6f14d737160321a4a1a0db2950833b64a317d637 (diff)
downloadperl-51c06fb2bfe238bf76b0ec0da3175c04f4bea2f2.tar.gz
Simplify IV abs operation in pp_abs.
Transforming -iv into "(UV)-(iv + 1) + 1" can avoid signed integer overflow even if iv was IV_MIN in 2's compelement representation (as long as iv < 0), so that it makes special treatment for IV_MIN unnecessary and saves one conditional jump.
Diffstat (limited to 'pp.c')
-rw-r--r--pp.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/pp.c b/pp.c
index 25d3a319cd..643a8758b7 100644
--- a/pp.c
+++ b/pp.c
@@ -3047,13 +3047,12 @@ PP(pp_abs)
if (iv >= 0) {
uv = (UV)iv;
} else {
- if (iv != IV_MIN) {
- uv = (UV)-iv;
- } else {
- /* 2s complement assumption. Also, not really needed as
- IV_MIN and -IV_MIN should both be %100...00 and NV-able */
- uv = (UV)IV_MIN;
- }
+ /* "(UV)-(iv + 1) + 1" below is mathematically "-iv", but
+ transformed so that every subexpression will never trigger
+ overflows even on 2's complement representation (note that
+ iv is always < 0 here), and modern compilers could optimize
+ this to a single negation. */
+ uv = (UV)-(iv + 1) + 1;
}
}
set_uv: