Remove undefined behavior from NextPowerOfTwo

This CL removes undefined behavior from NextPowerOfTwo(0). Currently on
Linux, calling NextPowerOfTwo(0) simplifies down to:
  - 1ull << (64 - __builtin_clzll(0 - 1));
  - 1ull << (64 - __builtin_clzll(INT_MAX));
  - 1ull << (64 - 0);
  - 1ull << 64

Since 64 is the same width as the long long in our left operand, this
left shift results in undefined behavior (C++11 standard 5.8.1). For a
default Chrome compile, this does not cause any issues; 1ull << 64
results in 0.

In ChromeOS, however, we compile with ThinLTO which, among other things,
inlines various functions in the interest of performance. When
NextPowerOfTwo is inlined, the undefined behavior of our invalid left
shift borks the stack which causes the Math.NextPowerOfTwo unit test to
fail.

BUG= chromium:993457
TEST= verified that Math.NextPowerOfTwo now passes with LTO

Change-Id: I2702ba0b780203643da1d98ad0380098c7b3eab0
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/10180
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Brian Ho <hob@chromium.org>
This commit is contained in:
Brian Ho 2019-08-16 18:44:14 +00:00 committed by Commit Bot service account
parent 09c12ca696
commit ee3de1e1f3
1 changed files with 1 additions and 1 deletions

View File

@ -63,7 +63,7 @@ uint64_t NextPowerOfTwo(uint64_t n) {
#if defined(DAWN_COMPILER_MSVC)
return n <= 1 ? 1 : 1ull << (64 - __lzcnt64(n - 1));
#else
return n == 1 ? 1 : 1ull << (64 - __builtin_clzll(n - 1));
return n <= 1 ? 1 : 1ull << (64 - __builtin_clzll(n - 1));
#endif
}