@@ -476,6 +476,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatToInt *) {
476476 return IrInstructionIdFloatToInt;
477477}
478478
479+ static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolToInt *) {
480+ return IrInstructionIdBoolToInt;
481+ }
482+
479483static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) {
480484 return IrInstructionIdIntType;
481485}
@@ -1959,6 +1963,15 @@ static IrInstruction *ir_build_float_to_int(IrBuilder *irb, Scope *scope, AstNod
19591963 return &instruction->base;
19601964}
19611965
1966+ static IrInstruction *ir_build_bool_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) {
1967+ IrInstructionBoolToInt *instruction = ir_build_instruction<IrInstructionBoolToInt>(irb, scope, source_node);
1968+ instruction->target = target;
1969+
1970+ ir_ref_instruction(target, irb->current_basic_block);
1971+
1972+ return &instruction->base;
1973+ }
1974+
19621975static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_signed, IrInstruction *bit_count) {
19631976 IrInstructionIntType *instruction = ir_build_instruction<IrInstructionIntType>(irb, scope, source_node);
19641977 instruction->is_signed = is_signed;
@@ -4071,6 +4084,16 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40714084 IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value);
40724085 return ir_lval_wrap(irb, scope, result, lval);
40734086 }
4087+ case BuiltinFnIdBoolToInt:
4088+ {
4089+ AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4090+ IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4091+ if (arg0_value == irb->codegen->invalid_instruction)
4092+ return arg0_value;
4093+
4094+ IrInstruction *result = ir_build_bool_to_int(irb, scope, node, arg0_value);
4095+ return ir_lval_wrap(irb, scope, result, lval);
4096+ }
40744097 case BuiltinFnIdIntType:
40754098 {
40764099 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
@@ -10055,13 +10078,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1005510078 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
1005610079 }
1005710080
10058- // explicit cast from bool to int
10059- if (wanted_type->id == TypeTableEntryIdInt &&
10060- actual_type->id == TypeTableEntryIdBool)
10061- {
10062- return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpBoolToInt, false);
10063- }
10064-
1006510081 // explicit widening conversion
1006610082 if (wanted_type->id == TypeTableEntryIdInt &&
1006710083 actual_type->id == TypeTableEntryIdInt &&
@@ -17605,6 +17621,33 @@ static TypeTableEntry *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrIns
1760517621 return dest_type;
1760617622}
1760717623
17624+ static TypeTableEntry *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstructionBoolToInt *instruction) {
17625+ IrInstruction *target = instruction->target->other;
17626+ if (type_is_invalid(target->value.type))
17627+ return ira->codegen->builtin_types.entry_invalid;
17628+
17629+ if (target->value.type->id != TypeTableEntryIdBool) {
17630+ ir_add_error(ira, instruction->target, buf_sprintf("expected bool, found '%s'",
17631+ buf_ptr(&target->value.type->name)));
17632+ return ira->codegen->builtin_types.entry_invalid;
17633+ }
17634+
17635+ if (instr_is_comptime(target)) {
17636+ bool is_true;
17637+ if (!ir_resolve_bool(ira, target, &is_true))
17638+ return ira->codegen->builtin_types.entry_invalid;
17639+
17640+ ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
17641+ bigint_init_unsigned(&out_val->data.x_bigint, is_true ? 1 : 0);
17642+ return ira->codegen->builtin_types.entry_num_lit_int;
17643+ }
17644+
17645+ TypeTableEntry *u1_type = get_int_type(ira->codegen, false, 1);
17646+ IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt, false);
17647+ ir_link_new_instruction(result, &instruction->base);
17648+ return u1_type;
17649+ }
17650+
1760817651static TypeTableEntry *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) {
1760917652 IrInstruction *is_signed_value = instruction->is_signed->other;
1761017653 bool is_signed;
@@ -20143,6 +20186,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
2014320186 return ir_analyze_instruction_int_to_float(ira, (IrInstructionIntToFloat *)instruction);
2014420187 case IrInstructionIdFloatToInt:
2014520188 return ir_analyze_instruction_float_to_int(ira, (IrInstructionFloatToInt *)instruction);
20189+ case IrInstructionIdBoolToInt:
20190+ return ir_analyze_instruction_bool_to_int(ira, (IrInstructionBoolToInt *)instruction);
2014620191 case IrInstructionIdIntType:
2014720192 return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction);
2014820193 case IrInstructionIdBoolNot:
@@ -20490,6 +20535,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2049020535 case IrInstructionIdFloatCast:
2049120536 case IrInstructionIdIntToFloat:
2049220537 case IrInstructionIdFloatToInt:
20538+ case IrInstructionIdBoolToInt:
2049320539 return false;
2049420540
2049520541 case IrInstructionIdAsm:
0 commit comments