craig.topper created this revision.
craig.topper added reviewers: RKSimon, spatel.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

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.


Repository:
  rC Clang

https://reviews.llvm.org/D59682

Files:
  lib/Headers/ia32intrin.h
  lib/Headers/immintrin.h
  test/CodeGen/bitscan-builtins.c
  test/CodeGen/x86-bswap.c

Index: test/CodeGen/x86-bswap.c
===================================================================
--- /dev/null
+++ test/CodeGen/x86-bswap.c
@@ -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);
+}
+
+
Index: test/CodeGen/bitscan-builtins.c
===================================================================
--- test/CodeGen/bitscan-builtins.c
+++ test/CodeGen/bitscan-builtins.c
@@ -3,7 +3,7 @@
 // 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);
@@ -18,3 +18,30 @@
 // 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(
+  return __bsfd(X);
+}
+
+int test__bsfq(long long X) {
+// CHECK: @test__bsfq
+// CHECK: %[[call:.*]] = call i64 @llvm.cttz.i64(
+  return __bsfq(X);
+}
+
+int test__bsrd(int X) {
+// CHECK: @test__bsrd
+// CHECK:  %[[call:.*]] = call i32 @llvm.ctlz.i32(
+// 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(
+// CHECK:  %[[cast:.*]] = trunc i64 %[[call]] to i32
+// CHECK:  %[[sub:.*]] = sub nsw i32 63, %[[cast]]
+  return __bsrq(X);
+}
Index: lib/Headers/immintrin.h
===================================================================
--- lib/Headers/immintrin.h
+++ lib/Headers/immintrin.h
@@ -241,18 +241,6 @@
 #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")))
Index: lib/Headers/ia32intrin.h
===================================================================
--- lib/Headers/ia32intrin.h
+++ lib/Headers/ia32intrin.h
@@ -28,6 +28,44 @@
 #ifndef __IA32INTRIN_H
 #define __IA32INTRIN_H
 
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+__bsfd(int __A) {
+  return __builtin_ctz(__A);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+__bsrd(int __A) {
+  return 31 - __builtin_clz(__A);
+}
+
+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__
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+__bsfq(long long __A) {
+  return __builtin_ctzll(__A);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+__bsrq(long long __A) {
+  return 63 - __builtin_clzll(__A);
+}
+
+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>
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to