summaryrefslogtreecommitdiffstats
path: root/lib/Headers/lzcntintrin.h
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2014-11-01 22:25:23 +0000
committerCraig Topper <craig.topper@gmail.com>2014-11-01 22:25:23 +0000
commitfd2bb3d314deec4d2c6dfd036db8d401ec5b16bc (patch)
treec15a3393bc8cc82734e819bc023b9f9926c46fad /lib/Headers/lzcntintrin.h
parent5e7180b8436993360d97b8d749f75cbdcc3967c4 (diff)
Avoid undefined behavior in the x86 lzcnt header file by explicitly checking for 0 before calling __builtin_clz. Without this the optimizers may take advantage of the undefined behavior and produce incorrect results. LLVM itself still needs to be taught to merge the zero check into the llvm.ctlz with defined zero behavior.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@221064 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Headers/lzcntintrin.h')
-rw-r--r--lib/Headers/lzcntintrin.h6
1 files changed, 3 insertions, 3 deletions
diff --git a/lib/Headers/lzcntintrin.h b/lib/Headers/lzcntintrin.h
index 62ab5ca2f3..5bb7435504 100644
--- a/lib/Headers/lzcntintrin.h
+++ b/lib/Headers/lzcntintrin.h
@@ -35,20 +35,20 @@
static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
__lzcnt16(unsigned short __X)
{
- return __builtin_clzs(__X);
+ return __X ? __builtin_clzs(__X) : 16;
}
static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
__lzcnt32(unsigned int __X)
{
- return __builtin_clz(__X);
+ return __X ? __builtin_clz(__X) : 32;
}
#ifdef __x86_64__
static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
__lzcnt64(unsigned long long __X)
{
- return __builtin_clzll(__X);
+ return __X ? __builtin_clzll(__X) : 64;
}
#endif