bridge: support more bit manipulation intrinsics
Add support of clz, popcount, and bswap16 intrinsics. They are
used for the math/bits package.
Change-Id: Iae9fab672ae9e3b618eb9b6ab7d18967bf52acfe
Reviewed-on: https://go-review.googlesource.com/c/gollvm/+/183246
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/bridge/go-llvm-builtins.cpp b/bridge/go-llvm-builtins.cpp
index 3563941..10befb0 100644
--- a/bridge/go-llvm-builtins.cpp
+++ b/bridge/go-llvm-builtins.cpp
@@ -102,6 +102,7 @@
void BuiltinTable::defineIntrinsicBuiltins() {
Btype *boolType = tman_->boolType();
Btype *ptrType = tman_->pointerType(boolType);
+ Btype *uint16Type = tman_->integerType(true, 16);
Btype *uint32Type = tman_->integerType(true, 32);
Btype *int32Type = tman_->integerType(false, 32);
unsigned bitsInPtr = tman_->datalayout()->getPointerSizeInBits();
@@ -157,6 +158,31 @@
defineIntrinsicBuiltin("__builtin_ctzll", "ctzll", llvm::Intrinsic::cttz,
uint64Type, nullptr);
+ // go runtime refers to this intrinsic as "clz", however the LLVM
+ // equivalent is named "ctlz".
+ defineIntrinsicBuiltin("__builtin_clz", "clz", llvm::Intrinsic::ctlz,
+ uint32Type, nullptr);
+
+ // go runtime refers to this intrinsic as "clzll", however the LLVM
+ // equivalent is named "ctlz".
+ defineIntrinsicBuiltin("__builtin_clzll", "clzll", llvm::Intrinsic::ctlz,
+ uint64Type, nullptr);
+
+ // go runtime refers to this intrinsic as "popcount", however the LLVM
+ // equivalent is named "ctpop".
+ defineIntrinsicBuiltin("__builtin_popcount", "popcount", llvm::Intrinsic::ctpop,
+ uint32Type, nullptr);
+
+ // go runtime refers to this intrinsic as "popcountll", however the LLVM
+ // equivalent is named "ctpop".
+ defineIntrinsicBuiltin("__builtin_popcountll", "popcountll", llvm::Intrinsic::ctpop,
+ uint64Type, nullptr);
+
+ // go runtime refers to this intrinsic as "bswap16", however the LLVM
+ // equivalent is named just "bswap"
+ defineIntrinsicBuiltin("__builtin_bswap16", "bswap16", llvm::Intrinsic::bswap,
+ uint16Type, nullptr);
+
// go runtime refers to this intrinsic as "bswap32", however the LLVM
// equivalent is named just "bswap"
defineIntrinsicBuiltin("__builtin_bswap32", "bswap32", llvm::Intrinsic::bswap,
diff --git a/bridge/go-llvm-materialize.cpp b/bridge/go-llvm-materialize.cpp
index 9d47274..beaba5a 100644
--- a/bridge/go-llvm-materialize.cpp
+++ b/bridge/go-llvm-materialize.cpp
@@ -1390,7 +1390,8 @@
if (llvm::isa<llvm::Function>(fnval)) {
llvm::Function *fcn = llvm::cast<llvm::Function>(fnval);
switch (fcn->getIntrinsicID()) {
- case llvm::Intrinsic::cttz: {
+ case llvm::Intrinsic::cttz:
+ case llvm::Intrinsic::ctlz: {
// @llvm.cttz.i32 (i32 <src>, i1 <is_zero_undef>)
// Add the <is_zero_undef> arg.
// GCC's __builtin_ctz results undefined for 0 input.