From ae371d105dec7a203041f7d53ba682d8724ada00 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Tue, 28 Sep 2021 19:43:59 +0200 Subject: [PATCH] Add vector ++ -- ! ~ - | & ^ ops and allow .c3t to be compiled. --- src/compiler/compiler.c | 3 +- src/compiler/compiler_internal.h | 14 +- src/compiler/llvm_codegen_expr.c | 52 +++++- src/compiler/sema_expr.c | 17 +- src/compiler/types.c | 7 + src/version.h | 2 +- test/test_suite/vector/vector_bit.c3t | 164 +++++++++++++++++++ test/test_suite/vector/vector_incdec.c3t | 191 +++++++++++++++++++++++ test/test_suite/vector/vector_init.c3t | 1 + test/test_suite/vector/vector_ops.c3t | 1 + 10 files changed, 439 insertions(+), 13 deletions(-) create mode 100644 test/test_suite/vector/vector_bit.c3t create mode 100644 test/test_suite/vector/vector_incdec.c3t diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 62e2cbf4f..e242d720c 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -465,7 +465,8 @@ static void target_expand_source_names(BuildTarget *target) goto INVALID_NAME; } if (name_len < 4) goto INVALID_NAME; - if (strcmp(&name[name_len - 3], ".c3") != 0) goto INVALID_NAME; + if (strcmp(&name[name_len - 3], ".c3") != 0 && + (name_len < 5 || strcmp(&name[name_len - 4], ".c3t") != 0)) goto INVALID_NAME; vec_add(files, name); continue; INVALID_NAME: diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 9b0551d37..953e64502 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -1672,15 +1672,22 @@ size_t bigint_popcount_signed(const BigInt *bi, size_t bit_count); size_t bigint_popcount_unsigned(const BigInt *big_int); void type_setup(PlatformTarget *target); -static inline bool builtin_may_negate(Type *canonical) +static inline bool type_may_negate(Type *type) { - assert(canonical->canonical == canonical); - switch (canonical->type_kind) + RETRY: + switch (type->type_kind) { case ALL_FLOATS: case ALL_SIGNED_INTS: + case TYPE_VECTOR: case TYPE_IXX: return true; + case TYPE_DISTINCT: + type = type->decl->distinct_decl.base_type; + goto RETRY; + case TYPE_TYPEDEF: + type = type->canonical; + goto RETRY; default: return false; } @@ -1976,6 +1983,7 @@ Type *type_get_subarray(Type *arr_type); Type *type_get_inferred_array(Type *arr_type); Type *type_get_vector(Type *vector_type, unsigned len); +Type *type_get_vector_bool(Type *original_type); Type *type_cint(void); Type *type_cuint(void); Type *type_int_signed_by_bitsize(unsigned bitsize); diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index eb915a263..d8f6c06b8 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -21,10 +21,7 @@ LLVMValueRef llvm_emit_is_no_error_value(GenContext *c, BEValue *value) void llvm_convert_vector_comparison(GenContext *c, BEValue *be_value, LLVMValueRef val, Type *vector_type) { - vector_type = type_flatten(vector_type); - ByteSize width = vector_type->vector.len; - ByteSize element_size = type_size(vector_type->vector.base); - Type *result_type = type_get_vector(type_int_signed_by_bitsize(element_size * 8), width); + Type *result_type = type_get_vector_bool(vector_type); val = LLVMBuildSExt(c->builder, val, llvm_get_type(c, result_type), ""); llvm_value_set(be_value, val, result_type); } @@ -1260,6 +1257,37 @@ static inline void llvm_emit_inc_dec_change(GenContext *c, bool use_mod, BEValue : llvm_emit_sub_int(c, type, value.value, diff_value, TOKLOC(expr->span.loc)); break; } + case TYPE_VECTOR: + { + Type *element = type->vector.base; + LLVMValueRef diff_value; + bool is_integer = type_is_integer(element); + if (is_integer) + { + diff_value = LLVMConstInt(llvm_get_type(c, element), 1, false); + } + else + { + diff_value = LLVMConstReal(llvm_get_type(c, element), diff); + } + ArrayIndex width = type->vector.len; + LLVMValueRef val = LLVMGetUndef(llvm_get_type(c, type)); + for (ArrayIndex i = 0; i < width; i++) + { + val = LLVMConstInsertElement(val, diff_value, llvm_const_int(c, type_usize, i)); + } + if (is_integer) + { + after_value = diff > 0 + ? llvm_emit_add_int(c, type, value.value, val, TOKLOC(expr->span.loc)) + : llvm_emit_sub_int(c, type, value.value, val, TOKLOC(expr->span.loc)); + } + else + { + after_value = LLVMBuildFAdd(c->builder, value.value, val, "fincdec"); + } + break; + } default: UNREACHABLE } @@ -1315,6 +1343,22 @@ static void gencontext_emit_unary_expr(GenContext *c, BEValue *value, Expr *expr case UNARYOP_NOT: llvm_emit_expr(c, value, inner); llvm_value_rvalue(c, value); + if (type_is_vector(type)) + { + Type *vec_type = type_vector_type(type); + if (type_is_float(vec_type)) + { + llvm_value = LLVMBuildFCmp(c->builder, LLVMRealUNE, value->value, llvm_get_zero(c, type), "not"); + } + else + { + llvm_value = LLVMBuildICmp(c->builder, LLVMIntEQ, value->value, llvm_get_zero(c, type), "not"); + } + Type *res_type = type_get_vector_bool(type); + llvm_value = LLVMBuildSExt(c->builder, llvm_value, llvm_get_type(c, res_type), ""); + llvm_value_set(value, llvm_value, res_type); + return; + } if (type_is_float(type)) { llvm_value = LLVMBuildFCmp(c->builder, LLVMRealUNE, value->value, llvm_get_zero(c, type), "not"); diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index c4e5d7cd2..c2970a4a3 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -9,6 +9,7 @@ * - Disallow jumping in and out of an expression block. */ + static inline void expr_set_as_const_list(Expr *expr, ConstInitializer *list) { expr->expr_kind = EXPR_CONST; @@ -4688,8 +4689,7 @@ DONE: // 8a. Except for vector, set to signed type with the correct size. if (left_type->type_kind == TYPE_VECTOR) { - ByteSize size = type_size(left_type->vector.base); - expr_set_type(expr, type_get_vector(type_int_signed_by_bitsize(size * 8), left_type->vector.len)); + expr_set_type(expr, type_get_vector_bool(left_type)); return true; } expr_set_type(expr, type_bool); @@ -4886,8 +4886,7 @@ static bool sema_expr_analyse_addr(Context *context, Type *to, Expr *expr, Expr static bool sema_expr_analyse_neg(Context *context, Type *to, Expr *expr, Expr *inner) { - Type *canonical = inner->type->canonical; - if (!builtin_may_negate(canonical)) + if (!type_may_negate(inner->type)) { SEMA_ERROR(expr, "Cannot negate %s.", type_to_error_string(inner->type)); return false; @@ -4937,9 +4936,13 @@ static bool sema_expr_analyse_bit_not(Context *context, Type *to, Expr *expr, Ex } if (!type_is_any_integer(canonical) && canonical != type_bool) { + Type *vector_type = type_vector_type(canonical); + if (type_is_any_integer(vector_type) || vector_type == type_bool) goto VALID_VEC; SEMA_ERROR(expr, "Cannot bit negate '%s'.", type_to_error_string(inner->type)); return false; } + +VALID_VEC: // The simple case, non-const. if (inner->expr_kind != EXPR_CONST) { @@ -4970,6 +4973,12 @@ static bool sema_expr_analyse_bit_not(Context *context, Type *to, Expr *expr, Ex static bool sema_expr_analyse_not(Expr *expr, Expr *inner) { + if (type_is_vector(inner->type)) + { + expr_copy_properties(expr, inner); + expr_set_type(expr, type_get_vector_bool(inner->type)); + return true; + } if (!cast_may_implicit(inner->type, type_bool)) { SEMA_ERROR(expr, "The use of '!' on %s is not allowed as it can't be converted to a boolean value.", type_quoted_error_string(inner->type)); diff --git a/src/compiler/types.c b/src/compiler/types.c index 14c01c36c..3c43e9de3 100644 --- a/src/compiler/types.c +++ b/src/compiler/types.c @@ -1063,6 +1063,13 @@ bool type_is_valid_for_vector(Type *type) } } +Type *type_get_vector_bool(Type *original_type) +{ + Type *type = type_flatten(original_type); + ByteSize size = type_size(type->vector.base); + return type_get_vector(type_int_signed_by_bitsize(size * 8), original_type->vector.len); +} + Type *type_get_vector(Type *vector_type, unsigned len) { return type_create_array(vector_type, len, true, false); diff --git a/src/version.h b/src/version.h index 1e7dbbf91..70523c841 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "A236" \ No newline at end of file +#define COMPILER_VERSION "A237" \ No newline at end of file diff --git a/test/test_suite/vector/vector_bit.c3t b/test/test_suite/vector/vector_bit.c3t new file mode 100644 index 000000000..2de0c7840 --- /dev/null +++ b/test/test_suite/vector/vector_bit.c3t @@ -0,0 +1,164 @@ +// #target: x64-darwin + +import libc; + +func void testf() +{ + float[<4>] y = { 0, 2, 3, 0 }; + int[<4>] w = !y; + libc::printf("Notf %d %d %d %d\n", w[0], w[1], w[2], w[3]); +} + +func void testi() +{ + int[<4>] y = { 1, 2, 3, 4 }; + int[<4>] z = { 2, 3, 13, -100 }; + int[<4>] w; + w = y & z; + libc::printf("And %d %d %d %d\n", w[0], w[1], w[2], w[3]); + w = y | z; + libc::printf("Or %d %d %d %d\n", w[0], w[1], w[2], w[3]); + w = y ^ z; + libc::printf("Xor %d %d %d %d\n", w[0], w[1], w[2], w[3]); + w = ~y; + libc::printf("BitNeg %d %d %d %d\n", w[0], w[1], w[2], w[3]); + w = -y; + libc::printf("Neg %d %d %d %d\n", w[0], w[1], w[2], w[3]); + w = !y; + w = { -1, 13, 0, 0 }; + w = !w; + libc::printf("Not %d %d %d %d\n", w[0], w[1], w[2], w[3]); +} + +func void main() +{ + testf(); + testi(); +} + +/* #expect: vector_bit.ll + +; Function Attrs: nounwind +define void @vector_bit.testf() #0 { +entry: + %y = alloca <4 x float>, align 16 + %w = alloca <4 x i32>, align 16 + store <4 x float> , <4 x float>* %y, align 16 + %0 = load <4 x float>, <4 x float>* %y, align 16 + %not = fcmp une <4 x float> %0, zeroinitializer + %1 = sext <4 x i1> %not to <4 x i32> + store <4 x i32> %1, <4 x i32>* %w, align 16 + %2 = load <4 x i32>, <4 x i32>* %w, align 16 + %3 = extractelement <4 x i32> %2, i64 0 + %4 = load <4 x i32>, <4 x i32>* %w, align 16 + %5 = extractelement <4 x i32> %4, i64 1 + %6 = load <4 x i32>, <4 x i32>* %w, align 16 + %7 = extractelement <4 x i32> %6, i64 2 + %8 = load <4 x i32>, <4 x i32>* %w, align 16 + %9 = extractelement <4 x i32> %8, i64 3 + %10 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str, i32 0, i32 0), i32 %3, i32 %5, i32 %7, i32 %9) + ret void +} + +; Function Attrs: nounwind +define void @vector_bit.testi() #0 { +entry: + %y = alloca <4 x i32>, align 16 + %z = alloca <4 x i32>, align 16 + %w = alloca <4 x i32>, align 16 + store <4 x i32> , <4 x i32>* %y, align 16 + store <4 x i32> , <4 x i32>* %z, align 16 + %0 = bitcast <4 x i32>* %w to i8* + call void @llvm.memset.p0i8.i64(i8* align 16 %0, i8 0, i64 16, i1 false) + %1 = load <4 x i32>, <4 x i32>* %y, align 16 + %2 = load <4 x i32>, <4 x i32>* %z, align 16 + %and = and <4 x i32> %1, %2 + store <4 x i32> %and, <4 x i32>* %w, align 16 + %3 = load <4 x i32>, <4 x i32>* %w, align 16 + %4 = extractelement <4 x i32> %3, i64 0 + %5 = load <4 x i32>, <4 x i32>* %w, align 16 + %6 = extractelement <4 x i32> %5, i64 1 + %7 = load <4 x i32>, <4 x i32>* %w, align 16 + %8 = extractelement <4 x i32> %7, i64 2 + %9 = load <4 x i32>, <4 x i32>* %w, align 16 + %10 = extractelement <4 x i32> %9, i64 3 + %11 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 %4, i32 %6, i32 %8, i32 %10) + %12 = load <4 x i32>, <4 x i32>* %y, align 16 + %13 = load <4 x i32>, <4 x i32>* %z, align 16 + %or = or <4 x i32> %12, %13 + store <4 x i32> %or, <4 x i32>* %w, align 16 + %14 = load <4 x i32>, <4 x i32>* %w, align 16 + %15 = extractelement <4 x i32> %14, i64 0 + %16 = load <4 x i32>, <4 x i32>* %w, align 16 + %17 = extractelement <4 x i32> %16, i64 1 + %18 = load <4 x i32>, <4 x i32>* %w, align 16 + %19 = extractelement <4 x i32> %18, i64 2 + %20 = load <4 x i32>, <4 x i32>* %w, align 16 + %21 = extractelement <4 x i32> %20, i64 3 + %22 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.2, i32 0, i32 0), i32 %15, i32 %17, i32 %19, i32 %21) + %23 = load <4 x i32>, <4 x i32>* %y, align 16 + %24 = load <4 x i32>, <4 x i32>* %z, align 16 + %xor = xor <4 x i32> %23, %24 + store <4 x i32> %xor, <4 x i32>* %w, align 16 + %25 = load <4 x i32>, <4 x i32>* %w, align 16 + %26 = extractelement <4 x i32> %25, i64 0 + %27 = load <4 x i32>, <4 x i32>* %w, align 16 + %28 = extractelement <4 x i32> %27, i64 1 + %29 = load <4 x i32>, <4 x i32>* %w, align 16 + %30 = extractelement <4 x i32> %29, i64 2 + %31 = load <4 x i32>, <4 x i32>* %w, align 16 + %32 = extractelement <4 x i32> %31, i64 3 + %33 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.3, i32 0, i32 0), i32 %26, i32 %28, i32 %30, i32 %32) + %34 = load <4 x i32>, <4 x i32>* %y, align 16 + %bnot = xor <4 x i32> %34, + store <4 x i32> %bnot, <4 x i32>* %w, align 16 + %35 = load <4 x i32>, <4 x i32>* %w, align 16 + %36 = extractelement <4 x i32> %35, i64 0 + %37 = load <4 x i32>, <4 x i32>* %w, align 16 + %38 = extractelement <4 x i32> %37, i64 1 + %39 = load <4 x i32>, <4 x i32>* %w, align 16 + %40 = extractelement <4 x i32> %39, i64 2 + %41 = load <4 x i32>, <4 x i32>* %w, align 16 + %42 = extractelement <4 x i32> %41, i64 3 + %43 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.4, i32 0, i32 0), i32 %36, i32 %38, i32 %40, i32 %42) + %44 = load <4 x i32>, <4 x i32>* %y, align 16 + %45 = load <4 x i32>, <4 x i32>* %y, align 16 + %neg = sub <4 x i32> zeroinitializer, %45 + store <4 x i32> %neg, <4 x i32>* %w, align 16 + %46 = load <4 x i32>, <4 x i32>* %w, align 16 + %47 = extractelement <4 x i32> %46, i64 0 + %48 = load <4 x i32>, <4 x i32>* %w, align 16 + %49 = extractelement <4 x i32> %48, i64 1 + %50 = load <4 x i32>, <4 x i32>* %w, align 16 + %51 = extractelement <4 x i32> %50, i64 2 + %52 = load <4 x i32>, <4 x i32>* %w, align 16 + %53 = extractelement <4 x i32> %52, i64 3 + %54 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.5, i32 0, i32 0), i32 %47, i32 %49, i32 %51, i32 %53) + %55 = load <4 x i32>, <4 x i32>* %y, align 16 + %not = icmp eq <4 x i32> %55, zeroinitializer + %56 = sext <4 x i1> %not to <4 x i32> + store <4 x i32> %56, <4 x i32>* %w, align 16 + store <4 x i32> , <4 x i32>* %w, align 16 + %57 = load <4 x i32>, <4 x i32>* %w, align 16 + %not1 = icmp eq <4 x i32> %57, zeroinitializer + %58 = sext <4 x i1> %not1 to <4 x i32> + store <4 x i32> %58, <4 x i32>* %w, align 16 + %59 = load <4 x i32>, <4 x i32>* %w, align 16 + %60 = extractelement <4 x i32> %59, i64 0 + %61 = load <4 x i32>, <4 x i32>* %w, align 16 + %62 = extractelement <4 x i32> %61, i64 1 + %63 = load <4 x i32>, <4 x i32>* %w, align 16 + %64 = extractelement <4 x i32> %63, i64 2 + %65 = load <4 x i32>, <4 x i32>* %w, align 16 + %66 = extractelement <4 x i32> %65, i64 3 + %67 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.6, i32 0, i32 0), i32 %60, i32 %62, i32 %64, i32 %66) + ret void +} + +; Function Attrs: nounwind +define void @main() #0 { +entry: + call void @vector_bit.testf() + call void @vector_bit.testi() + ret void +} \ No newline at end of file diff --git a/test/test_suite/vector/vector_incdec.c3t b/test/test_suite/vector/vector_incdec.c3t new file mode 100644 index 000000000..c88b37420 --- /dev/null +++ b/test/test_suite/vector/vector_incdec.c3t @@ -0,0 +1,191 @@ +// #target: x64-darwin +import libc; + +func void testf() +{ + float[<4>] y = { 1, 2, 3, 4 }; + float[<4>] z = { 2, 2, 2, -100 }; + y += z; + libc::printf("Add %f %f %f %f\n", y[0], y[1], y[2], y[3]); + y++; + libc::printf("Inc %f %f %f %f\n", y[0], y[1], y[2], y[3]); + ++y; + libc::printf("Inc %f %f %f %f\n", y[0], y[1], y[2], y[3]); + y--; + libc::printf("Dec %f %f %f %f\n", y[0], y[1], y[2], y[3]); +} + +func void testi() +{ + int[<4>] y = { 1, 2, 3, 4 }; + int[<4>] z = { 2, 2, 2, -100 }; + y += z; + libc::printf("Add %d %d %d %d\n", y[0], y[1], y[2], y[3]); + y++; + libc::printf("Inc %d %d %d %d\n", y[0], y[1], y[2], y[3]); + ++y; + libc::printf("Inc %d %d %d %d\n", y[0], y[1], y[2], y[3]); + int[<4>]w = y--; + libc::printf("Dec %d %d %d %d\n", y[0], y[1], y[2], y[3]); + libc::printf("Original %d %d %d %d\n", w[0], w[1], w[2], w[3]); +} + +func void main() +{ + testf(); + testi(); +} + +/* #expect: vector_incdec.ll + +define void @vector_incdec.testf() #0 { +entry: + %y = alloca <4 x float>, align 16 + %z = alloca <4 x float>, align 16 + store <4 x float> , <4 x float>* %y, align 16 + store <4 x float> , <4 x float>* %z, align 16 + %0 = load <4 x float>, <4 x float>* %y, align 16 + %1 = load <4 x float>, <4 x float>* %z, align 16 + %fadd = fadd <4 x float> %0, %1 + store <4 x float> %fadd, <4 x float>* %y, align 16 + %2 = load <4 x float>, <4 x float>* %y, align 16 + %3 = extractelement <4 x float> %2, i64 0 + %fpfpext = fpext float %3 to double + %4 = load <4 x float>, <4 x float>* %y, align 16 + %5 = extractelement <4 x float> %4, i64 1 + %fpfpext1 = fpext float %5 to double + %6 = load <4 x float>, <4 x float>* %y, align 16 + %7 = extractelement <4 x float> %6, i64 2 + %fpfpext2 = fpext float %7 to double + %8 = load <4 x float>, <4 x float>* %y, align 16 + %9 = extractelement <4 x float> %8, i64 3 + %fpfpext3 = fpext float %9 to double + %10 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str, i32 0, i32 0), double %fpfpext, double %fpfpext1, double %fpfpext2, double %fpfpext3) + %11 = load <4 x float>, <4 x float>* %y, align 16 + %fincdec = fadd <4 x float> %11, + store <4 x float> %fincdec, <4 x float>* %y, align 16 + %12 = load <4 x float>, <4 x float>* %y, align 16 + %13 = extractelement <4 x float> %12, i64 0 + %fpfpext4 = fpext float %13 to double + %14 = load <4 x float>, <4 x float>* %y, align 16 + %15 = extractelement <4 x float> %14, i64 1 + %fpfpext5 = fpext float %15 to double + %16 = load <4 x float>, <4 x float>* %y, align 16 + %17 = extractelement <4 x float> %16, i64 2 + %fpfpext6 = fpext float %17 to double + %18 = load <4 x float>, <4 x float>* %y, align 16 + %19 = extractelement <4 x float> %18, i64 3 + %fpfpext7 = fpext float %19 to double + %20 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), double %fpfpext4, double %fpfpext5, double %fpfpext6, double %fpfpext7) + %21 = load <4 x float>, <4 x float>* %y, align 16 + %fincdec8 = fadd <4 x float> %21, + store <4 x float> %fincdec8, <4 x float>* %y, align 16 + %22 = load <4 x float>, <4 x float>* %y, align 16 + %23 = extractelement <4 x float> %22, i64 0 + %fpfpext9 = fpext float %23 to double + %24 = load <4 x float>, <4 x float>* %y, align 16 + %25 = extractelement <4 x float> %24, i64 1 + %fpfpext10 = fpext float %25 to double + %26 = load <4 x float>, <4 x float>* %y, align 16 + %27 = extractelement <4 x float> %26, i64 2 + %fpfpext11 = fpext float %27 to double + %28 = load <4 x float>, <4 x float>* %y, align 16 + %29 = extractelement <4 x float> %28, i64 3 + %fpfpext12 = fpext float %29 to double + %30 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.2, i32 0, i32 0), double %fpfpext9, double %fpfpext10, double %fpfpext11, double %fpfpext12) + %31 = load <4 x float>, <4 x float>* %y, align 16 + %fincdec13 = fadd <4 x float> %31, + store <4 x float> %fincdec13, <4 x float>* %y, align 16 + %32 = load <4 x float>, <4 x float>* %y, align 16 + %33 = extractelement <4 x float> %32, i64 0 + %fpfpext14 = fpext float %33 to double + %34 = load <4 x float>, <4 x float>* %y, align 16 + %35 = extractelement <4 x float> %34, i64 1 + %fpfpext15 = fpext float %35 to double + %36 = load <4 x float>, <4 x float>* %y, align 16 + %37 = extractelement <4 x float> %36, i64 2 + %fpfpext16 = fpext float %37 to double + %38 = load <4 x float>, <4 x float>* %y, align 16 + %39 = extractelement <4 x float> %38, i64 3 + %fpfpext17 = fpext float %39 to double + %40 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.3, i32 0, i32 0), double %fpfpext14, double %fpfpext15, double %fpfpext16, double %fpfpext17) + ret void +} + +; Function Attrs: nounwind +define void @vector_incdec.testi() #0 { +entry: + %y = alloca <4 x i32>, align 16 + %z = alloca <4 x i32>, align 16 + %w = alloca <4 x i32>, align 16 + store <4 x i32> , <4 x i32>* %y, align 16 + store <4 x i32> , <4 x i32>* %z, align 16 + %0 = load <4 x i32>, <4 x i32>* %y, align 16 + %1 = load <4 x i32>, <4 x i32>* %z, align 16 + %add = add <4 x i32> %0, %1 + store <4 x i32> %add, <4 x i32>* %y, align 16 + %2 = load <4 x i32>, <4 x i32>* %y, align 16 + %3 = extractelement <4 x i32> %2, i64 0 + %4 = load <4 x i32>, <4 x i32>* %y, align 16 + %5 = extractelement <4 x i32> %4, i64 1 + %6 = load <4 x i32>, <4 x i32>* %y, align 16 + %7 = extractelement <4 x i32> %6, i64 2 + %8 = load <4 x i32>, <4 x i32>* %y, align 16 + %9 = extractelement <4 x i32> %8, i64 3 + %10 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.4, i32 0, i32 0), i32 %3, i32 %5, i32 %7, i32 %9) + %11 = load <4 x i32>, <4 x i32>* %y, align 16 + %add1 = add <4 x i32> %11, + store <4 x i32> %add1, <4 x i32>* %y, align 16 + %12 = load <4 x i32>, <4 x i32>* %y, align 16 + %13 = extractelement <4 x i32> %12, i64 0 + %14 = load <4 x i32>, <4 x i32>* %y, align 16 + %15 = extractelement <4 x i32> %14, i64 1 + %16 = load <4 x i32>, <4 x i32>* %y, align 16 + %17 = extractelement <4 x i32> %16, i64 2 + %18 = load <4 x i32>, <4 x i32>* %y, align 16 + %19 = extractelement <4 x i32> %18, i64 3 + %20 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.5, i32 0, i32 0), i32 %13, i32 %15, i32 %17, i32 %19) + %21 = load <4 x i32>, <4 x i32>* %y, align 16 + %add2 = add <4 x i32> %21, + store <4 x i32> %add2, <4 x i32>* %y, align 16 + %22 = load <4 x i32>, <4 x i32>* %y, align 16 + %23 = extractelement <4 x i32> %22, i64 0 + %24 = load <4 x i32>, <4 x i32>* %y, align 16 + %25 = extractelement <4 x i32> %24, i64 1 + %26 = load <4 x i32>, <4 x i32>* %y, align 16 + %27 = extractelement <4 x i32> %26, i64 2 + %28 = load <4 x i32>, <4 x i32>* %y, align 16 + %29 = extractelement <4 x i32> %28, i64 3 + %30 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.6, i32 0, i32 0), i32 %23, i32 %25, i32 %27, i32 %29) + %31 = load <4 x i32>, <4 x i32>* %y, align 16 + %sub = sub <4 x i32> %31, + store <4 x i32> %sub, <4 x i32>* %y, align 16 + store <4 x i32> %31, <4 x i32>* %w, align 16 + %32 = load <4 x i32>, <4 x i32>* %y, align 16 + %33 = extractelement <4 x i32> %32, i64 0 + %34 = load <4 x i32>, <4 x i32>* %y, align 16 + %35 = extractelement <4 x i32> %34, i64 1 + %36 = load <4 x i32>, <4 x i32>* %y, align 16 + %37 = extractelement <4 x i32> %36, i64 2 + %38 = load <4 x i32>, <4 x i32>* %y, align 16 + %39 = extractelement <4 x i32> %38, i64 3 + %40 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.7, i32 0, i32 0), i32 %33, i32 %35, i32 %37, i32 %39) + %41 = load <4 x i32>, <4 x i32>* %w, align 16 + %42 = extractelement <4 x i32> %41, i64 0 + %43 = load <4 x i32>, <4 x i32>* %w, align 16 + %44 = extractelement <4 x i32> %43, i64 1 + %45 = load <4 x i32>, <4 x i32>* %w, align 16 + %46 = extractelement <4 x i32> %45, i64 2 + %47 = load <4 x i32>, <4 x i32>* %w, align 16 + %48 = extractelement <4 x i32> %47, i64 3 + %49 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.8, i32 0, i32 0), i32 %42, i32 %44, i32 %46, i32 %48) + ret void +} + +; Function Attrs: nounwind +define void @main() #0 { +entry: + call void @vector_incdec.testf() + call void @vector_incdec.testi() + ret void +} diff --git a/test/test_suite/vector/vector_init.c3t b/test/test_suite/vector/vector_init.c3t index 26940aecb..33a2c0675 100644 --- a/test/test_suite/vector/vector_init.c3t +++ b/test/test_suite/vector/vector_init.c3t @@ -1,3 +1,4 @@ +// #target: x64-darwin int[<4>] baz = { 1, 4, 5, 7 }; func void main() diff --git a/test/test_suite/vector/vector_ops.c3t b/test/test_suite/vector/vector_ops.c3t index 86d1a591b..f0df89951 100644 --- a/test/test_suite/vector/vector_ops.c3t +++ b/test/test_suite/vector/vector_ops.c3t @@ -1,3 +1,4 @@ +// #target: x64-darwin import libc; func void testf()