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,
155155 LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type,
156156 LLVMValueRef result_loc, bool non_async);
157157static Error get_tmp_filename(CodeGen *g, Buf *out, Buf *suffix);
158static LLVMValueRef scalarize_cmp_result(CodeGen *g, LLVMValueRef val);
159158
160159static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) {
161160 unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name));
......@@ -2536,6 +2535,36 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutableGen *executable, Ir
25362535 return nullptr;
25372536}
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
25392568static LLVMValueRef gen_overflow_shl_op(CodeGen *g, ZigType *operand_type,
25402569 LLVMValueRef val1, LLVMValueRef val2)
25412570{
......@@ -2560,7 +2589,7 @@ static LLVMValueRef gen_overflow_shl_op(CodeGen *g, ZigType *operand_type,
25602589 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowOk");
25612590 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowFail");
25622591 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);
25642593 }
25652594 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,
25912620 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowOk");
25922621 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowFail");
25932622 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);
25952624 }
25962625 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) {
26472676 }
26482677}
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
26602679static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast_math,
26612680 LLVMValueRef val1, LLVMValueRef val2, ZigType *operand_type, DivKind div_kind)
26622681{
......@@ -2678,7 +2697,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast
26782697 }
26792698
26802699 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);
26822701 }
26832702
26842703 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
27032722 LLVMValueRef den_is_neg_1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, neg_1_value, "");
27042723 LLVMValueRef overflow_fail_bit = LLVMBuildAnd(g->builder, num_is_int_min, den_is_neg_1, "");
27052724 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);
27072726 }
27082727 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
27282747 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactFail");
27292748 LLVMValueRef ok_bit = LLVMBuildFCmp(g->builder, LLVMRealOEQ, floored, result, "");
27302749 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);
27322751 }
27332752 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
27452764 LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncEnd");
27462765 LLVMValueRef ltz = LLVMBuildFCmp(g->builder, LLVMRealOLT, val1, zero, "");
27472766 if (operand_type->id == ZigTypeIdVector) {
2748 ltz = scalarize_cmp_result(g, ltz);
2767 ltz = scalarize_cmp_result(g, ltz, ScalarizePredicate::Any);
27492768 }
27502769 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
27972816 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactFail");
27982817 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");
27992818 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);
28012820 }
28022821 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
28612880 }
28622881
28632882 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);
28652884 }
28662885
28672886 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
29182937 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "CheckOk");
29192938 LLVMValueRef less_than_bit = LLVMBuildICmp(g->builder, LLVMIntULT, value, bit_count_value, "");
29202939 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);
29222941 }
29232942 LLVMBuildCondBr(g->builder, less_than_bit, ok_block, fail_block);
29242943