authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-04-05 10:40:41+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-05 18:34:31-04:00
logf6cdc94a50235eaf145f6c2c2ec257008d592494
tree5225b4d0fe332afabb6bedd3f8e24aa900ad8e73
parent0f964e19109d44d039fbefa691657ca82c7bbe52
signaturelock-open Commit is signed but in an unrecognized format.

ir: Fix error checking for vector ops

The extra logic that's needed was lost during a refactoring, now it should be fine.

1 files changed, 39 insertions(+), 20 deletions(-)

src/codegen.cpp+39-20
...@@ -155,7 +155,6 @@ static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr,...@@ -155,7 +155,6 @@ static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr,
155 LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type,155 LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type,
156 LLVMValueRef result_loc, bool non_async);156 LLVMValueRef result_loc, bool non_async);
157static Error get_tmp_filename(CodeGen *g, Buf *out, Buf *suffix);157static Error get_tmp_filename(CodeGen *g, Buf *out, Buf *suffix);
158static LLVMValueRef scalarize_cmp_result(CodeGen *g, LLVMValueRef val);
159158
160static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) {159static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) {
161 unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name));160 unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name));
...@@ -2536,6 +2535,36 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutableGen *executable, Ir...@@ -2536,6 +2535,36 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutableGen *executable, Ir
2536 return nullptr;2535 return nullptr;
2537}2536}
25382537
2538enum class ScalarizePredicate {
2539 // Returns true iff all the elements in the vector are 1.
2540 // Equivalent to folding all the bits with `and`.
2541 All,
2542 // Returns true iff there's at least one element in the vector that is 1.
2543 // Equivalent to folding all the bits with `or`.
2544 Any,
2545};
2546
2547// Collapses a <N x i1> vector into a single i1 according to the given predicate
2548static LLVMValueRef scalarize_cmp_result(CodeGen *g, LLVMValueRef val, ScalarizePredicate predicate) {
2549 assert(LLVMGetTypeKind(LLVMTypeOf(val)) == LLVMVectorTypeKind);
2550 LLVMTypeRef scalar_type = LLVMIntType(LLVMGetVectorSize(LLVMTypeOf(val)));
2551 LLVMValueRef casted = LLVMBuildBitCast(g->builder, val, scalar_type, "");
2552
2553 switch (predicate) {
2554 case ScalarizePredicate::Any: {
2555 LLVMValueRef all_zeros = LLVMConstNull(scalar_type);
2556 return LLVMBuildICmp(g->builder, LLVMIntNE, casted, all_zeros, "");
2557 }
2558 case ScalarizePredicate::All: {
2559 LLVMValueRef all_ones = LLVMConstAllOnes(scalar_type);
2560 return LLVMBuildICmp(g->builder, LLVMIntEQ, casted, all_ones, "");
2561 }
2562 }
2563
2564 zig_unreachable();
2565}
2566
2567
2539static LLVMValueRef gen_overflow_shl_op(CodeGen *g, ZigType *operand_type,2568static LLVMValueRef gen_overflow_shl_op(CodeGen *g, ZigType *operand_type,
2540 LLVMValueRef val1, LLVMValueRef val2)2569 LLVMValueRef val1, LLVMValueRef val2)
2541{2570{
...@@ -2560,7 +2589,7 @@ static LLVMValueRef gen_overflow_shl_op(CodeGen *g, ZigType *operand_type,...@@ -2560,7 +2589,7 @@ static LLVMValueRef gen_overflow_shl_op(CodeGen *g, ZigType *operand_type,
2560 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowOk");2589 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowOk");
2561 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowFail");2590 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowFail");
2562 if (operand_type->id == ZigTypeIdVector) {2591 if (operand_type->id == ZigTypeIdVector) {
2563 ok_bit = scalarize_cmp_result(g, ok_bit);2592 ok_bit = scalarize_cmp_result(g, ok_bit, ScalarizePredicate::All);
2564 }2593 }
2565 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);2594 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
25662595
...@@ -2591,7 +2620,7 @@ static LLVMValueRef gen_overflow_shr_op(CodeGen *g, ZigType *operand_type,...@@ -2591,7 +2620,7 @@ static LLVMValueRef gen_overflow_shr_op(CodeGen *g, ZigType *operand_type,
2591 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowOk");2620 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowOk");
2592 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowFail");2621 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowFail");
2593 if (operand_type->id == ZigTypeIdVector) {2622 if (operand_type->id == ZigTypeIdVector) {
2594 ok_bit = scalarize_cmp_result(g, ok_bit);2623 ok_bit = scalarize_cmp_result(g, ok_bit, ScalarizePredicate::All);
2595 }2624 }
2596 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);2625 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
25972626
...@@ -2647,16 +2676,6 @@ static LLVMValueRef bigint_to_llvm_const(LLVMTypeRef type_ref, BigInt *bigint) {...@@ -2647,16 +2676,6 @@ static LLVMValueRef bigint_to_llvm_const(LLVMTypeRef type_ref, BigInt *bigint) {
2647 }2676 }
2648}2677}
26492678
2650// Collapses a <N x i1> vector into a single i1 whose value is 1 iff all the
2651// vector elements are 1
2652static LLVMValueRef scalarize_cmp_result(CodeGen *g, LLVMValueRef val) {
2653 assert(LLVMGetTypeKind(LLVMTypeOf(val)) == LLVMVectorTypeKind);
2654 LLVMTypeRef scalar_type = LLVMIntType(LLVMGetVectorSize(LLVMTypeOf(val)));
2655 LLVMValueRef all_ones = LLVMConstAllOnes(scalar_type);
2656 LLVMValueRef casted = LLVMBuildBitCast(g->builder, val, scalar_type, "");
2657 return LLVMBuildICmp(g->builder, LLVMIntEQ, casted, all_ones, "");
2658}
2659
2660static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast_math,2679static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast_math,
2661 LLVMValueRef val1, LLVMValueRef val2, ZigType *operand_type, DivKind div_kind)2680 LLVMValueRef val1, LLVMValueRef val2, ZigType *operand_type, DivKind div_kind)
2662{2681{
...@@ -2678,7 +2697,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast...@@ -2678,7 +2697,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast
2678 }2697 }
26792698
2680 if (operand_type->id == ZigTypeIdVector) {2699 if (operand_type->id == ZigTypeIdVector) {
2681 is_zero_bit = scalarize_cmp_result(g, is_zero_bit);2700 is_zero_bit = scalarize_cmp_result(g, is_zero_bit, ScalarizePredicate::Any);
2682 }2701 }
26832702
2684 LLVMBasicBlockRef div_zero_fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivZeroFail");2703 LLVMBasicBlockRef div_zero_fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivZeroFail");
...@@ -2703,7 +2722,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast...@@ -2703,7 +2722,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast
2703 LLVMValueRef den_is_neg_1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, neg_1_value, "");2722 LLVMValueRef den_is_neg_1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, neg_1_value, "");
2704 LLVMValueRef overflow_fail_bit = LLVMBuildAnd(g->builder, num_is_int_min, den_is_neg_1, "");2723 LLVMValueRef overflow_fail_bit = LLVMBuildAnd(g->builder, num_is_int_min, den_is_neg_1, "");
2705 if (operand_type->id == ZigTypeIdVector) {2724 if (operand_type->id == ZigTypeIdVector) {
2706 overflow_fail_bit = scalarize_cmp_result(g, overflow_fail_bit);2725 overflow_fail_bit = scalarize_cmp_result(g, overflow_fail_bit, ScalarizePredicate::Any);
2707 }2726 }
2708 LLVMBuildCondBr(g->builder, overflow_fail_bit, overflow_fail_block, overflow_ok_block);2727 LLVMBuildCondBr(g->builder, overflow_fail_bit, overflow_fail_block, overflow_ok_block);
27092728
...@@ -2728,7 +2747,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast...@@ -2728,7 +2747,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast
2728 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactFail");2747 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactFail");
2729 LLVMValueRef ok_bit = LLVMBuildFCmp(g->builder, LLVMRealOEQ, floored, result, "");2748 LLVMValueRef ok_bit = LLVMBuildFCmp(g->builder, LLVMRealOEQ, floored, result, "");
2730 if (operand_type->id == ZigTypeIdVector) {2749 if (operand_type->id == ZigTypeIdVector) {
2731 ok_bit = scalarize_cmp_result(g, ok_bit);2750 ok_bit = scalarize_cmp_result(g, ok_bit, ScalarizePredicate::All);
2732 }2751 }
2733 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);2752 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
27342753
...@@ -2745,7 +2764,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast...@@ -2745,7 +2764,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast
2745 LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncEnd");2764 LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncEnd");
2746 LLVMValueRef ltz = LLVMBuildFCmp(g->builder, LLVMRealOLT, val1, zero, "");2765 LLVMValueRef ltz = LLVMBuildFCmp(g->builder, LLVMRealOLT, val1, zero, "");
2747 if (operand_type->id == ZigTypeIdVector) {2766 if (operand_type->id == ZigTypeIdVector) {
2748 ltz = scalarize_cmp_result(g, ltz);2767 ltz = scalarize_cmp_result(g, ltz, ScalarizePredicate::Any);
2749 }2768 }
2750 LLVMBuildCondBr(g->builder, ltz, ltz_block, gez_block);2769 LLVMBuildCondBr(g->builder, ltz, ltz_block, gez_block);
27512770
...@@ -2797,7 +2816,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast...@@ -2797,7 +2816,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast
2797 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactFail");2816 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactFail");
2798 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");2817 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");
2799 if (operand_type->id == ZigTypeIdVector) {2818 if (operand_type->id == ZigTypeIdVector) {
2800 ok_bit = scalarize_cmp_result(g, ok_bit);2819 ok_bit = scalarize_cmp_result(g, ok_bit, ScalarizePredicate::All);
2801 }2820 }
2802 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);2821 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
28032822
...@@ -2861,7 +2880,7 @@ static LLVMValueRef gen_rem(CodeGen *g, bool want_runtime_safety, bool want_fast...@@ -2861,7 +2880,7 @@ static LLVMValueRef gen_rem(CodeGen *g, bool want_runtime_safety, bool want_fast
2861 }2880 }
28622881
2863 if (operand_type->id == ZigTypeIdVector) {2882 if (operand_type->id == ZigTypeIdVector) {
2864 is_zero_bit = scalarize_cmp_result(g, is_zero_bit);2883 is_zero_bit = scalarize_cmp_result(g, is_zero_bit, ScalarizePredicate::Any);
2865 }2884 }
28662885
2867 LLVMBasicBlockRef rem_zero_ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "RemZeroOk");2886 LLVMBasicBlockRef rem_zero_ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "RemZeroOk");
...@@ -2918,7 +2937,7 @@ static void gen_shift_rhs_check(CodeGen *g, ZigType *lhs_type, ZigType *rhs_type...@@ -2918,7 +2937,7 @@ static void gen_shift_rhs_check(CodeGen *g, ZigType *lhs_type, ZigType *rhs_type
2918 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "CheckOk");2937 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "CheckOk");
2919 LLVMValueRef less_than_bit = LLVMBuildICmp(g->builder, LLVMIntULT, value, bit_count_value, "");2938 LLVMValueRef less_than_bit = LLVMBuildICmp(g->builder, LLVMIntULT, value, bit_count_value, "");
2920 if (rhs_type->id == ZigTypeIdVector) {2939 if (rhs_type->id == ZigTypeIdVector) {
2921 less_than_bit = scalarize_cmp_result(g, less_than_bit);2940 less_than_bit = scalarize_cmp_result(g, less_than_bit, ScalarizePredicate::Any);
2922 }2941 }
2923 LLVMBuildCondBr(g->builder, less_than_bit, ok_block, fail_block);2942 LLVMBuildCondBr(g->builder, less_than_bit, ok_block, fail_block);
29242943