Skip to content

stage2 fixes #11974

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

Merged
merged 5 commits into from
Jul 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion lib/std/simd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ pub fn extract(
}

test "vector patterns" {
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
const base = @Vector(4, u32){ 10, 20, 30, 40 };
const other_base = @Vector(4, u32){ 55, 66, 77, 88 };

Expand Down
6 changes: 1 addition & 5 deletions src/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1024,10 +1024,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
if (options.use_llvm) |explicit|
break :blk explicit;

// If we are outputting .c code we must use Zig backend.
if (ofmt == .c)
break :blk false;

// If emitting to LLVM bitcode object format, must use LLVM backend.
if (options.emit_llvm_ir != null or options.emit_llvm_bc != null)
break :blk true;
Expand All @@ -1042,7 +1038,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
break :blk true;

// If LLVM does not support the target, then we can't use it.
if (!target_util.hasLlvmSupport(options.target))
if (!target_util.hasLlvmSupport(options.target, ofmt))
break :blk false;

// Prefer LLVM for release builds.
Expand Down
23 changes: 15 additions & 8 deletions src/codegen/llvm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,11 @@ pub const Object = struct {
if (ptr_info.@"align" != 0) {
dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align");
} else {
dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.pointee_type.abiAlignment(target));
const elem_align = @maximum(
ptr_info.pointee_type.abiAlignment(target),
1,
);
dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);
}
}
}
Expand Down Expand Up @@ -840,7 +844,8 @@ pub const Object = struct {
if (ptr_info.@"align" != 0) {
dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align");
} else {
dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.pointee_type.abiAlignment(target));
const elem_align = @maximum(ptr_info.pointee_type.abiAlignment(target), 1);
dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);
}
const ptr_param = llvm_func.getParam(llvm_arg_i);
llvm_arg_i += 1;
Expand Down Expand Up @@ -3401,13 +3406,21 @@ pub const DeclGen = struct {
const union_obj = tv.ty.cast(Type.Payload.Union).?.data;
const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, dg.module).?;
assert(union_obj.haveFieldTypes());

// Sometimes we must make an unnamed struct because LLVM does
// not support bitcasting our payload struct to the true union payload type.
// Instead we use an unnamed struct and every reference to the global
// must pointer cast to the expected type before accessing the union.
var need_unnamed: bool = layout.most_aligned_field != field_index;

const field_ty = union_obj.fields.values()[field_index].ty;
const payload = p: {
if (!field_ty.hasRuntimeBitsIgnoreComptime()) {
const padding_len = @intCast(c_uint, layout.payload_size);
break :p dg.context.intType(8).arrayType(padding_len).getUndef();
}
const field = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val });
need_unnamed = need_unnamed or dg.isUnnamedType(field_ty, field);
const field_size = field_ty.abiSize(target);
if (field_size == layout.payload_size) {
break :p field;
Expand All @@ -3419,12 +3432,6 @@ pub const DeclGen = struct {
break :p dg.context.constStruct(&fields, fields.len, .True);
};

// In this case we must make an unnamed struct because LLVM does
// not support bitcasting our payload struct to the true union payload type.
// Instead we use an unnamed struct and every reference to the global
// must pointer cast to the expected type before accessing the union.
const need_unnamed = layout.most_aligned_field != field_index;

if (layout.tag_size == 0) {
const fields: [1]*const llvm.Value = .{payload};
if (need_unnamed) {
Expand Down
19 changes: 18 additions & 1 deletion src/target.zig
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,24 @@ pub fn hasValgrindSupport(target: std.Target) bool {
/// The set of targets that LLVM has non-experimental support for.
/// Used to select between LLVM backend and self-hosted backend when compiling in
/// release modes.
pub fn hasLlvmSupport(target: std.Target) bool {
pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool {
switch (ofmt) {
// LLVM does not support these object formats:
.c,
.plan9,
=> return false,

.coff,
.elf,
.macho,
.wasm,
.spirv,
.hex,
.raw,
.nvptx,
=> {},
}

return switch (target.cpu.arch) {
.arm,
.armeb,
Expand Down
10 changes: 7 additions & 3 deletions src/type.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2906,9 +2906,13 @@ pub const Type = extern union {

.array, .array_sentinel => return ty.elemType().abiAlignmentAdvanced(target, strat),

// TODO audit this - is there any more complicated logic to determine
// ABI alignment of vectors?
.vector => return AbiAlignmentAdvanced{ .scalar = 16 },
.vector => {
const len = ty.arrayLen();
const bits = try bitSizeAdvanced(ty.elemType(), target, sema_kit);
const bytes = (bits + 7) / 8;
const alignment = std.math.ceilPowerOfTwoAssert(u64, bytes * len);
return AbiAlignmentAdvanced{ .scalar = @intCast(u32, alignment) };
},

.i16, .u16 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(16, target) },
.u29 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(29, target) },
Expand Down
24 changes: 24 additions & 0 deletions test/behavior/vector.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1048,3 +1048,27 @@ test "@shlWithOverflow" {
try S.doTheTest();
comptime try S.doTheTest();
}

test "alignment of vectors" {
try expect(@alignOf(@Vector(2, u8)) == 2);
try expect(@alignOf(@Vector(2, u1)) == 2);
try expect(@alignOf(@Vector(1, u1)) == 1);
try expect(@alignOf(@Vector(2, u16)) == 4);
}

test "loading the second vector from a slice of vectors" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO

@setRuntimeSafety(false);
var small_bases = [2]@Vector(2, u8){
@Vector(2, u8){ 0, 1 },
@Vector(2, u8){ 2, 3 },
};
var a: []const @Vector(2, u8) = &small_bases;
var a4 = a[1][1];
try expect(a4 == 3);
}
5 changes: 0 additions & 5 deletions test/cases/plan9/exit.zig

This file was deleted.

28 changes: 0 additions & 28 deletions test/cases/plan9/hello_world_with_updates.0.zig

This file was deleted.

10 changes: 0 additions & 10 deletions test/cases/plan9/hello_world_with_updates.1.zig

This file was deleted.