diff options
author | TAKAI Kousuke <62541129+t-a-k@users.noreply.github.com> | 2021-10-08 22:58:54 +0900 |
---|---|---|
committer | Tony Cook <tony@develop-help.com> | 2021-12-09 11:05:49 +1100 |
commit | 51c06fb2bfe238bf76b0ec0da3175c04f4bea2f2 (patch) | |
tree | 786e21dced5eb3f795ea12571003aae2b8622935 /pp.c | |
parent | 6f14d737160321a4a1a0db2950833b64a317d637 (diff) | |
download | perl-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.c | 13 |
1 files changed, 6 insertions, 7 deletions
@@ -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: |