| ... | ... | @@ -10773,10 +10773,15 @@ static TypeTableEntry *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp |
| 10773 | 10773 | if (casted_op2 == ira->codegen->invalid_instruction) |
| 10774 | 10774 | return ira->codegen->builtin_types.entry_invalid; |
| 10775 | 10775 | |
| 10776 | | ConstExprValue *op1_val = &casted_op1->value; |
| 10777 | | ConstExprValue *op2_val = &casted_op2->value; |
| 10778 | | if (op1_val->special != ConstValSpecialRuntime && op2_val->special != ConstValSpecialRuntime) { |
| 10776 | if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { |
| 10779 | 10777 | ConstExprValue *out_val = ir_build_const_from(ira, &bin_op_instruction->base); |
| 10778 | ConstExprValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); |
| 10779 | if (op1_val == nullptr) |
| 10780 | return ira->codegen->builtin_types.entry_invalid; |
| 10781 | |
| 10782 | ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); |
| 10783 | if (op2_val == nullptr) |
| 10784 | return ira->codegen->builtin_types.entry_invalid; |
| 10780 | 10785 | |
| 10781 | 10786 | assert(casted_op1->value.type->id == TypeTableEntryIdBool); |
| 10782 | 10787 | assert(casted_op2->value.type->id == TypeTableEntryIdBool); |
| ... | ... | @@ -10926,9 +10931,14 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp |
| 10926 | 10931 | } |
| 10927 | 10932 | } |
| 10928 | 10933 | |
| 10929 | | ConstExprValue *op1_val = &op1->value; |
| 10930 | | ConstExprValue *op2_val = &op2->value; |
| 10931 | | if (value_is_comptime(op1_val) && value_is_comptime(op2_val)) { |
| 10934 | if (instr_is_comptime(op1) && instr_is_comptime(op2)) { |
| 10935 | ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); |
| 10936 | if (op1_val == nullptr) |
| 10937 | return ira->codegen->builtin_types.entry_invalid; |
| 10938 | ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); |
| 10939 | if (op2_val == nullptr) |
| 10940 | return ira->codegen->builtin_types.entry_invalid; |
| 10941 | |
| 10932 | 10942 | bool answer; |
| 10933 | 10943 | bool are_equal = op1_val->data.x_err_set->value == op2_val->data.x_err_set->value; |
| 10934 | 10944 | if (op_id == IrBinOpCmpEq) { |
| ... | ... | @@ -11017,10 +11027,15 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp |
| 11017 | 11027 | if (casted_op2 == ira->codegen->invalid_instruction) |
| 11018 | 11028 | return ira->codegen->builtin_types.entry_invalid; |
| 11019 | 11029 | |
| 11020 | | ConstExprValue *op1_val = &casted_op1->value; |
| 11021 | | ConstExprValue *op2_val = &casted_op2->value; |
| 11022 | 11030 | bool one_possible_value = !type_requires_comptime(resolved_type) && !type_has_bits(resolved_type); |
| 11023 | | if (one_possible_value || (value_is_comptime(op1_val) && value_is_comptime(op2_val))) { |
| 11031 | if (one_possible_value || (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2))) { |
| 11032 | ConstExprValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); |
| 11033 | if (op1_val == nullptr) |
| 11034 | return ira->codegen->builtin_types.entry_invalid; |
| 11035 | ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); |
| 11036 | if (op2_val == nullptr) |
| 11037 | return ira->codegen->builtin_types.entry_invalid; |
| 11038 | |
| 11024 | 11039 | bool answer; |
| 11025 | 11040 | if (resolved_type->id == TypeTableEntryIdComptimeFloat || resolved_type->id == TypeTableEntryIdFloat) { |
| 11026 | 11041 | Cmp cmp_result = float_cmp(op1_val, op2_val); |
| ... | ... | @@ -11048,11 +11063,17 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp |
| 11048 | 11063 | if (resolved_type->id == TypeTableEntryIdInt && !resolved_type->data.integral.is_signed) { |
| 11049 | 11064 | ConstExprValue *known_left_val; |
| 11050 | 11065 | IrBinOp flipped_op_id; |
| 11051 | | if (value_is_comptime(op1_val)) { |
| 11052 | | known_left_val = op1_val; |
| 11066 | if (instr_is_comptime(casted_op1)) { |
| 11067 | known_left_val = ir_resolve_const(ira, casted_op1, UndefBad); |
| 11068 | if (known_left_val == nullptr) |
| 11069 | return ira->codegen->builtin_types.entry_invalid; |
| 11070 | |
| 11053 | 11071 | flipped_op_id = op_id; |
| 11054 | | } else if (value_is_comptime(op2_val)) { |
| 11055 | | known_left_val = op2_val; |
| 11072 | } else if (instr_is_comptime(casted_op2)) { |
| 11073 | known_left_val = ir_resolve_const(ira, casted_op2, UndefBad); |
| 11074 | if (known_left_val == nullptr) |
| 11075 | return ira->codegen->builtin_types.entry_invalid; |
| 11076 | |
| 11056 | 11077 | if (op_id == IrBinOpCmpLessThan) { |
| 11057 | 11078 | flipped_op_id = IrBinOpCmpGreaterThan; |
| 11058 | 11079 | } else if (op_id == IrBinOpCmpGreaterThan) { |
| ... | ... | @@ -11304,8 +11325,14 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp * |
| 11304 | 11325 | } |
| 11305 | 11326 | |
| 11306 | 11327 | if (instr_is_comptime(op1) && instr_is_comptime(casted_op2)) { |
| 11307 | | ConstExprValue *op1_val = &op1->value; |
| 11308 | | ConstExprValue *op2_val = &casted_op2->value; |
| 11328 | ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); |
| 11329 | if (op1_val == nullptr) |
| 11330 | return ira->codegen->builtin_types.entry_invalid; |
| 11331 | |
| 11332 | ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); |
| 11333 | if (op2_val == nullptr) |
| 11334 | return ira->codegen->builtin_types.entry_invalid; |
| 11335 | |
| 11309 | 11336 | IrInstruction *result_instruction = ir_get_const(ira, &bin_op_instruction->base); |
| 11310 | 11337 | ir_link_new_instruction(result_instruction, &bin_op_instruction->base); |
| 11311 | 11338 | ConstExprValue *out_val = &result_instruction->value; |
| ... | ... | @@ -11384,7 +11411,15 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 11384 | 11411 | if (is_signed_div) { |
| 11385 | 11412 | bool ok = false; |
| 11386 | 11413 | if (instr_is_comptime(op1) && instr_is_comptime(op2)) { |
| 11387 | | if (bigint_cmp_zero(&op2->value.data.x_bigint) == CmpEQ) { |
| 11414 | ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); |
| 11415 | if (op1_val == nullptr) |
| 11416 | return ira->codegen->builtin_types.entry_invalid; |
| 11417 | |
| 11418 | ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); |
| 11419 | if (op2_val == nullptr) |
| 11420 | return ira->codegen->builtin_types.entry_invalid; |
| 11421 | |
| 11422 | if (bigint_cmp_zero(&op2_val->data.x_bigint) == CmpEQ) { |
| 11388 | 11423 | // the division by zero error will be caught later, but we don't have a |
| 11389 | 11424 | // division function ambiguity problem. |
| 11390 | 11425 | op_id = IrBinOpDivTrunc; |
| ... | ... | @@ -11392,8 +11427,8 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 11392 | 11427 | } else { |
| 11393 | 11428 | BigInt trunc_result; |
| 11394 | 11429 | BigInt floor_result; |
| 11395 | | bigint_div_trunc(&trunc_result, &op1->value.data.x_bigint, &op2->value.data.x_bigint); |
| 11396 | | bigint_div_floor(&floor_result, &op1->value.data.x_bigint, &op2->value.data.x_bigint); |
| 11430 | bigint_div_trunc(&trunc_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); |
| 11431 | bigint_div_floor(&floor_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); |
| 11397 | 11432 | if (bigint_cmp(&trunc_result, &floor_result) == CmpEQ) { |
| 11398 | 11433 | ok = true; |
| 11399 | 11434 | op_id = IrBinOpDivTrunc; |
| ... | ... | @@ -11414,7 +11449,15 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 11414 | 11449 | if (is_signed_div && (is_int || is_float)) { |
| 11415 | 11450 | bool ok = false; |
| 11416 | 11451 | if (instr_is_comptime(op1) && instr_is_comptime(op2)) { |
| 11452 | ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); |
| 11453 | if (op1_val == nullptr) |
| 11454 | return ira->codegen->builtin_types.entry_invalid; |
| 11455 | |
| 11417 | 11456 | if (is_int) { |
| 11457 | ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); |
| 11458 | if (op2_val == nullptr) |
| 11459 | return ira->codegen->builtin_types.entry_invalid; |
| 11460 | |
| 11418 | 11461 | if (bigint_cmp_zero(&op2->value.data.x_bigint) == CmpEQ) { |
| 11419 | 11462 | // the division by zero error will be caught later, but we don't |
| 11420 | 11463 | // have a remainder function ambiguity problem |
| ... | ... | @@ -11422,14 +11465,19 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 11422 | 11465 | } else { |
| 11423 | 11466 | BigInt rem_result; |
| 11424 | 11467 | BigInt mod_result; |
| 11425 | | bigint_rem(&rem_result, &op1->value.data.x_bigint, &op2->value.data.x_bigint); |
| 11426 | | bigint_mod(&mod_result, &op1->value.data.x_bigint, &op2->value.data.x_bigint); |
| 11468 | bigint_rem(&rem_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); |
| 11469 | bigint_mod(&mod_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); |
| 11427 | 11470 | ok = bigint_cmp(&rem_result, &mod_result) == CmpEQ; |
| 11428 | 11471 | } |
| 11429 | 11472 | } else { |
| 11430 | 11473 | IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); |
| 11431 | 11474 | if (casted_op2 == ira->codegen->invalid_instruction) |
| 11432 | 11475 | return ira->codegen->builtin_types.entry_invalid; |
| 11476 | |
| 11477 | ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); |
| 11478 | if (op2_val == nullptr) |
| 11479 | return ira->codegen->builtin_types.entry_invalid; |
| 11480 | |
| 11433 | 11481 | if (float_cmp_zero(&casted_op2->value) == CmpEQ) { |
| 11434 | 11482 | // the division by zero error will be caught later, but we don't |
| 11435 | 11483 | // have a remainder function ambiguity problem |
| ... | ... | @@ -11437,8 +11485,8 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 11437 | 11485 | } else { |
| 11438 | 11486 | ConstExprValue rem_result; |
| 11439 | 11487 | ConstExprValue mod_result; |
| 11440 | | float_rem(&rem_result, &op1->value, &casted_op2->value); |
| 11441 | | float_mod(&mod_result, &op1->value, &casted_op2->value); |
| 11488 | float_rem(&rem_result, op1_val, op2_val); |
| 11489 | float_mod(&mod_result, op1_val, op2_val); |
| 11442 | 11490 | ok = float_cmp(&rem_result, &mod_result) == CmpEQ; |
| 11443 | 11491 | } |
| 11444 | 11492 | } |
| ... | ... | @@ -11496,8 +11544,13 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 11496 | 11544 | return ira->codegen->builtin_types.entry_invalid; |
| 11497 | 11545 | |
| 11498 | 11546 | if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { |
| 11499 | | ConstExprValue *op1_val = &casted_op1->value; |
| 11500 | | ConstExprValue *op2_val = &casted_op2->value; |
| 11547 | ConstExprValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); |
| 11548 | if (op1_val == nullptr) |
| 11549 | return ira->codegen->builtin_types.entry_invalid; |
| 11550 | ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); |
| 11551 | if (op2_val == nullptr) |
| 11552 | return ira->codegen->builtin_types.entry_invalid; |
| 11553 | |
| 11501 | 11554 | IrInstruction *result_instruction = ir_get_const(ira, &bin_op_instruction->base); |
| 11502 | 11555 | ir_link_new_instruction(result_instruction, &bin_op_instruction->base); |
| 11503 | 11556 | ConstExprValue *out_val = &result_instruction->value; |
| ... | ... | @@ -11672,9 +11725,16 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * |
| 11672 | 11725 | out_val->data.x_ptr.data.base_array.array_val = out_array_val; |
| 11673 | 11726 | out_val->data.x_ptr.data.base_array.elem_index = 0; |
| 11674 | 11727 | } |
| 11675 | | out_array_val->data.x_array.s_none.elements = create_const_vals(new_len); |
| 11676 | 11728 | |
| 11729 | if (op1_array_val->data.x_array.special == ConstArraySpecialUndef && |
| 11730 | op2_array_val->data.x_array.special == ConstArraySpecialUndef) { |
| 11731 | out_array_val->data.x_array.special = ConstArraySpecialUndef; |
| 11732 | return result_type; |
| 11733 | } |
| 11734 | |
| 11735 | out_array_val->data.x_array.s_none.elements = create_const_vals(new_len); |
| 11677 | 11736 | expand_undef_array(ira->codegen, op1_array_val); |
| 11737 | expand_undef_array(ira->codegen, op2_array_val); |
| 11678 | 11738 | |
| 11679 | 11739 | size_t next_index = 0; |
| 11680 | 11740 | for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { |
| ... | ... | @@ -11726,10 +11786,14 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp |
| 11726 | 11786 | } |
| 11727 | 11787 | |
| 11728 | 11788 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 11789 | if (array_val->data.x_array.special == ConstArraySpecialUndef) { |
| 11790 | out_val->data.x_array.special = ConstArraySpecialUndef; |
| 11729 | 11791 | |
| 11730 | | out_val->data.x_array.s_none.elements = create_const_vals(new_array_len); |
| 11792 | TypeTableEntry *child_type = array_type->data.array.child_type; |
| 11793 | return get_array_type(ira->codegen, child_type, new_array_len); |
| 11794 | } |
| 11731 | 11795 | |
| 11732 | | expand_undef_array(ira->codegen, array_val); |
| 11796 | out_val->data.x_array.s_none.elements = create_const_vals(new_array_len); |
| 11733 | 11797 | |
| 11734 | 11798 | uint64_t i = 0; |
| 11735 | 11799 | for (uint64_t x = 0; x < mult_amt; x += 1) { |
| ... | ... | @@ -13056,7 +13120,11 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp |
| 13056 | 13120 | // one of the ptr instructions |
| 13057 | 13121 | |
| 13058 | 13122 | if (instr_is_comptime(value)) { |
| 13059 | | ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &value->value); |
| 13123 | ConstExprValue *comptime_value = ir_resolve_const(ira, value, UndefBad); |
| 13124 | if (comptime_value == nullptr) |
| 13125 | return ira->codegen->builtin_types.entry_invalid; |
| 13126 | |
| 13127 | ConstExprValue *pointee = const_ptr_pointee(ira->codegen, comptime_value); |
| 13060 | 13128 | if (pointee->type == child_type) { |
| 13061 | 13129 | ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base); |
| 13062 | 13130 | copy_const_val(out_val, pointee, value->value.data.x_ptr.mut == ConstPtrMutComptimeConst); |
| ... | ... | @@ -13173,7 +13241,7 @@ static TypeTableEntry *ir_analyze_bin_not(IrAnalyze *ira, IrInstructionUnOp *ins |
| 13173 | 13241 | if (expr_type->id == TypeTableEntryIdInt) { |
| 13174 | 13242 | if (instr_is_comptime(value)) { |
| 13175 | 13243 | ConstExprValue *target_const_val = ir_resolve_const(ira, value, UndefBad); |
| 13176 | | if (!target_const_val) |
| 13244 | if (target_const_val == nullptr) |
| 13177 | 13245 | return ira->codegen->builtin_types.entry_invalid; |
| 13178 | 13246 | |
| 13179 | 13247 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| ... | ... | @@ -17750,9 +17818,13 @@ static TypeTableEntry *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstruc |
| 17750 | 17818 | if (type_is_invalid(casted_value->value.type)) |
| 17751 | 17819 | return ira->codegen->builtin_types.entry_invalid; |
| 17752 | 17820 | |
| 17753 | | if (casted_value->value.special != ConstValSpecialRuntime) { |
| 17821 | if (instr_is_comptime(casted_value)) { |
| 17822 | ConstExprValue *value = ir_resolve_const(ira, casted_value, UndefBad); |
| 17823 | if (value == nullptr) |
| 17824 | return ira->codegen->builtin_types.entry_invalid; |
| 17825 | |
| 17754 | 17826 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 17755 | | out_val->data.x_bool = !casted_value->value.data.x_bool; |
| 17827 | out_val->data.x_bool = !value->data.x_bool; |
| 17756 | 17828 | return bool_type; |
| 17757 | 17829 | } |
| 17758 | 17830 | |