| author | |
| committer | |
| log | 2360f8c490f3ec684ed64ff28e8c1fade249070b |
| tree | f39083118406b53b0de41b99ee88a4269cc537ab |
| parent | 7e2eb1326ba267012d47aa2eda539f01963d4d6b |
| parent | 095e24e537fcb6a702b992d946d1ca73d6f608b3 |
| signature |
stage2 fixes9 files changed, 65 insertions(+), 61 deletions(-)
lib/std/simd.zig-1| ... | @@ -160,7 +160,6 @@ pub fn extract( | ... | @@ -160,7 +160,6 @@ pub fn extract( |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | test "vector patterns" { | 162 | test "vector patterns" { |
| 163 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; | ||
| 164 | const base = @Vector(4, u32){ 10, 20, 30, 40 }; | 163 | const base = @Vector(4, u32){ 10, 20, 30, 40 }; |
| 165 | const other_base = @Vector(4, u32){ 55, 66, 77, 88 }; | 164 | const other_base = @Vector(4, u32){ 55, 66, 77, 88 }; |
| 166 | 165 |
src/Compilation.zig+1-5| ... | @@ -1024,10 +1024,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1024,10 +1024,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1024 | if (options.use_llvm) |explicit| | 1024 | if (options.use_llvm) |explicit| |
| 1025 | break :blk explicit; | 1025 | break :blk explicit; |
| 1026 | 1026 | ||
| 1027 | // If we are outputting .c code we must use Zig backend. | ||
| 1028 | if (ofmt == .c) | ||
| 1029 | break :blk false; | ||
| 1030 | |||
| 1031 | // If emitting to LLVM bitcode object format, must use LLVM backend. | 1027 | // If emitting to LLVM bitcode object format, must use LLVM backend. |
| 1032 | if (options.emit_llvm_ir != null or options.emit_llvm_bc != null) | 1028 | if (options.emit_llvm_ir != null or options.emit_llvm_bc != null) |
| 1033 | break :blk true; | 1029 | break :blk true; |
| ... | @@ -1042,7 +1038,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1042,7 +1038,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1042 | break :blk true; | 1038 | break :blk true; |
| 1043 | 1039 | ||
| 1044 | // If LLVM does not support the target, then we can't use it. | 1040 | // If LLVM does not support the target, then we can't use it. |
| 1045 | if (!target_util.hasLlvmSupport(options.target)) | 1041 | if (!target_util.hasLlvmSupport(options.target, ofmt)) |
| 1046 | break :blk false; | 1042 | break :blk false; |
| 1047 | 1043 | ||
| 1048 | // Prefer LLVM for release builds. | 1044 | // Prefer LLVM for release builds. |
src/codegen/llvm.zig+15-8| ... | @@ -768,7 +768,11 @@ pub const Object = struct { | ... | @@ -768,7 +768,11 @@ pub const Object = struct { |
| 768 | if (ptr_info.@"align" != 0) { | 768 | if (ptr_info.@"align" != 0) { |
| 769 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align"); | 769 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align"); |
| 770 | } else { | 770 | } else { |
| 771 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.pointee_type.abiAlignment(target)); | 771 | const elem_align = @maximum( |
| 772 | ptr_info.pointee_type.abiAlignment(target), | ||
| 773 | 1, | ||
| 774 | ); | ||
| 775 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align); | ||
| 772 | } | 776 | } |
| 773 | } | 777 | } |
| 774 | } | 778 | } |
| ... | @@ -840,7 +844,8 @@ pub const Object = struct { | ... | @@ -840,7 +844,8 @@ pub const Object = struct { |
| 840 | if (ptr_info.@"align" != 0) { | 844 | if (ptr_info.@"align" != 0) { |
| 841 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align"); | 845 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align"); |
| 842 | } else { | 846 | } else { |
| 843 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.pointee_type.abiAlignment(target)); | 847 | const elem_align = @maximum(ptr_info.pointee_type.abiAlignment(target), 1); |
| 848 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align); | ||
| 844 | } | 849 | } |
| 845 | const ptr_param = llvm_func.getParam(llvm_arg_i); | 850 | const ptr_param = llvm_func.getParam(llvm_arg_i); |
| 846 | llvm_arg_i += 1; | 851 | llvm_arg_i += 1; |
| ... | @@ -3401,6 +3406,13 @@ pub const DeclGen = struct { | ... | @@ -3401,6 +3406,13 @@ pub const DeclGen = struct { |
| 3401 | const union_obj = tv.ty.cast(Type.Payload.Union).?.data; | 3406 | const union_obj = tv.ty.cast(Type.Payload.Union).?.data; |
| 3402 | const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, dg.module).?; | 3407 | const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, dg.module).?; |
| 3403 | assert(union_obj.haveFieldTypes()); | 3408 | assert(union_obj.haveFieldTypes()); |
| 3409 | |||
| 3410 | // Sometimes we must make an unnamed struct because LLVM does | ||
| 3411 | // not support bitcasting our payload struct to the true union payload type. | ||
| 3412 | // Instead we use an unnamed struct and every reference to the global | ||
| 3413 | // must pointer cast to the expected type before accessing the union. | ||
| 3414 | var need_unnamed: bool = layout.most_aligned_field != field_index; | ||
| 3415 | |||
| 3404 | const field_ty = union_obj.fields.values()[field_index].ty; | 3416 | const field_ty = union_obj.fields.values()[field_index].ty; |
| 3405 | const payload = p: { | 3417 | const payload = p: { |
| 3406 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) { | 3418 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) { |
| ... | @@ -3408,6 +3420,7 @@ pub const DeclGen = struct { | ... | @@ -3408,6 +3420,7 @@ pub const DeclGen = struct { |
| 3408 | break :p dg.context.intType(8).arrayType(padding_len).getUndef(); | 3420 | break :p dg.context.intType(8).arrayType(padding_len).getUndef(); |
| 3409 | } | 3421 | } |
| 3410 | const field = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val }); | 3422 | const field = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val }); |
| 3423 | need_unnamed = need_unnamed or dg.isUnnamedType(field_ty, field); | ||
| 3411 | const field_size = field_ty.abiSize(target); | 3424 | const field_size = field_ty.abiSize(target); |
| 3412 | if (field_size == layout.payload_size) { | 3425 | if (field_size == layout.payload_size) { |
| 3413 | break :p field; | 3426 | break :p field; |
| ... | @@ -3419,12 +3432,6 @@ pub const DeclGen = struct { | ... | @@ -3419,12 +3432,6 @@ pub const DeclGen = struct { |
| 3419 | break :p dg.context.constStruct(&fields, fields.len, .True); | 3432 | break :p dg.context.constStruct(&fields, fields.len, .True); |
| 3420 | }; | 3433 | }; |
| 3421 | 3434 | ||
| 3422 | // In this case we must make an unnamed struct because LLVM does | ||
| 3423 | // not support bitcasting our payload struct to the true union payload type. | ||
| 3424 | // Instead we use an unnamed struct and every reference to the global | ||
| 3425 | // must pointer cast to the expected type before accessing the union. | ||
| 3426 | const need_unnamed = layout.most_aligned_field != field_index; | ||
| 3427 | |||
| 3428 | if (layout.tag_size == 0) { | 3435 | if (layout.tag_size == 0) { |
| 3429 | const fields: [1]*const llvm.Value = .{payload}; | 3436 | const fields: [1]*const llvm.Value = .{payload}; |
| 3430 | if (need_unnamed) { | 3437 | if (need_unnamed) { |
src/target.zig+18-1| ... | @@ -204,7 +204,24 @@ pub fn hasValgrindSupport(target: std.Target) bool { | ... | @@ -204,7 +204,24 @@ pub fn hasValgrindSupport(target: std.Target) bool { |
| 204 | /// The set of targets that LLVM has non-experimental support for. | 204 | /// The set of targets that LLVM has non-experimental support for. |
| 205 | /// Used to select between LLVM backend and self-hosted backend when compiling in | 205 | /// Used to select between LLVM backend and self-hosted backend when compiling in |
| 206 | /// release modes. | 206 | /// release modes. |
| 207 | pub fn hasLlvmSupport(target: std.Target) bool { | 207 | pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool { |
| 208 | switch (ofmt) { | ||
| 209 | // LLVM does not support these object formats: | ||
| 210 | .c, | ||
| 211 | .plan9, | ||
| 212 | => return false, | ||
| 213 | |||
| 214 | .coff, | ||
| 215 | .elf, | ||
| 216 | .macho, | ||
| 217 | .wasm, | ||
| 218 | .spirv, | ||
| 219 | .hex, | ||
| 220 | .raw, | ||
| 221 | .nvptx, | ||
| 222 | => {}, | ||
| 223 | } | ||
| 224 | |||
| 208 | return switch (target.cpu.arch) { | 225 | return switch (target.cpu.arch) { |
| 209 | .arm, | 226 | .arm, |
| 210 | .armeb, | 227 | .armeb, |
src/type.zig+7-3| ... | @@ -2906,9 +2906,13 @@ pub const Type = extern union { | ... | @@ -2906,9 +2906,13 @@ pub const Type = extern union { |
| 2906 | 2906 | ||
| 2907 | .array, .array_sentinel => return ty.elemType().abiAlignmentAdvanced(target, strat), | 2907 | .array, .array_sentinel => return ty.elemType().abiAlignmentAdvanced(target, strat), |
| 2908 | 2908 | ||
| 2909 | // TODO audit this - is there any more complicated logic to determine | 2909 | .vector => { |
| 2910 | // ABI alignment of vectors? | 2910 | const len = ty.arrayLen(); |
| 2911 | .vector => return AbiAlignmentAdvanced{ .scalar = 16 }, | 2911 | const bits = try bitSizeAdvanced(ty.elemType(), target, sema_kit); |
| 2912 | const bytes = (bits + 7) / 8; | ||
| 2913 | const alignment = std.math.ceilPowerOfTwoAssert(u64, bytes * len); | ||
| 2914 | return AbiAlignmentAdvanced{ .scalar = @intCast(u32, alignment) }; | ||
| 2915 | }, | ||
| 2912 | 2916 | ||
| 2913 | .i16, .u16 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(16, target) }, | 2917 | .i16, .u16 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(16, target) }, |
| 2914 | .u29 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(29, target) }, | 2918 | .u29 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(29, target) }, |
test/behavior/vector.zig+24| ... | @@ -1048,3 +1048,27 @@ test "@shlWithOverflow" { | ... | @@ -1048,3 +1048,27 @@ test "@shlWithOverflow" { |
| 1048 | try S.doTheTest(); | 1048 | try S.doTheTest(); |
| 1049 | comptime try S.doTheTest(); | 1049 | comptime try S.doTheTest(); |
| 1050 | } | 1050 | } |
| 1051 | |||
| 1052 | test "alignment of vectors" { | ||
| 1053 | try expect(@alignOf(@Vector(2, u8)) == 2); | ||
| 1054 | try expect(@alignOf(@Vector(2, u1)) == 2); | ||
| 1055 | try expect(@alignOf(@Vector(1, u1)) == 1); | ||
| 1056 | try expect(@alignOf(@Vector(2, u16)) == 4); | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | test "loading the second vector from a slice of vectors" { | ||
| 1060 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 1061 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1062 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1063 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1064 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1065 | |||
| 1066 | @setRuntimeSafety(false); | ||
| 1067 | var small_bases = [2]@Vector(2, u8){ | ||
| 1068 | @Vector(2, u8){ 0, 1 }, | ||
| 1069 | @Vector(2, u8){ 2, 3 }, | ||
| 1070 | }; | ||
| 1071 | var a: []const @Vector(2, u8) = &small_bases; | ||
| 1072 | var a4 = a[1][1]; | ||
| 1073 | try expect(a4 == 3); | ||
| 1074 | } |
test/cases/plan9/exit.zig deleted-5| ... | @@ -1,5 +0,0 @@ | ||
| 1 | pub fn main() void {} | ||
| 2 | |||
| 3 | // run | ||
| 4 | // target=x86_64-plan9,aarch64-plan9 | ||
| 5 | // | ||
test/cases/plan9/hello_world_with_updates.0.zig deleted-28| ... | @@ -1,28 +0,0 @@ | ||
| 1 | pub fn main() void { | ||
| 2 | const str = "Hello World!\n"; | ||
| 3 | asm volatile ( | ||
| 4 | \\push $0 | ||
| 5 | \\push %%r10 | ||
| 6 | \\push %%r11 | ||
| 7 | \\push $1 | ||
| 8 | \\push $0 | ||
| 9 | \\syscall | ||
| 10 | \\pop %%r11 | ||
| 11 | \\pop %%r11 | ||
| 12 | \\pop %%r11 | ||
| 13 | \\pop %%r11 | ||
| 14 | \\pop %%r11 | ||
| 15 | : | ||
| 16 | // pwrite | ||
| 17 | : [syscall_number] "{rbp}" (51), | ||
| 18 | [hey] "{r11}" (@ptrToInt(str)), | ||
| 19 | [strlen] "{r10}" (str.len), | ||
| 20 | : "rcx", "rbp", "r11", "memory" | ||
| 21 | ); | ||
| 22 | } | ||
| 23 | |||
| 24 | // run | ||
| 25 | // target=x86_64-plan9 | ||
| 26 | // | ||
| 27 | // Hello World | ||
| 28 | // | ||
test/cases/plan9/hello_world_with_updates.1.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | pub fn main() void { | ||
| 3 | const str = "Hello World!\n"; | ||
| 4 | _ = std.os.plan9.pwrite(1, str, str.len, 0); | ||
| 5 | } | ||
| 6 | |||
| 7 | // run | ||
| 8 | // | ||
| 9 | // Hello World | ||
| 10 | // | ||