summaryrefslogtreecommitdiff
path: root/pp_hot.c
diff options
context:
space:
mode:
authorTomasz Konojacki <me@xenu.pl>2018-11-21 09:26:31 +0100
committerDavid Mitchell <davem@iabyn.com>2018-11-21 12:39:09 +0000
commitad9b9a4926e4b0d348c048937df69e382f7e6d27 (patch)
treec7b0cc925a06b868b7b1fbedfe79c8f85c652ac0 /pp_hot.c
parent9ba9a28aaea66bad2de041880a2c4210a911dda6 (diff)
downloadperl-ad9b9a4926e4b0d348c048937df69e382f7e6d27.tar.gz
optimize IV -> UV conversions
This commit replaces all instances of code that looks like this: uv = (iv == IV_MIN) ? (UV)iv : (UV)(-iv) with simpler and more optimal: uv = -(UV)iv While -iv indeed results in an undefined behaviour when iv == IV_MIN, -(UV)iv is perfectly well defined and does the right thing. C standard guarantees that the result of (UV)iv (for negative iv) is equal to iv + UV_MAX + 1 (see 6.3.1.3, paragraph 2 in C11). It also guarantees that the result of -uv is UV_MAX - uv + 1 (6.2.5, paragraph 9). That means that the result of -(UV)iv is UV_MAX - (iv + UV_MAX + 1) + 1 which is equal to -iv for *all* possible negative values of iv. [perl #133677]
Diffstat (limited to 'pp_hot.c')
-rw-r--r--pp_hot.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/pp_hot.c b/pp_hot.c
index dc02612042..ace5f0208b 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1521,7 +1521,7 @@ PP(pp_add)
auv = aiv;
auvok = 1; /* Now acting as a sign flag. */
} else {
- auv = (aiv == IV_MIN) ? (UV)aiv : (UV)(-aiv);
+ auv = -(UV)aiv;
}
}
a_valid = 1;
@@ -1541,7 +1541,7 @@ PP(pp_add)
buv = biv;
buvok = 1;
} else
- buv = (biv == IV_MIN) ? (UV)biv : (UV)(-biv);
+ buv = -(UV)biv;
}
/* ?uvok if value is >= 0. basically, flagged as UV if it's +ve,
else "IV" now, independent of how it came in.