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

Craig Topper via cfe-commits cfe-commits at lists.llvm.org
Sun Mar 24 10:59:23 PDT 2019


Made a function in r356852

~Craig


On Sun, Mar 24, 2019 at 9:59 AM Nico Weber via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> 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
>>
> _______________________________________________
> 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/1cd96de3/attachment-0001.html>


More information about the cfe-commits mailing list