Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

llvm: handle vectors in packed structs #14004

Merged
merged 8 commits into from
Dec 20, 2022
Merged
2 changes: 1 addition & 1 deletion src/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ pub const AllErrors = struct {
self.arena.promote(gpa).deinit();
}

fn add(
pub fn add(
module: *Module,
arena: *std.heap.ArenaAllocator,
errors: *std.ArrayList(Message),
Expand Down
261 changes: 156 additions & 105 deletions src/Sema.zig

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion src/arch/x86_64/abi.zig
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
.integer, .integer, .integer, .integer,
.integer, .integer, .integer, .integer,
};
if (has_avx512 and bit_size <= 256) return .{
const has_avx = target.cpu.features.isEnabled(@enumToInt(std.Target.x86.Feature.avx));
if (has_avx and bit_size <= 256) return .{
.integer, .integer, .integer, .integer,
.none, .none, .none, .none,
};
Expand Down
6 changes: 3 additions & 3 deletions src/codegen/llvm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5966,7 +5966,7 @@ pub const FuncGen = struct {
const shift_amt = containing_int.typeOf().constInt(bit_offset, .False);
const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");
const elem_llvm_ty = try self.dg.lowerType(field_ty);
if (field_ty.zigTypeTag() == .Float) {
if (field_ty.zigTypeTag() == .Float or field_ty.zigTypeTag() == .Vector) {
const elem_bits = @intCast(c_uint, field_ty.bitSize(target));
const same_size_int = self.context.intType(elem_bits);
const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
Expand All @@ -5989,7 +5989,7 @@ pub const FuncGen = struct {
assert(struct_ty.containerLayout() == .Packed);
const containing_int = struct_llvm_val;
const elem_llvm_ty = try self.dg.lowerType(field_ty);
if (field_ty.zigTypeTag() == .Float) {
if (field_ty.zigTypeTag() == .Float or field_ty.zigTypeTag() == .Vector) {
const elem_bits = @intCast(c_uint, field_ty.bitSize(target));
const same_size_int = self.context.intType(elem_bits);
const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");
Expand Down Expand Up @@ -9889,7 +9889,7 @@ pub const FuncGen = struct {
return result_ptr;
}

if (info.pointee_type.zigTypeTag() == .Float) {
if (info.pointee_type.zigTypeTag() == .Float or info.pointee_type.zigTypeTag() == .Vector) {
const same_size_int = self.context.intType(elem_bits);
const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
Expand Down
451 changes: 311 additions & 140 deletions src/value.zig

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions test/behavior/bitcast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,6 @@ test "comptime @bitCast packed struct to int and back" {
const rt_cast = @bitCast(S, i);
const ct_cast = comptime @bitCast(S, @as(Int, 0));
inline for (@typeInfo(S).Struct.fields) |field| {
if (@typeInfo(field.type) == .Vector)
continue; //TODO: https://github.com/ziglang/zig/issues/13201

try expectEqual(@field(rt_cast, field.name), @field(ct_cast, field.name));
}
}
Expand Down
37 changes: 37 additions & 0 deletions test/behavior/call.zig
Original file line number Diff line number Diff line change
Expand Up @@ -344,3 +344,40 @@ test "inline call doesn't re-evaluate non generic struct" {
try @call(.always_inline, S.foo, ArgTuple{.{ .a = 123, .b = 45 }});
comptime try @call(.always_inline, S.foo, ArgTuple{.{ .a = 123, .b = 45 }});
}

test "Enum constructed by @Type passed as generic argument" {
const S = struct {
const E = std.meta.FieldEnum(struct {
prev_pos: bool,
pos: bool,
vel: bool,
damp_vel: bool,
acc: bool,
rgba: bool,
prev_scale: bool,
scale: bool,
prev_rotation: bool,
rotation: bool,
angular_vel: bool,
alive: bool,
});
fn foo(comptime a: E, b: u32) !void {
try expect(@enumToInt(a) == b);
}
};
inline for (@typeInfo(S.E).Enum.fields) |_, i| {
try S.foo(@intToEnum(S.E, i), i);
}
}

test "generic function with generic function parameter" {
const S = struct {
fn f(comptime a: fn (anytype) anyerror!void, b: anytype) anyerror!void {
try a(b);
}
fn g(a: anytype) anyerror!void {
try expect(a == 123);
}
};
try S.f(S.g, 123);
}
10 changes: 10 additions & 0 deletions test/behavior/cast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1495,3 +1495,13 @@ test "cast typed undefined to int" {
_ = b;
}
}

test "implicit cast from [:0]T to [*c]T" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO

var a: [:0]const u8 = "foo";
var b: [*c]const u8 = a;
var c = std.mem.span(b);
try expect(c.len == a.len);
try expect(c.ptr == a.ptr);
}
13 changes: 13 additions & 0 deletions test/c_abi/cfuncs.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,19 @@ SmallVec c_ret_small_vec(void) {
return (SmallVec){3, 4};
}

typedef size_t MediumVec __attribute__((vector_size(4 * sizeof(size_t))));

void c_medium_vec(MediumVec vec) {
assert_or_panic(vec[0] == 1);
assert_or_panic(vec[1] == 2);
assert_or_panic(vec[2] == 3);
assert_or_panic(vec[3] == 4);
}

MediumVec c_ret_medium_vec(void) {
return (MediumVec){5, 6, 7, 8};
}

typedef size_t BigVec __attribute__((vector_size(8 * sizeof(size_t))));

void c_big_vec(BigVec vec) {
Expand Down
17 changes: 17 additions & 0 deletions test/c_abi/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,23 @@ test "small simd vector" {
try expect(x[1] == 4);
}

const MediumVec = @Vector(4, usize);

extern fn c_medium_vec(MediumVec) void;
extern fn c_ret_medium_vec() MediumVec;

test "medium simd vector" {
if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;

c_medium_vec(.{ 1, 2, 3, 4 });

var x = c_ret_medium_vec();
try expect(x[0] == 5);
try expect(x[1] == 6);
try expect(x[2] == 7);
try expect(x[3] == 8);
}

const BigVec = @Vector(8, usize);

extern fn c_big_vec(BigVec) void;
Expand Down
6 changes: 6 additions & 0 deletions test/cases/compile_errors/noalias_on_non_pointer_param.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
fn f(noalias x: i32) void { _ = x; }
export fn entry() void { f(1234); }

fn generic(comptime T: type, noalias _: [*]T, noalias _: [*]const T, _: usize) void {}
comptime { _ = generic; }

fn slice(noalias _: []u8) void {}
comptime { _ = slice; }

// error
// backend=stage2
// target=native
Expand Down