r356848 - [X86] Add BSR/BSF/BSWAP intrinsics to ia32intrin.h to match gcc.

Nico Weber via cfe-commits cfe-commits at lists.llvm.org
Sun Mar 24 09:59:10 PDT 2019


This breaks Chromium's build. We have a class with a _bswap method, and
this adds a _bswap macro expanding to something that gets in the way. Could
_bswap be an inline function instead?

https://bugs.chromium.org/p/chromium/issues/detail?id=945172

On Sat, Mar 23, 2019 at 8:55 PM Craig Topper via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: ctopper
> Date: Sat Mar 23 17:56:52 2019
> New Revision: 356848
>
> URL: http://llvm.org/viewvc/llvm-project?rev=356848&view=rev
> Log:
> [X86] Add BSR/BSF/BSWAP intrinsics to ia32intrin.h to match gcc.
>
> Summary:
> These are all implemented by icc as well.
>
> I made bit_scan_forward/reverse forward to the __bsfd/__bsrq since we also
> have
> __bsfq/__bsrq.
>
> Note, when lzcnt is enabled the bsr intrinsics generates lzcnt+xor instead
> of bsr.
>
> Reviewers: RKSimon, spatel
>
> Subscribers: cfe-commits, llvm-commits
>
> Tags: #clang
>
> Differential Revision: https://reviews.llvm.org/D59682
>
> Added:
>     cfe/trunk/test/CodeGen/x86-bswap.c
> Modified:
>     cfe/trunk/lib/Headers/ia32intrin.h
>     cfe/trunk/lib/Headers/immintrin.h
>     cfe/trunk/test/CodeGen/bitscan-builtins.c
>
> Modified: cfe/trunk/lib/Headers/ia32intrin.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/ia32intrin.h?rev=356848&r1=356847&r2=356848&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Headers/ia32intrin.h (original)
> +++ cfe/trunk/lib/Headers/ia32intrin.h Sat Mar 23 17:56:52 2019
> @@ -28,6 +28,114 @@
>  #ifndef __IA32INTRIN_H
>  #define __IA32INTRIN_H
>
> +/** Find the first set bit starting from the lsb. Result is undefined if
> + *  input is 0.
> + *
> + *  \headerfile <x86intrin.h>
> + *
> + *  This intrinsic corresponds to the <c> BSF </c> instruction or the
> + *  <c> TZCNT </c> instruction.
> + *
> + *  \param __A
> + *     A 32-bit integer operand.
> + *  \returns A 32-bit integer containing the bit number.
> + */
> +static __inline__ int __attribute__((__always_inline__, __nodebug__))
> +__bsfd(int __A) {
> +  return __builtin_ctz(__A);
> +}
> +
> +/** Find the first set bit starting from the msb. Result is undefined if
> + *  input is 0.
> + *
> + *  \headerfile <x86intrin.h>
> + *
> + *  This intrinsic corresponds to the <c> BSR </c> instruction or the
> + *  <c> LZCNT </c> instruction and an <c> XOR </c>.
> + *
> + *  \param __A
> + *     A 32-bit integer operand.
> + *  \returns A 32-bit integer containing the bit number.
> + */
> +static __inline__ int __attribute__((__always_inline__, __nodebug__))
> +__bsrd(int __A) {
> +  return 31 - __builtin_clz(__A);
> +}
> +
> +/** Swaps the bytes in the input. Converting little endian to big endian
> or
> + *  vice versa.
> + *
> + *  \headerfile <x86intrin.h>
> + *
> + *  This intrinsic corresponds to the <c> BSWAP </c> instruction.
> + *
> + *  \param __A
> + *     A 32-bit integer operand.
> + *  \returns A 32-bit integer containing the swapped bytes.
> + */
> +static __inline__ int __attribute__((__always_inline__, __nodebug__))
> +__bswapd(int __A) {
> +  return __builtin_bswap32(__A);
> +}
> +
> +#define _bswap(A) __bswapd((A))
> +#define _bit_scan_forward(A) __bsfd((A))
> +#define _bit_scan_reverse(A) __bsrd((A))
> +
> +#ifdef __x86_64__
> +/** Find the first set bit starting from the lsb. Result is undefined if
> + *  input is 0.
> + *
> + *  \headerfile <x86intrin.h>
> + *
> + *  This intrinsic corresponds to the <c> BSF </c> instruction or the
> + *  <c> TZCNT </c> instruction.
> + *
> + *  \param __A
> + *     A 64-bit integer operand.
> + *  \returns A 32-bit integer containing the bit number.
> + */
> +static __inline__ int __attribute__((__always_inline__, __nodebug__))
> +__bsfq(long long __A) {
> +  return __builtin_ctzll(__A);
> +}
> +
> +/** Find the first set bit starting from the msb. Result is undefined if
> + *  input is 0.
> + *
> + *  \headerfile <x86intrin.h>
> + *
> + *  This intrinsic corresponds to the <c> BSR </c> instruction or the
> + *  <c> LZCNT </c> instruction and an <c> XOR </c>.
> + *
> + *  \param __A
> + *     A 64-bit integer operand.
> + *  \returns A 32-bit integer containing the bit number.
> + */
> +static __inline__ int __attribute__((__always_inline__, __nodebug__))
> +__bsrq(long long __A) {
> +  return 63 - __builtin_clzll(__A);
> +}
> +
> +/** Swaps the bytes in the input. Converting little endian to big endian
> or
> + *  vice versa.
> + *
> + *  \headerfile <x86intrin.h>
> + *
> + *  This intrinsic corresponds to the <c> BSWAP </c> instruction.
> + *
> + *  \param __A
> + *     A 64-bit integer operand.
> + *  \returns A 64-bit integer containing the swapped bytes.
> + */
> +static __inline__ long long __attribute__((__always_inline__,
> __nodebug__))
> +__bswapq(long long __A) {
> +  return __builtin_bswap64(__A);
> +}
> +
> +#define _bswap64(A) __bswapq((A))
> +#endif
> +
>  /** Counts the number of bits in the source operand having a value of 1.
>   *
>   *  \headerfile <x86intrin.h>
>
> Modified: cfe/trunk/lib/Headers/immintrin.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/immintrin.h?rev=356848&r1=356847&r2=356848&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Headers/immintrin.h (original)
> +++ cfe/trunk/lib/Headers/immintrin.h Sat Mar 23 17:56:52 2019
> @@ -241,18 +241,6 @@ _rdrand64_step(unsigned long long *__p)
>  #endif
>  #endif /* __RDRND__ */
>
> -/* __bit_scan_forward */
> -static __inline__ int __attribute__((__always_inline__, __nodebug__))
> -_bit_scan_forward(int __A) {
> -  return __builtin_ctz(__A);
> -}
> -
> -/* __bit_scan_reverse */
> -static __inline__ int __attribute__((__always_inline__, __nodebug__))
> -_bit_scan_reverse(int __A) {
> -  return 31 - __builtin_clz(__A);
> -}
> -
>  #if !defined(_MSC_VER) || __has_feature(modules) || defined(__FSGSBASE__)
>  #ifdef __x86_64__
>  static __inline__ unsigned int __attribute__((__always_inline__,
> __nodebug__, __target__("fsgsbase")))
>
> Modified: cfe/trunk/test/CodeGen/bitscan-builtins.c
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/bitscan-builtins.c?rev=356848&r1=356847&r2=356848&view=diff
>
> ==============================================================================
> --- cfe/trunk/test/CodeGen/bitscan-builtins.c (original)
> +++ cfe/trunk/test/CodeGen/bitscan-builtins.c Sat Mar 23 17:56:52 2019
> @@ -3,18 +3,45 @@
>  // PR33722
>  // RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-unknown
> -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -o - %s |
> FileCheck %s
>
> -#include <immintrin.h>
> +#include <x86intrin.h>
>
>  int test_bit_scan_forward(int a) {
>    return _bit_scan_forward(a);
>  // CHECK: @test_bit_scan_forward
> -// CHECK: %[[call:.*]] = call i32 @llvm.cttz.i32(
> +// CHECK: %[[call:.*]] = call i32 @llvm.cttz.i32(i32 %{{.*}}, i1 true)
>  // CHECK: ret i32 %[[call]]
>  }
>
>  int test_bit_scan_reverse(int a) {
>    return _bit_scan_reverse(a);
> -// CHECK:  %[[call:.*]] = call i32 @llvm.ctlz.i32(
> +// CHECK:  %[[call:.*]] = call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 true)
>  // CHECK:  %[[sub:.*]] = sub nsw i32 31, %[[call]]
>  // CHECK: ret i32 %[[sub]]
>  }
> +
> +int test__bsfd(int X) {
> +// CHECK: @test__bsfd
> +// CHECK: %[[call:.*]] = call i32 @llvm.cttz.i32(i32 %{{.*}}, i1 true)
> +  return __bsfd(X);
> +}
> +
> +int test__bsfq(long long X) {
> +// CHECK: @test__bsfq
> +// CHECK: %[[call:.*]] = call i64 @llvm.cttz.i64(i64 %{{.*}}, i1 true)
> +  return __bsfq(X);
> +}
> +
> +int test__bsrd(int X) {
> +// CHECK: @test__bsrd
> +// CHECK:  %[[call:.*]] = call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 true)
> +// CHECK:  %[[sub:.*]] = sub nsw i32 31, %[[call]]
> +  return __bsrd(X);
> +}
> +
> +int test__bsrq(long long X) {
> +// CHECK: @test__bsrq
> +// CHECK:  %[[call:.*]] = call i64 @llvm.ctlz.i64(i64 %{{.*}}, i1 true)
> +// CHECK:  %[[cast:.*]] = trunc i64 %[[call]] to i32
> +// CHECK:  %[[sub:.*]] = sub nsw i32 63, %[[cast]]
> +  return __bsrq(X);
> +}
>
> Added: cfe/trunk/test/CodeGen/x86-bswap.c
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86-bswap.c?rev=356848&view=auto
>
> ==============================================================================
> --- cfe/trunk/test/CodeGen/x86-bswap.c (added)
> +++ cfe/trunk/test/CodeGen/x86-bswap.c Sat Mar 23 17:56:52 2019
> @@ -0,0 +1,29 @@
> +// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin
> -emit-llvm -o - | FileCheck %s
> +
> +#include <x86intrin.h>
> +
> +int test__bswapd(int X) {
> +// CHECK-LABEL: @test__bswapd
> +// CHECK: call i32 @llvm.bswap.i32
> +  return __bswapd(X);
> +}
> +
> +int test_bswap(int X) {
> +// CHECK-LABEL: @test_bswap
> +// CHECK: call i32 @llvm.bswap.i32
> +  return _bswap(X);
> +}
> +
> +long test__bswapq(long long X) {
> +// CHECK-LABEL: @test__bswapq
> +// CHECK: call i64 @llvm.bswap.i64
> +  return __bswapq(X);
> +}
> +
> +long test_bswap64(long long X) {
> +// CHECK-LABEL: @test_bswap64
> +// CHECK: call i64 @llvm.bswap.i64
> +  return _bswap64(X);
> +}
> +
> +
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190324/1e96ab1e/attachment-0001.html>


More information about the cfe-commits mailing list