aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-02-12 20:44:30 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-02-12 20:44:30 -0700
commita005ac9d3c884c6254074ec150fe536881fe31b5 (patch)
tree6c7d2016362d441ad77d77abbf76f5116b329c73 /src/codegen
parent16ec848d2ab5702ad3794d30ed5d776b5abb60ce (diff)
downloadzig-a005ac9d3c884c6254074ec150fe536881fe31b5.tar.gz
zig-a005ac9d3c884c6254074ec150fe536881fe31b5.zip
stage2: implement `@popCount` for SIMD vectors
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/llvm.zig15
1 files changed, 10 insertions, 5 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 3b9bac09ec..493b895d5d 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -2205,7 +2205,7 @@ pub const FuncGen = struct {
.get_union_tag => try self.airGetUnionTag(inst),
.clz => try self.airClzCtz(inst, "ctlz"),
.ctz => try self.airClzCtz(inst, "cttz"),
- .popcount => try self.airPopCount(inst, "ctpop"),
+ .popcount => try self.airPopCount(inst),
.tag_name => try self.airTagName(inst),
.error_name => try self.airErrorName(inst),
.splat => try self.airSplat(inst),
@@ -4364,7 +4364,7 @@ pub const FuncGen = struct {
}
}
- fn airPopCount(self: *FuncGen, inst: Air.Inst.Index, prefix: [*:0]const u8) !?*const llvm.Value {
+ fn airPopCount(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
@@ -4372,11 +4372,16 @@ pub const FuncGen = struct {
const operand = try self.resolveInst(ty_op.operand);
const target = self.dg.module.getTarget();
const bits = operand_ty.intInfo(target).bits;
+ const vec_len: ?u32 = switch (operand_ty.zigTypeTag()) {
+ .Vector => operand_ty.vectorLen(),
+ else => null,
+ };
var fn_name_buf: [100]u8 = undefined;
- const llvm_fn_name = std.fmt.bufPrintZ(&fn_name_buf, "llvm.{s}.i{d}", .{
- prefix, bits,
- }) catch unreachable;
+ const llvm_fn_name = if (vec_len) |len|
+ std.fmt.bufPrintZ(&fn_name_buf, "llvm.ctpop.v{d}i{d}", .{ len, bits }) catch unreachable
+ else
+ std.fmt.bufPrintZ(&fn_name_buf, "llvm.ctpop.i{d}", .{bits}) catch unreachable;
const fn_val = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
const operand_llvm_ty = try self.dg.llvmType(operand_ty);
const param_types = [_]*const llvm.Type{operand_llvm_ty};