diff --git a/clang/include/clang/Basic/BuiltinsX86.def b/clang/include/clang/Basic/BuiltinsX86.def --- a/clang/include/clang/Basic/BuiltinsX86.def +++ b/clang/include/clang/Basic/BuiltinsX86.def @@ -1900,10 +1900,11 @@ TARGET_BUILTIN(__builtin_ia32_enqcmd, "Ucv*vC*", "n", "enqcmd") TARGET_BUILTIN(__builtin_ia32_enqcmds, "Ucv*vC*", "n", "enqcmd") -// MSVC -TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +// BITSCAN +TARGET_BUILTIN(_BitScanForward, "UcUNi*UNi", "n", "") +TARGET_BUILTIN(_BitScanReverse, "UcUNi*UNi", "n", "") +// MSVC TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_ReadBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_WriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") diff --git a/clang/include/clang/Basic/BuiltinsX86_64.def b/clang/include/clang/Basic/BuiltinsX86_64.def --- a/clang/include/clang/Basic/BuiltinsX86_64.def +++ b/clang/include/clang/Basic/BuiltinsX86_64.def @@ -21,9 +21,6 @@ # define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) #endif -TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") - TARGET_HEADER_BUILTIN(__mulh, "LLiLLiLLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_mul128, "LLiLLiLLiLLi*", "nch", "intrin.h", ALL_MS_LANGUAGES, "") @@ -43,6 +40,10 @@ TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128, "UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "cx16") +// BITSCAN +TARGET_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "n", "") +TARGET_BUILTIN(_BitScanReverse64, "UcUNi*ULLi", "n", "") + TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "UOi", "n", "") TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vUOi", "n", "") TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "OiV4f", "ncV:128:", "sse") diff --git a/clang/test/CodeGen/bitscan-builtins.c b/clang/test/CodeGen/bitscan-builtins.c --- a/clang/test/CodeGen/bitscan-builtins.c +++ b/clang/test/CodeGen/bitscan-builtins.c @@ -3,6 +3,46 @@ // PR33722 // RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-unknown -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -o - %s | FileCheck %s +// Using _BitScan* intrinsics should not need any header file, so the tests for +// them are placed before any include directive intentionally. +unsigned char test_BitScanForward(unsigned *index, unsigned mask) { + return _BitScanForward(index, mask); + // CHECK: @test_BitScanForward + // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}} + // CHECK: %[[result:.*]] = phi i8 [ 0, %{{.*}} ], [ 1, %{{.*}} ] + // CHECK: ret i8 %[[result]] + // CHECK: %{{.*}} = call i32 @llvm.cttz.i32(i32 %{{.*}}, i1 true) +} + +unsigned char test_BitScanForward64(unsigned *index, unsigned long long mask) { + return _BitScanForward64(index, mask); + // CHECK: @test_BitScanForward64 + // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}} + // CHECK: %[[result:.*]] = phi i8 [ 0, %{{.*}} ], [ 1, %{{.*}} ] + // CHECK: ret i8 %[[result]] + // CHECK: %{{.*}} = call i64 @llvm.cttz.i64(i64 %{{.*}}, i1 true) +} + +unsigned char test_BitScanReverse(unsigned *index, unsigned mask) { + return _BitScanReverse(index, mask); + // CHECK: @test_BitScanReverse + // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}} + // CHECK: %[[result:.*]] = phi i8 [ 0, %{{.*}} ], [ 1, %{{.*}} ] + // CHECK: ret i8 %[[result]] + // CHECK: %[[call:.*]] = call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 true) + // CHECK: %[[sub:.*]] = sub nsw i32 31, %[[call]] +} + +unsigned char test_BitScanReverse64(unsigned *index, unsigned long long mask) { + return _BitScanReverse64(index, mask); + // CHECK: @test_BitScanReverse64 + // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}} + // CHECK: %[[result:.*]] = phi i8 [ 0, %{{.*}} ], [ 1, %{{.*}} ] + // CHECK: ret i8 %[[result]] + // CHECK: %{{.*}} = call i64 @llvm.ctlz.i64(i64 %{{.*}}, i1 true) + // CHECK: %{{.*}} = sub nsw i32 63, %{{.*}} +} + #include int test_bit_scan_forward(int a) {