summaryrefslogtreecommitdiffstats
path: root/lib/Headers/bmiintrin.h
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2014-11-01 22:50:54 +0000
committerCraig Topper <craig.topper@gmail.com>2014-11-01 22:50:54 +0000
commitd520349ab94cfa8814291e4eec3a9200fde47dd1 (patch)
tree0d7bad4c0f693d1f16ec29585b4753a179f7df94 /lib/Headers/bmiintrin.h
parentfd2bb3d314deec4d2c6dfd036db8d401ec5b16bc (diff)
Avoid undefined behavior in the x86 bmi header file by explicitly checking for 0 before calling __builtin_ctz. 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.cttz with defined zero behavior.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@221065 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Headers/bmiintrin.h')
-rw-r--r--lib/Headers/bmiintrin.h6
1 files changed, 3 insertions, 3 deletions
diff --git a/lib/Headers/bmiintrin.h b/lib/Headers/bmiintrin.h
index 43c4a5e5de..0e5fd5551f 100644
--- a/lib/Headers/bmiintrin.h
+++ b/lib/Headers/bmiintrin.h
@@ -43,7 +43,7 @@
static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
__tzcnt_u16(unsigned short __X)
{
- return __builtin_ctzs(__X);
+ return __X ? __builtin_ctzs(__X) : 16;
}
static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
@@ -87,7 +87,7 @@ __blsr_u32(unsigned int __X)
static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
__tzcnt_u32(unsigned int __X)
{
- return __builtin_ctz(__X);
+ return __X ? __builtin_ctz(__X) : 32;
}
#ifdef __x86_64__
@@ -140,7 +140,7 @@ __blsr_u64(unsigned long long __X)
static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
__tzcnt_u64(unsigned long long __X)
{
- return __builtin_ctzll(__X);
+ return __X ? __builtin_ctzll(__X) : 64;
}
#endif /* __x86_64__ */