Skip to content

Commit af5d5a6

Browse files
imciner2KristofferC
authored andcommitted
Fix codegen for sizeof for arrays with non-power-of-2 types (#35900)
(cherry picked from commit a383d61)
1 parent 9a8fedd commit af5d5a6

File tree

4 files changed

+56
-2
lines changed

4 files changed

+56
-2
lines changed

base/subarray.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ size(V::SubArray) = (@_inline_meta; map(n->Int(unsafe_length(n)), axes(V)))
6464

6565
similar(V::SubArray, T::Type, dims::Dims) = similar(V.parent, T, dims)
6666

67-
sizeof(V::SubArray) = length(V) * sizeof(eltype(V))
67+
sizeof(V::SubArray) = length(V) * elsize(V.parent)
6868

6969
copy(V::SubArray) = V.parent[V.indices...]
7070

src/codegen.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2484,7 +2484,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
24842484
*ret = mark_julia_type(ctx, len, false, jl_long_type);
24852485
return true;
24862486
}
2487-
else if (jl_is_datatype(sty) && sty->name == jl_array_typename) {
2487+
else if (jl_is_array_type(sty)) {
24882488
auto len = emit_arraylen(ctx, obj);
24892489
jl_value_t *ety = jl_tparam0(sty);
24902490
Value *elsize;
@@ -2495,6 +2495,11 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
24952495
if (isboxed) {
24962496
elsize = ConstantInt::get(T_size, sizeof(void*));
24972497
}
2498+
else if (jl_is_primitivetype(ety)) {
2499+
// Primitive types should use the array element size, but
2500+
// this can be different from the type's size
2501+
elsize = ConstantInt::get(T_size, LLT_ALIGN(elsz, al));
2502+
}
24982503
else {
24992504
elsize = ConstantInt::get(T_size, elsz);
25002505
}

test/abstractarray.jl

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,3 +937,40 @@ end
937937
@testset "vcat with mixed elements" begin
938938
@test vcat(Nothing[], [missing], [1.0], [Int8(1)]) isa Vector{Union{Missing, Nothing, Float64}}
939939
end
940+
941+
@testset "sizeof" begin
942+
let arrUInt8 = zeros(UInt8, 10)
943+
@test sizeof(arrUInt8) == 10
944+
@test Core.sizeof(arrUInt8) == 10
945+
end
946+
947+
let arrUInt32 = zeros(UInt32, 10)
948+
@test sizeof(arrUInt32) == 40
949+
@test Core.sizeof(arrUInt32) == 40
950+
end
951+
952+
let arrFloat64 = zeros(Float64, 10, 10)
953+
@test sizeof(arrFloat64) == 800
954+
@test Core.sizeof(arrFloat64) == 800
955+
end
956+
957+
# Test union arrays (Issue #23321)
958+
let arrUnion = Union{Int64, Cvoid}[rand(Bool) ? k : nothing for k = 1:10]
959+
@test sizeof(arrUnion) == 80
960+
@test Core.sizeof(arrUnion) == 80
961+
end
962+
963+
# Test non-power of 2 types (Issue #35884)
964+
primitive type UInt48 48 end
965+
UInt48(x::UInt64) = Core.Intrinsics.trunc_int(UInt48, x)
966+
UInt48(x::UInt32) = Core.Intrinsics.zext_int(UInt48, x)
967+
968+
a = UInt48(0x00000001);
969+
b = UInt48(0x00000002);
970+
c = UInt48(0x00000003);
971+
let arrayOfUInt48 = [a, b, c]
972+
f35884(x) = sizeof(x)
973+
@test f35884(arrayOfUInt48) == 24
974+
@test Core.sizeof(arrayOfUInt48) == 24
975+
end
976+
end

test/subarray.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,18 @@ end
589589
@test sizeof(view(zeros(UInt8, 10), 1:4)) == 4
590590
@test sizeof(view(zeros(UInt8, 10), 1:3)) == 3
591591
@test sizeof(view(zeros(Float64, 10, 10), 1:3, 2:6)) == 120
592+
593+
# Test non-power of 2 types (Issue #35884)
594+
primitive type UInt48 48 end
595+
UInt48(x::UInt64) = Core.Intrinsics.trunc_int(UInt48, x)
596+
UInt48(x::UInt32) = Core.Intrinsics.zext_int(UInt48, x)
597+
598+
a = UInt48(0x00000001);
599+
b = UInt48(0x00000002);
600+
c = UInt48(0x00000003);
601+
arrayOfUInt48 = [a, b, c];
602+
603+
@test sizeof(view(arrayOfUInt48, 1:2)) == 16
592604
end
593605

594606

0 commit comments

Comments
 (0)