| ... | @@ -16635,34 +16635,47 @@ static IrInstGen *ir_analyze_bit_shift(IrAnalyze *ira, IrInstSrcBinOp *bin_op_in | ... | @@ -16635,34 +16635,47 @@ static IrInstGen *ir_analyze_bit_shift(IrAnalyze *ira, IrInstSrcBinOp *bin_op_in |
| 16635 | IrInstGen *casted_op2; | 16635 | IrInstGen *casted_op2; |
| 16636 | IrBinOp op_id = bin_op_instruction->op_id; | 16636 | IrBinOp op_id = bin_op_instruction->op_id; |
| 16637 | if (op1->value->type->id == ZigTypeIdComptimeInt) { | 16637 | if (op1->value->type->id == ZigTypeIdComptimeInt) { |
| | 16638 | // comptime_int has no finite bit width |
| 16638 | casted_op2 = op2; | 16639 | casted_op2 = op2; |
| 16639 | | 16640 | |
| 16640 | if (op_id == IrBinOpBitShiftLeftLossy) { | 16641 | if (op_id == IrBinOpBitShiftLeftLossy) { |
| 16641 | op_id = IrBinOpBitShiftLeftExact; | 16642 | op_id = IrBinOpBitShiftLeftExact; |
| 16642 | } | 16643 | } |
| 16643 | | 16644 | |
| 16644 | if (casted_op2->value->data.x_bigint.is_negative) { | 16645 | if (!instr_is_comptime(op2)) { |
| | 16646 | ir_add_error(ira, &bin_op_instruction->base.base, |
| | 16647 | buf_sprintf("LHS of shift must be an integer type, or RHS must be compile-time known")); |
| | 16648 | return ira->codegen->invalid_inst_gen; |
| | 16649 | } |
| | 16650 | |
| | 16651 | ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); |
| | 16652 | if (op2_val == nullptr) |
| | 16653 | return ira->codegen->invalid_inst_gen; |
| | 16654 | |
| | 16655 | if (op2_val->data.x_bigint.is_negative) { |
| 16645 | Buf *val_buf = buf_alloc(); | 16656 | Buf *val_buf = buf_alloc(); |
| 16646 | bigint_append_buf(val_buf, &casted_op2->value->data.x_bigint, 10); | 16657 | bigint_append_buf(val_buf, &op2_val->data.x_bigint, 10); |
| 16647 | ir_add_error(ira, &casted_op2->base, buf_sprintf("shift by negative value %s", buf_ptr(val_buf))); | 16658 | ir_add_error(ira, &casted_op2->base, |
| | 16659 | buf_sprintf("shift by negative value %s", buf_ptr(val_buf))); |
| 16648 | return ira->codegen->invalid_inst_gen; | 16660 | return ira->codegen->invalid_inst_gen; |
| 16649 | } | 16661 | } |
| 16650 | } else { | 16662 | } else { |
| 16651 | assert(op1->value->type->data.integral.bit_count > 0); | 16663 | const unsigned bit_count = op1->value->type->data.integral.bit_count; |
| 16652 | ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, | 16664 | ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, |
| 16653 | op1->value->type->data.integral.bit_count - 1); | 16665 | bit_count > 0 ? bit_count - 1 : 0); |
| 16654 | | 16666 | |
| 16655 | casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); | 16667 | casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); |
| 16656 | if (type_is_invalid(casted_op2->value->type)) | 16668 | if (type_is_invalid(casted_op2->value->type)) |
| 16657 | return ira->codegen->invalid_inst_gen; | 16669 | return ira->codegen->invalid_inst_gen; |
| 16658 | | 16670 | |
| 16659 | if (instr_is_comptime(casted_op2)) { | 16671 | // This check is only valid iff op1 has at least one bit |
| | 16672 | if (bit_count > 0 && instr_is_comptime(casted_op2)) { |
| 16660 | ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); | 16673 | ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); |
| 16661 | if (op2_val == nullptr) | 16674 | if (op2_val == nullptr) |
| 16662 | return ira->codegen->invalid_inst_gen; | 16675 | return ira->codegen->invalid_inst_gen; |
| 16663 | | 16676 | |
| 16664 | BigInt bit_count_value = {0}; | 16677 | BigInt bit_count_value = {0}; |
| 16665 | bigint_init_unsigned(&bit_count_value, op1->value->type->data.integral.bit_count); | 16678 | bigint_init_unsigned(&bit_count_value, bit_count); |
| 16666 | | 16679 | |
| 16667 | if (bigint_cmp(&op2_val->data.x_bigint, &bit_count_value) != CmpLT) { | 16680 | if (bigint_cmp(&op2_val->data.x_bigint, &bit_count_value) != CmpLT) { |
| 16668 | ErrorMsg* msg = ir_add_error(ira, | 16681 | ErrorMsg* msg = ir_add_error(ira, |
| ... | @@ -16670,14 +16683,23 @@ static IrInstGen *ir_analyze_bit_shift(IrAnalyze *ira, IrInstSrcBinOp *bin_op_in | ... | @@ -16670,14 +16683,23 @@ static IrInstGen *ir_analyze_bit_shift(IrAnalyze *ira, IrInstSrcBinOp *bin_op_in |
| 16670 | buf_sprintf("RHS of shift is too large for LHS type")); | 16683 | buf_sprintf("RHS of shift is too large for LHS type")); |
| 16671 | add_error_note(ira->codegen, msg, op1->base.source_node, | 16684 | add_error_note(ira->codegen, msg, op1->base.source_node, |
| 16672 | buf_sprintf("type %s has only %u bits", | 16685 | buf_sprintf("type %s has only %u bits", |
| 16673 | buf_ptr(&op1->value->type->name), | 16686 | buf_ptr(&op1->value->type->name), bit_count)); |
| 16674 | op1->value->type->data.integral.bit_count)); | | |
| 16675 | | 16687 | |
| 16676 | return ira->codegen->invalid_inst_gen; | 16688 | return ira->codegen->invalid_inst_gen; |
| 16677 | } | 16689 | } |
| 16678 | } | 16690 | } |
| 16679 | } | 16691 | } |
| 16680 | | 16692 | |
| | 16693 | // Fast path for zero RHS |
| | 16694 | if (instr_is_comptime(casted_op2)) { |
| | 16695 | ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); |
| | 16696 | if (op2_val == nullptr) |
| | 16697 | return ira->codegen->invalid_inst_gen; |
| | 16698 | |
| | 16699 | if (bigint_cmp_zero(&op2_val->data.x_bigint) == CmpEQ) |
| | 16700 | return ir_analyze_cast(ira, &bin_op_instruction->base.base, op1->value->type, op1); |
| | 16701 | } |
| | 16702 | |
| 16681 | if (instr_is_comptime(op1) && instr_is_comptime(casted_op2)) { | 16703 | if (instr_is_comptime(op1) && instr_is_comptime(casted_op2)) { |
| 16682 | ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); | 16704 | ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); |
| 16683 | if (op1_val == nullptr) | 16705 | if (op1_val == nullptr) |
| ... | @@ -16688,12 +16710,6 @@ static IrInstGen *ir_analyze_bit_shift(IrAnalyze *ira, IrInstSrcBinOp *bin_op_in | ... | @@ -16688,12 +16710,6 @@ static IrInstGen *ir_analyze_bit_shift(IrAnalyze *ira, IrInstSrcBinOp *bin_op_in |
| 16688 | return ira->codegen->invalid_inst_gen; | 16710 | return ira->codegen->invalid_inst_gen; |
| 16689 | | 16711 | |
| 16690 | return ir_analyze_math_op(ira, &bin_op_instruction->base.base, op1->value->type, op1_val, op_id, op2_val); | 16712 | return ir_analyze_math_op(ira, &bin_op_instruction->base.base, op1->value->type, op1_val, op_id, op2_val); |
| 16691 | } else if (op1->value->type->id == ZigTypeIdComptimeInt) { | | |
| 16692 | ir_add_error(ira, &bin_op_instruction->base.base, | | |
| 16693 | buf_sprintf("LHS of shift must be an integer type, or RHS must be compile-time known")); | | |
| 16694 | return ira->codegen->invalid_inst_gen; | | |
| 16695 | } else if (instr_is_comptime(casted_op2) && bigint_cmp_zero(&casted_op2->value->data.x_bigint) == CmpEQ) { | | |
| 16696 | return ir_build_cast(ira, &bin_op_instruction->base.base, op1->value->type, op1, CastOpNoop); | | |
| 16697 | } | 16713 | } |
| 16698 | | 16714 | |
| 16699 | return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, op1->value->type, | 16715 | return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, op1->value->type, |