diff options
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/llvm.zig | 15 |
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}; |
