Author: rnk
Date: Mon Jun 4 18:33:40 2018
New Revision: 333978
URL: http://llvm.org/viewvc/llvm-project?rev=333978&view=rev
Log:
Reimplement the bittest intrinsic family as builtins with inline asm
We need to implement _interlockedbittestandset as a builtin for
windows.h, so we might as well do the whole family. It reduces code
duplication anyway.
Fixes PR33188, a long standing bug in our bittest implementation
encountered by Chakra.
Added:
cfe/trunk/test/CodeGen/bittest-intrin.c
Modified:
cfe/trunk/include/clang/Basic/Builtins.def
cfe/trunk/lib/CodeGen/CGBuiltin.cpp
cfe/trunk/lib/Headers/intrin.h
cfe/trunk/test/CodeGen/ms-intrinsics-other.c
cfe/trunk/test/CodeGen/ms-intrinsics.c
Modified: cfe/trunk/include/clang/Basic/Builtins.def
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=333978&r1=333977&r2=333978&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Builtins.def (original)
+++ cfe/trunk/include/clang/Basic/Builtins.def Mon Jun 4 18:33:40 2018
@@ -744,6 +744,14 @@ BUILTIN(__builtin_rindex, "c*cC*i", "Fn"
LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__annotation, "wC*.","n", ALL_MS_LANGUAGES)
LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_bittest, "UcNiC*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_bittestandcomplement, "UcNi*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_bittestandreset, "UcNi*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_bittestandset, "UcNi*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_bittest64, "UcWiC*Wi", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_bittestandcomplement64, "UcWi*Wi", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_bittestandreset64, "UcWi*Wi", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_bittestandset64, "UcWi*Wi", "n", ALL_MS_LANGUAGES)
LIBBUILTIN(_byteswap_ushort, "UsUs", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
LIBBUILTIN(_byteswap_ulong, "UNiUNi", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
LIBBUILTIN(_byteswap_uint64, "ULLiULLi", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
@@ -783,7 +791,10 @@ LANGBUILTIN(_InterlockedOr, "NiNiD*Ni"
LANGBUILTIN(_InterlockedXor8, "ccD*c", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedXor16, "ssD*s", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedXor, "NiNiD*Ni", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_interlockedbittestandset, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_interlockedbittestandreset, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_interlockedbittestandreset64, "UcWiD*Wi", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_interlockedbittestandset, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_interlockedbittestandset64, "UcWiD*Wi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__popcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__popcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=333978&r1=333977&r2=333978&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Mon Jun 4 18:33:40 2018
@@ -484,6 +484,37 @@ CodeGenFunction::emitBuiltinObjectSize(c
return Builder.CreateCall(F, {Ptr, Min, NullIsUnknown});
}
+static RValue EmitBitTestIntrinsic(CodeGenFunction &CGF, const CallExpr *E,
+ char TestAnd, char Size,
+ bool Locked = false) {
+ Value *BitBase = CGF.EmitScalarExpr(E->getArg(0));
+ Value *BitPos = CGF.EmitScalarExpr(E->getArg(1));
+
+ // Build the assembly.
+ SmallString<64> Asm;
+ raw_svector_ostream AsmOS(Asm);
+ if (Locked)
+ AsmOS << "lock ";
+ AsmOS << "bt";
+ if (TestAnd)
+ AsmOS << TestAnd;
+ AsmOS << Size << " $2, ($1)\n\tsetc ${0:b}";
+
+ // Build the constraints. FIXME: We should support immediates when possible.
+ std::string Constraints = "=r,r,r,~{cc},~{flags},~{memory},~{fpsr}";
+ llvm::IntegerType *IntType = llvm::IntegerType::get(
+ CGF.getLLVMContext(),
+ CGF.getContext().getTypeSize(E->getArg(1)->getType()));
+ llvm::Type *IntPtrType = IntType->getPointerTo();
+ llvm::FunctionType *FTy =
+ llvm::FunctionType::get(CGF.Int8Ty, {IntPtrType, IntType}, false);
+
+ llvm::InlineAsm *IA =
+ llvm::InlineAsm::get(FTy, Asm, Constraints, /*SideEffects=*/true);
+ CallSite CS = CGF.Builder.CreateCall(IA, {BitBase, BitPos});
+ return RValue::get(CS.getInstruction());
+}
+
// Many of MSVC builtins are on both x64 and ARM; to avoid repeating code, we
// handle them here.