| ... | ... | @@ -1593,35 +1593,16 @@ static const BuildBinOpFunc unsigned_op[3] = { LLVMBuildNUWAdd, LLVMBuildNUWSub, |
| 1593 | 1593 | static LLVMValueRef gen_overflow_op(CodeGen *g, ZigType *operand_type, AddSubMul op, |
| 1594 | 1594 | LLVMValueRef val1, LLVMValueRef val2) |
| 1595 | 1595 | { |
| 1596 | | LLVMValueRef overflow_bit; |
| 1597 | | LLVMValueRef result; |
| 1598 | | |
| 1596 | LLVMValueRef fn_val = get_int_overflow_fn(g, operand_type, op); |
| 1597 | LLVMValueRef params[] = { |
| 1598 | val1, |
| 1599 | val2, |
| 1600 | }; |
| 1601 | LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, ""); |
| 1602 | LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, ""); |
| 1603 | LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, ""); |
| 1599 | 1604 | if (operand_type->id == ZigTypeIdVector) { |
| 1600 | | ZigType *int_type = operand_type->data.vector.elem_type; |
| 1601 | | assert(int_type->id == ZigTypeIdInt); |
| 1602 | | LLVMTypeRef one_more_bit_int = LLVMIntType(int_type->data.integral.bit_count + 1); |
| 1603 | | LLVMTypeRef one_more_bit_int_vector = LLVMVectorType(one_more_bit_int, operand_type->data.vector.len); |
| 1604 | | const auto buildExtFn = int_type->data.integral.is_signed ? LLVMBuildSExt : LLVMBuildZExt; |
| 1605 | | LLVMValueRef extended1 = buildExtFn(g->builder, val1, one_more_bit_int_vector, ""); |
| 1606 | | LLVMValueRef extended2 = buildExtFn(g->builder, val2, one_more_bit_int_vector, ""); |
| 1607 | | LLVMValueRef extended_result = wrap_op[op](g->builder, extended1, extended2, ""); |
| 1608 | | result = LLVMBuildTrunc(g->builder, extended_result, get_llvm_type(g, operand_type), ""); |
| 1609 | | |
| 1610 | | LLVMValueRef re_extended_result = buildExtFn(g->builder, result, one_more_bit_int_vector, ""); |
| 1611 | | LLVMValueRef overflow_vector = LLVMBuildICmp(g->builder, LLVMIntNE, extended_result, re_extended_result, ""); |
| 1612 | | LLVMTypeRef bitcast_int_type = LLVMIntType(operand_type->data.vector.len); |
| 1613 | | LLVMValueRef bitcasted_overflow = LLVMBuildBitCast(g->builder, overflow_vector, bitcast_int_type, ""); |
| 1614 | | LLVMValueRef zero = LLVMConstNull(bitcast_int_type); |
| 1615 | | overflow_bit = LLVMBuildICmp(g->builder, LLVMIntNE, bitcasted_overflow, zero, ""); |
| 1616 | | } else { |
| 1617 | | LLVMValueRef fn_val = get_int_overflow_fn(g, operand_type, op); |
| 1618 | | LLVMValueRef params[] = { |
| 1619 | | val1, |
| 1620 | | val2, |
| 1621 | | }; |
| 1622 | | LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, ""); |
| 1623 | | result = LLVMBuildExtractValue(g->builder, result_struct, 0, ""); |
| 1624 | | overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, ""); |
| 1605 | overflow_bit = ZigLLVMBuildOrReduce(g->builder, overflow_bit); |
| 1625 | 1606 | } |
| 1626 | 1607 | |
| 1627 | 1608 | LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowFail"); |