[utils] Fix undefined behavior in Abs helper.
This fixes undefined behavior in the arithmetic negation operation by switching to a branch-free implementation. R=clemensh@chromium.org TEST=unittests/MachineOperatorReducerTest.Int32DivWithConstant Change-Id: I518f0e4343fc331607b8bbeefd2bb06285621fe6 Reviewed-on: https://chromium-review.googlesource.com/584870 Reviewed-by: Clemens Hammacher <clemensh@chromium.org> Commit-Queue: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#46905}
This commit is contained in:
parent
fdf28c7bea
commit
a4663baa42
10
src/utils.h
10
src/utils.h
@ -185,9 +185,15 @@ T JSMin(T x, T y) {
|
||||
|
||||
// Returns the absolute value of its argument.
|
||||
template <typename T,
|
||||
typename = typename std::enable_if<std::is_integral<T>::value>::type>
|
||||
typename = typename std::enable_if<std::is_signed<T>::value>::type>
|
||||
typename std::make_unsigned<T>::type Abs(T a) {
|
||||
return a < 0 ? -a : a;
|
||||
// This is a branch-free implementation of the absolute value function and is
|
||||
// described in Warren's "Hacker's Delight", chapter 2. It avoids undefined
|
||||
// behavior with the arithmetic negation operation on signed values as well.
|
||||
typedef typename std::make_unsigned<T>::type unsignedT;
|
||||
unsignedT x = static_cast<unsignedT>(a);
|
||||
unsignedT y = static_cast<unsignedT>(a >> (sizeof(T) * 8 - 1));
|
||||
return (x ^ y) - y;
|
||||
}
|
||||
|
||||
// Floor(-0.0) == 0.0
|
||||
|
Loading…
Reference in New Issue
Block a user