diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index 56a863677bbcc5..590b5583e118e9 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -105,7 +105,7 @@ static Value *FP(Value *v) // convert float type to same-size int type static Type *JL_INTT(Type *t) { - if (t->isIntegerTy()) + if (t->isIntegerTy() || t->isVectorTy()) return t; if (t->isPointerTy()) return T_size; @@ -360,7 +360,7 @@ static Value *emit_unbox(Type *to, const jl_cgval_t &x, jl_value_t *jt, Value *d static Value *auto_unbox(const jl_cgval_t &v, jl_codectx_t *ctx) { jl_value_t *bt = v.typ; - if (!jl_is_bitstype(bt)) { + if (!(jl_is_bitstype(bt) || jl_is_vec_type(bt))) { // This can be reached with a direct invalid call to an Intrinsic, such as: // Intrinsics.neg_int("") emit_error("auto_unbox: unable to determine argument type", ctx); @@ -392,7 +392,7 @@ static jl_value_t *staticeval_bitstype(jl_value_t *targ, const char *fname, jl_c jl_value_t *bt = NULL; if (jl_is_type_type(bt_value.typ)) bt = jl_tparam0(bt_value.typ); - if (!bt || !jl_is_bitstype(bt)) { + if (!(bt && (jl_is_bitstype(bt) || jl_is_vec_type(bt)))) { emit_error("expected bits type as first argument", ctx); return NULL; } @@ -401,7 +401,7 @@ static jl_value_t *staticeval_bitstype(jl_value_t *targ, const char *fname, jl_c static Type *staticeval_bitstype(jl_value_t *bt) { - assert(jl_is_bitstype(bt)); + assert(jl_is_bitstype(bt) || jl_is_vec_type(bt)); bool isboxed; Type *to = julia_type_to_llvm(bt, &isboxed); if (to == NULL || isboxed) { @@ -429,7 +429,7 @@ static jl_cgval_t generic_box(jl_value_t *targ, jl_value_t *x, jl_codectx_t *ctx if (jl_is_type_type(bt_value.typ)) bt = jl_tparam0(bt_value.typ); - if (!bt || !jl_is_bitstype(bt)) { + if (!(bt && (jl_is_bitstype(bt) || jl_is_vec_type(bt)))) { // it's easier to throw a good error from C than llvm Value *arg1 = boxed(bt_value, ctx); Value *arg2 = boxed(v, ctx); @@ -454,7 +454,7 @@ static jl_cgval_t generic_box(jl_value_t *targ, jl_value_t *x, jl_codectx_t *ctx || !jl_is_bitstype(v.typ) || jl_datatype_size(v.typ) != nb) { Value *typ = emit_typeof_boxed(v, ctx); - if (!jl_is_bitstype(v.typ)) { + if (!(jl_is_bitstype(v.typ) || jl_is_vec_type(v.typ))) { if (isboxed) { Value *isbits = emit_datatype_isbitstype(typ); error_unless(isbits, "reinterpret: expected bitstype value for second argument", ctx); diff --git a/src/julia.h b/src/julia.h index 4e64664f3de4b8..9dbf1894779a36 100644 --- a/src/julia.h +++ b/src/julia.h @@ -937,6 +937,24 @@ STATIC_INLINE int jl_is_vecelement_type(jl_value_t* t) ((jl_datatype_t*)(t))->name == jl_vecelement_typename); } +STATIC_INLINE int jl_is_vec_type(jl_value_t* t) +{ + if (!jl_is_tuple_type(t)) + return 0; + + jl_value_t* ft0 = jl_field_type(t, 0); + if (!jl_is_vecelement_type(ft0)) + return 0; + + size_t nf = jl_datatype_nfields(t); + for (size_t i = 1; i < nf; ++i) + if (jl_field_type(t, i) != ft0) + // Not homogeneous + return 0; + + return 1; +} + STATIC_INLINE int jl_is_type_type(jl_value_t *v) { return (jl_is_datatype(v) && diff --git a/src/runtime_intrinsics.c b/src/runtime_intrinsics.c index ddc13206b098a0..1031fa7e86b349 100644 --- a/src/runtime_intrinsics.c +++ b/src/runtime_intrinsics.c @@ -18,13 +18,14 @@ const unsigned int host_char_bit = 8; JL_DLLEXPORT jl_value_t *jl_reinterpret(jl_value_t *ty, jl_value_t *v) { JL_TYPECHK(reinterpret, datatype, ty); - if (!jl_is_leaf_type(ty) || !jl_is_bitstype(ty)) + if (!jl_is_leaf_type(ty) || !(jl_is_bitstype(ty) || jl_is_vec_type(ty))) jl_error("reinterpret: target type not a leaf bitstype"); - if (!jl_is_bitstype(jl_typeof(v))) + jl_value_t* dt = jl_typeof(v); + if (!(jl_is_bitstype(dt) || jl_is_vec_type(dt))) jl_error("reinterpret: value not a bitstype"); - if (jl_datatype_size(jl_typeof(v)) != jl_datatype_size(ty)) + if (jl_datatype_size(dt) != jl_datatype_size(ty)) jl_error("reinterpret: argument size does not match size of target type"); - if (ty == jl_typeof(v)) + if (ty == dt) return v; if (ty == (jl_value_t*)jl_bool_type) return *(uint8_t*)jl_data_ptr(v) & 1 ? jl_true : jl_false; diff --git a/test/vecelement.jl b/test/vecelement.jl index 10ea4c5d8e899d..a6c3a4dfaefe1f 100644 --- a/test/vecelement.jl +++ b/test/vecelement.jl @@ -65,3 +65,16 @@ a[1] = Gr(5.0, Bunch((VecElement(6.0), VecElement(7.0))), 8.0) @test a[2] == Gr(1.0, Bunch((VecElement(2.0), VecElement(3.0))), 4.0) @test isa(VecElement((1,2)), VecElement{Tuple{Int,Int}}) + +import Core.Intrinsics +# Test intrinsics for #18445 +# Explicit form +function trunc_vec{T1 <: Vec, T2 <: Vec}(::Type{T1}, x :: T2) + Intrinsics.box(T1, Intrinsics.trunc_int(T1, Intrinsics.unbox(T2, x))) +end + +@test trunc_vec(Vec{4, UInt8}, Vec((0xff00, 0xff01, 0x00ff, 0xf0f0))) == Vec((0x00, 0x01, 0xff, 0xf0)) +@test Intrinsics.zext_int(Vec{4, UInt16}, Vec((0x00, 0x01, 0xff, 0xf0))) == Vec((0x0000, 0x0001, 0x00ff, 0x00f0)) +@test Intrinsics.sext_int(Vec{4, UInt16}, Vec((0x00, 0x01, 0xff, 0xf0))) == Vec((0x0000, 0x0001, 0xffff, 0xfff0)) +@test Intrinsics.add_int(Vec((1,2,3,4)), Vec((1,2,3,4))) == Vec((2,4,6,8)) +# @test Intrinsics.mul_float(Vec((1.0, 2.0, 1.0, 2.0)), Vec((0.5, 0.5, 1.5, 1.5))) == Vec((0.5, 1.0, 1.5, 3.0))