authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-07 00:25:32-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-07 00:25:32-04:00
logd8295c188946b0f07d62420c2f08c940f70b03ac
tree96fc4b4199546dad9010ce659673e83ced997fe4
parente19f0b5d9c26f4d309df9cfc84b7e5dc04b10ed5

add @popCount intrinsic


11 files changed, 205 insertions(+), 6 deletions(-)

doc/langref.html.in+13-2
......@@ -5013,7 +5013,7 @@ comptime {
50135013 <p>
50145014 If <code>x</code> is zero, <code>@clz</code> returns <code>T.bit_count</code>.
50155015 </p>
5016
5016 {#see_also|@ctz|@popCount#}
50175017 {#header_close#}
50185018 {#header_open|@cmpxchgStrong#}
50195019 <pre><code class="zig">@cmpxchgStrong(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T</code></pre>
......@@ -5149,6 +5149,7 @@ test "main" {
51495149 <p>
51505150 If <code>x</code> is zero, <code>@ctz</code> returns <code>T.bit_count</code>.
51515151 </p>
5152 {#see_also|@clz|@popCount#}
51525153 {#header_close#}
51535154 {#header_open|@divExact#}
51545155 <pre><code class="zig">@divExact(numerator: T, denominator: T) T</code></pre>
......@@ -5631,6 +5632,16 @@ test "call foo" {
56315632 </ul>
56325633 {#see_also|Root Source File#}
56335634 {#header_close#}
5635 {#header_open|@popCount#}
5636 <pre><code class="zig">@popCount(integer: var) var</code></pre>
5637 <p>Counts the number of bits set in an integer.</p>
5638 <p>
5639 If <code>integer</code> is known at {#link|comptime#}, the return type is <code>comptime_int</code>.
5640 Otherwise, the return type is an unsigned integer with the minimum number
5641 of bits that can represent the bit count of the integer type.
5642 </p>
5643 {#see_also|@ctz|@clz#}
5644 {#header_close#}
56345645 {#header_open|@ptrCast#}
56355646 <pre><code class="zig">@ptrCast(comptime DestType: type, value: var) DestType</code></pre>
56365647 <p>
......@@ -7337,7 +7348,7 @@ hljs.registerLanguage("zig", function(t) {
73377348 a = t.IR + "\\s*\\(",
73387349 c = {
73397350 keyword: "const align var extern stdcallcc nakedcc volatile export pub noalias inline struct packed enum union break return try catch test continue unreachable comptime and or asm defer errdefer if else switch while for fn use bool f32 f64 void type noreturn error i8 u8 i16 u16 i32 u32 i64 u64 isize usize i8w u8w i16w i32w u32w i64w u64w isizew usizew c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong resume cancel await async orelse",
7340 built_in: "atomicLoad breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage divTrunc divFloor enumTagName intToPtr ptrToInt panic ptrCast intCast floatCast intToFloat floatToInt boolToInt bytesToSlice sliceToBytes errSetCast bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount memberName memberType typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchgStrong cmpxchgWeak fence divExact truncate atomicRmw sqrt field typeInfo typeName newStackCall errorToInt intToError enumToInt intToEnum",
7351 built_in: "atomicLoad breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage divTrunc divFloor enumTagName intToPtr ptrToInt panic ptrCast intCast floatCast intToFloat floatToInt boolToInt bytesToSlice sliceToBytes errSetCast bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount memberName memberType typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz popCount import cImport errorName embedFile cmpxchgStrong cmpxchgWeak fence divExact truncate atomicRmw sqrt field typeInfo typeName newStackCall errorToInt intToError enumToInt intToEnum",
73417352 literal: "true false null undefined"
73427353 },
73437354 n = [e, t.CLCM, t.CBCM, s, r];
src/all_types.hpp+12
......@@ -1352,6 +1352,7 @@ enum BuiltinFnId {
13521352 BuiltinFnIdCompileLog,
13531353 BuiltinFnIdCtz,
13541354 BuiltinFnIdClz,
1355 BuiltinFnIdPopCount,
13551356 BuiltinFnIdImport,
13561357 BuiltinFnIdCImport,
13571358 BuiltinFnIdErrName,
......@@ -1477,6 +1478,7 @@ bool type_id_eql(TypeId a, TypeId b);
14771478enum ZigLLVMFnId {
14781479 ZigLLVMFnIdCtz,
14791480 ZigLLVMFnIdClz,
1481 ZigLLVMFnIdPopCount,
14801482 ZigLLVMFnIdOverflowArithmetic,
14811483 ZigLLVMFnIdFloor,
14821484 ZigLLVMFnIdCeil,
......@@ -1499,6 +1501,9 @@ struct ZigLLVMFnKey {
14991501 struct {
15001502 uint32_t bit_count;
15011503 } clz;
1504 struct {
1505 uint32_t bit_count;
1506 } pop_count;
15021507 struct {
15031508 uint32_t bit_count;
15041509 } floating;
......@@ -2050,6 +2055,7 @@ enum IrInstructionId {
20502055 IrInstructionIdUnionTag,
20512056 IrInstructionIdClz,
20522057 IrInstructionIdCtz,
2058 IrInstructionIdPopCount,
20532059 IrInstructionIdImport,
20542060 IrInstructionIdCImport,
20552061 IrInstructionIdCInclude,
......@@ -2545,6 +2551,12 @@ struct IrInstructionClz {
25452551 IrInstruction *value;
25462552};
25472553
2554struct IrInstructionPopCount {
2555 IrInstruction base;
2556
2557 IrInstruction *value;
2558};
2559
25482560struct IrInstructionUnionTag {
25492561 IrInstruction base;
25502562
src/analyze.cpp+4
......@@ -5976,6 +5976,8 @@ uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey x) {
59765976 return (uint32_t)(x.data.ctz.bit_count) * (uint32_t)810453934;
59775977 case ZigLLVMFnIdClz:
59785978 return (uint32_t)(x.data.clz.bit_count) * (uint32_t)2428952817;
5979 case ZigLLVMFnIdPopCount:
5980 return (uint32_t)(x.data.clz.bit_count) * (uint32_t)101195049;
59795981 case ZigLLVMFnIdFloor:
59805982 return (uint32_t)(x.data.floating.bit_count) * (uint32_t)1899859168;
59815983 case ZigLLVMFnIdCeil:
......@@ -5998,6 +6000,8 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
59986000 return a.data.ctz.bit_count == b.data.ctz.bit_count;
59996001 case ZigLLVMFnIdClz:
60006002 return a.data.clz.bit_count == b.data.clz.bit_count;
6003 case ZigLLVMFnIdPopCount:
6004 return a.data.pop_count.bit_count == b.data.pop_count.bit_count;
60016005 case ZigLLVMFnIdFloor:
60026006 case ZigLLVMFnIdCeil:
60036007 case ZigLLVMFnIdSqrt:
src/bigint.cpp+31
......@@ -1593,6 +1593,37 @@ void bigint_append_buf(Buf *buf, const BigInt *op, uint64_t base) {
15931593 }
15941594}
15951595
1596size_t bigint_popcount_unsigned(const BigInt *bi) {
1597 assert(!bi->is_negative);
1598 if (bi->digit_count == 0)
1599 return 0;
1600
1601 size_t count = 0;
1602 size_t bit_count = bi->digit_count * 64;
1603 for (size_t i = 0; i < bit_count; i += 1) {
1604 if (bit_at_index(bi, i))
1605 count += 1;
1606 }
1607 return count;
1608}
1609
1610size_t bigint_popcount_signed(const BigInt *bi, size_t bit_count) {
1611 if (bit_count == 0)
1612 return 0;
1613 if (bi->digit_count == 0)
1614 return 0;
1615
1616 BigInt twos_comp = {0};
1617 to_twos_complement(&twos_comp, bi, bit_count);
1618
1619 size_t count = 0;
1620 for (size_t i = 0; i < bit_count; i += 1) {
1621 if (bit_at_index(&twos_comp, i))
1622 count += 1;
1623 }
1624 return count;
1625}
1626
15961627size_t bigint_ctz(const BigInt *bi, size_t bit_count) {
15971628 if (bit_count == 0)
15981629 return 0;
src/bigint.hpp+2
......@@ -81,6 +81,8 @@ void bigint_append_buf(Buf *buf, const BigInt *op, uint64_t base);
8181
8282size_t bigint_ctz(const BigInt *bi, size_t bit_count);
8383size_t bigint_clz(const BigInt *bi, size_t bit_count);
84size_t bigint_popcount_signed(const BigInt *bi, size_t bit_count);
85size_t bigint_popcount_unsigned(const BigInt *bi);
8486
8587size_t bigint_bits_needed(const BigInt *op);
8688
src/codegen.cpp+20-1
......@@ -3426,14 +3426,22 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable,
34263426static LLVMValueRef get_int_builtin_fn(CodeGen *g, TypeTableEntry *int_type, BuiltinFnId fn_id) {
34273427 ZigLLVMFnKey key = {};
34283428 const char *fn_name;
3429 uint32_t n_args;
34293430 if (fn_id == BuiltinFnIdCtz) {
34303431 fn_name = "cttz";
3432 n_args = 2;
34313433 key.id = ZigLLVMFnIdCtz;
34323434 key.data.ctz.bit_count = (uint32_t)int_type->data.integral.bit_count;
34333435 } else if (fn_id == BuiltinFnIdClz) {
34343436 fn_name = "ctlz";
3437 n_args = 2;
34353438 key.id = ZigLLVMFnIdClz;
34363439 key.data.clz.bit_count = (uint32_t)int_type->data.integral.bit_count;
3440 } else if (fn_id == BuiltinFnIdPopCount) {
3441 fn_name = "ctpop";
3442 n_args = 1;
3443 key.id = ZigLLVMFnIdPopCount;
3444 key.data.pop_count.bit_count = (uint32_t)int_type->data.integral.bit_count;
34373445 } else {
34383446 zig_unreachable();
34393447 }
......@@ -3448,7 +3456,7 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, TypeTableEntry *int_type, Bui
34483456 int_type->type_ref,
34493457 LLVMInt1Type(),
34503458 };
3451 LLVMTypeRef fn_type = LLVMFunctionType(int_type->type_ref, param_types, 2, false);
3459 LLVMTypeRef fn_type = LLVMFunctionType(int_type->type_ref, param_types, n_args, false);
34523460 LLVMValueRef fn_val = LLVMAddFunction(g->module, llvm_name, fn_type);
34533461 assert(LLVMGetIntrinsicID(fn_val));
34543462
......@@ -3481,6 +3489,14 @@ static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstru
34813489 return gen_widen_or_shorten(g, false, int_type, instruction->base.value.type, wrong_size_int);
34823490}
34833491
3492static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutable *executable, IrInstructionPopCount *instruction) {
3493 TypeTableEntry *int_type = instruction->value->value.type;
3494 LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount);
3495 LLVMValueRef operand = ir_llvm_value(g, instruction->value);
3496 LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, &operand, 1, "");
3497 return gen_widen_or_shorten(g, false, int_type, instruction->base.value.type, wrong_size_int);
3498}
3499
34843500static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutable *executable, IrInstructionSwitchBr *instruction) {
34853501 LLVMValueRef target_value = ir_llvm_value(g, instruction->target_value);
34863502 LLVMBasicBlockRef else_block = instruction->else_block->llvm_block;
......@@ -4831,6 +4847,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
48314847 return ir_render_clz(g, executable, (IrInstructionClz *)instruction);
48324848 case IrInstructionIdCtz:
48334849 return ir_render_ctz(g, executable, (IrInstructionCtz *)instruction);
4850 case IrInstructionIdPopCount:
4851 return ir_render_pop_count(g, executable, (IrInstructionPopCount *)instruction);
48344852 case IrInstructionIdSwitchBr:
48354853 return ir_render_switch_br(g, executable, (IrInstructionSwitchBr *)instruction);
48364854 case IrInstructionIdPhi:
......@@ -6342,6 +6360,7 @@ static void define_builtin_fns(CodeGen *g) {
63426360 create_builtin_fn(g, BuiltinFnIdCUndef, "cUndef", 1);
63436361 create_builtin_fn(g, BuiltinFnIdCtz, "ctz", 1);
63446362 create_builtin_fn(g, BuiltinFnIdClz, "clz", 1);
6363 create_builtin_fn(g, BuiltinFnIdPopCount, "popCount", 1);
63456364 create_builtin_fn(g, BuiltinFnIdImport, "import", 1);
63466365 create_builtin_fn(g, BuiltinFnIdCImport, "cImport", 1);
63476366 create_builtin_fn(g, BuiltinFnIdErrName, "errorName", 1);
src/ir.cpp+68
......@@ -427,6 +427,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCtz *) {
427427 return IrInstructionIdCtz;
428428}
429429
430static constexpr IrInstructionId ir_instruction_id(IrInstructionPopCount *) {
431 return IrInstructionIdPopCount;
432}
433
430434static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionTag *) {
431435 return IrInstructionIdUnionTag;
432436}
......@@ -1725,6 +1729,15 @@ static IrInstruction *ir_build_ctz_from(IrBuilder *irb, IrInstruction *old_instr
17251729 return new_instruction;
17261730}
17271731
1732static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
1733 IrInstructionPopCount *instruction = ir_build_instruction<IrInstructionPopCount>(irb, scope, source_node);
1734 instruction->value = value;
1735
1736 ir_ref_instruction(value, irb->current_basic_block);
1737
1738 return &instruction->base;
1739}
1740
17281741static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target_value,
17291742 IrBasicBlock *else_block, size_t case_count, IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime,
17301743 IrInstruction *switch_prongs_void)
......@@ -3841,6 +3854,16 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
38413854 IrInstruction *ctz = ir_build_ctz(irb, scope, node, arg0_value);
38423855 return ir_lval_wrap(irb, scope, ctz, lval);
38433856 }
3857 case BuiltinFnIdPopCount:
3858 {
3859 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
3860 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
3861 if (arg0_value == irb->codegen->invalid_instruction)
3862 return arg0_value;
3863
3864 IrInstruction *instr = ir_build_pop_count(irb, scope, node, arg0_value);
3865 return ir_lval_wrap(irb, scope, instr, lval);
3866 }
38443867 case BuiltinFnIdClz:
38453868 {
38463869 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -15275,6 +15298,48 @@ static TypeTableEntry *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionC
1527515298 }
1527615299}
1527715300
15301static TypeTableEntry *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstructionPopCount *instruction) {
15302 IrInstruction *value = instruction->value->other;
15303 if (type_is_invalid(value->value.type))
15304 return ira->codegen->builtin_types.entry_invalid;
15305
15306 if (value->value.type->id != TypeTableEntryIdInt && value->value.type->id != TypeTableEntryIdComptimeInt) {
15307 ir_add_error(ira, value,
15308 buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name)));
15309 return ira->codegen->builtin_types.entry_invalid;
15310 }
15311
15312 if (instr_is_comptime(value)) {
15313 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
15314 if (!val)
15315 return ira->codegen->builtin_types.entry_invalid;
15316 if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) {
15317 size_t result = bigint_popcount_unsigned(&val->data.x_bigint);
15318 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
15319 bigint_init_unsigned(&out_val->data.x_bigint, result);
15320 return ira->codegen->builtin_types.entry_num_lit_int;
15321 }
15322 if (value->value.type->id == TypeTableEntryIdComptimeInt) {
15323 Buf *val_buf = buf_alloc();
15324 bigint_append_buf(val_buf, &val->data.x_bigint, 10);
15325 ir_add_error(ira, &instruction->base,
15326 buf_sprintf("@popCount on negative %s value %s",
15327 buf_ptr(&value->value.type->name), buf_ptr(val_buf)));
15328 return ira->codegen->builtin_types.entry_invalid;
15329 }
15330 size_t result = bigint_popcount_signed(&val->data.x_bigint, value->value.type->data.integral.bit_count);
15331 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
15332 bigint_init_unsigned(&out_val->data.x_bigint, result);
15333 return ira->codegen->builtin_types.entry_num_lit_int;
15334 }
15335
15336 IrInstruction *result = ir_build_pop_count(&ira->new_irb, instruction->base.scope,
15337 instruction->base.source_node, value);
15338 result->value.type = get_smallest_unsigned_int_type(ira->codegen, value->value.type->data.integral.bit_count);
15339 ir_link_new_instruction(result, &instruction->base);
15340 return result->value.type;
15341}
15342
1527815343static IrInstruction *ir_analyze_union_tag(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value) {
1527915344 if (type_is_invalid(value->value.type))
1528015345 return ira->codegen->invalid_instruction;
......@@ -20534,6 +20599,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
2053420599 return ir_analyze_instruction_clz(ira, (IrInstructionClz *)instruction);
2053520600 case IrInstructionIdCtz:
2053620601 return ir_analyze_instruction_ctz(ira, (IrInstructionCtz *)instruction);
20602 case IrInstructionIdPopCount:
20603 return ir_analyze_instruction_pop_count(ira, (IrInstructionPopCount *)instruction);
2053720604 case IrInstructionIdSwitchBr:
2053820605 return ir_analyze_instruction_switch_br(ira, (IrInstructionSwitchBr *)instruction);
2053920606 case IrInstructionIdSwitchTarget:
......@@ -20892,6 +20959,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2089220959 case IrInstructionIdUnwrapOptional:
2089320960 case IrInstructionIdClz:
2089420961 case IrInstructionIdCtz:
20962 case IrInstructionIdPopCount:
2089520963 case IrInstructionIdSwitchVar:
2089620964 case IrInstructionIdSwitchTarget:
2089720965 case IrInstructionIdUnionTag:
src/ir_print.cpp+9
......@@ -501,6 +501,12 @@ static void ir_print_ctz(IrPrint *irp, IrInstructionCtz *instruction) {
501501 fprintf(irp->f, ")");
502502}
503503
504static void ir_print_pop_count(IrPrint *irp, IrInstructionPopCount *instruction) {
505 fprintf(irp->f, "@popCount(");
506 ir_print_other_instruction(irp, instruction->value);
507 fprintf(irp->f, ")");
508}
509
504510static void ir_print_switch_br(IrPrint *irp, IrInstructionSwitchBr *instruction) {
505511 fprintf(irp->f, "switch (");
506512 ir_print_other_instruction(irp, instruction->target_value);
......@@ -1425,6 +1431,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
14251431 case IrInstructionIdCtz:
14261432 ir_print_ctz(irp, (IrInstructionCtz *)instruction);
14271433 break;
1434 case IrInstructionIdPopCount:
1435 ir_print_pop_count(irp, (IrInstructionPopCount *)instruction);
1436 break;
14281437 case IrInstructionIdClz:
14291438 ir_print_clz(irp, (IrInstructionClz *)instruction);
14301439 break;
test/behavior.zig+4-3
......@@ -8,17 +8,17 @@ comptime {
88 _ = @import("cases/atomics.zig");
99 _ = @import("cases/bitcast.zig");
1010 _ = @import("cases/bool.zig");
11 _ = @import("cases/bugs/1111.zig");
1112 _ = @import("cases/bugs/394.zig");
1213 _ = @import("cases/bugs/655.zig");
1314 _ = @import("cases/bugs/656.zig");
1415 _ = @import("cases/bugs/828.zig");
1516 _ = @import("cases/bugs/920.zig");
16 _ = @import("cases/bugs/1111.zig");
1717 _ = @import("cases/byval_arg_var.zig");
1818 _ = @import("cases/cast.zig");
1919 _ = @import("cases/const_slice_child.zig");
20 _ = @import("cases/coroutines.zig");
2120 _ = @import("cases/coroutine_await_struct.zig");
21 _ = @import("cases/coroutines.zig");
2222 _ = @import("cases/defer.zig");
2323 _ = @import("cases/enum.zig");
2424 _ = @import("cases/enum_with_members.zig");
......@@ -36,11 +36,12 @@ comptime {
3636 _ = @import("cases/math.zig");
3737 _ = @import("cases/merge_error_sets.zig");
3838 _ = @import("cases/misc.zig");
39 _ = @import("cases/optional.zig");
4039 _ = @import("cases/namespace_depends_on_compile_var/index.zig");
4140 _ = @import("cases/new_stack_call.zig");
4241 _ = @import("cases/null.zig");
42 _ = @import("cases/optional.zig");
4343 _ = @import("cases/pointers.zig");
44 _ = @import("cases/popcount.zig");
4445 _ = @import("cases/pub_enum/index.zig");
4546 _ = @import("cases/ref_var_in_if_after_if_2nd_switch_prong.zig");
4647 _ = @import("cases/reflection.zig");
test/cases/popcount.zig created+24
......@@ -0,0 +1,24 @@
1const assert = @import("std").debug.assert;
2
3test "@popCount" {
4 comptime testPopCount();
5 testPopCount();
6}
7
8fn testPopCount() void {
9 {
10 var x: u32 = 0xaa;
11 assert(@popCount(x) == 4);
12 }
13 {
14 var x: u32 = 0xaaaaaaaa;
15 assert(@popCount(x) == 16);
16 }
17 {
18 var x: i16 = -1;
19 assert(@popCount(x) == 16);
20 }
21 comptime {
22 assert(@popCount(0b11111111000110001100010000100001000011000011100101010001) == 24);
23 }
24}
test/compile_errors.zig+18
......@@ -1,6 +1,24 @@
11const tests = @import("tests.zig");
22
33pub fn addCases(cases: *tests.CompileErrorContext) void {
4 cases.add(
5 "@popCount - non-integer",
6 \\export fn entry(x: f32) u32 {
7 \\ return @popCount(x);
8 \\}
9 ,
10 ".tmp_source.zig:2:22: error: expected integer type, found 'f32'",
11 );
12
13 cases.add(
14 "@popCount - negative comptime_int",
15 \\comptime {
16 \\ _ = @popCount(-1);
17 \\}
18 ,
19 ".tmp_source.zig:2:9: error: @popCount on negative comptime_int value -1",
20 );
21
422 cases.addCase(x: {
523 const tc = cases.create(
624 "wrong same named struct",