| 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 | 160 | } |
| 161 | 161 | |
| 162 | 162 | test "vector patterns" { |
| 163 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; | |
| 164 | 163 | const base = @Vector(4, u32){ 10, 20, 30, 40 }; |
| 165 | 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 | 1024 | if (options.use_llvm) |explicit| |
| 1025 | 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 | 1027 | // If emitting to LLVM bitcode object format, must use LLVM backend. |
| 1032 | 1028 | if (options.emit_llvm_ir != null or options.emit_llvm_bc != null) |
| 1033 | 1029 | break :blk true; |
| ... | ... | @@ -1042,7 +1038,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1042 | 1038 | break :blk true; |
| 1043 | 1039 | |
| 1044 | 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 | 1042 | break :blk false; |
| 1047 | 1043 | |
| 1048 | 1044 | // Prefer LLVM for release builds. |
src/codegen/llvm.zig+15-8| ... | ... | @@ -768,7 +768,11 @@ pub const Object = struct { |
| 768 | 768 | if (ptr_info.@"align" != 0) { |
| 769 | 769 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align"); |
| 770 | 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 | 844 | if (ptr_info.@"align" != 0) { |
| 841 | 845 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align"); |
| 842 | 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 | 850 | const ptr_param = llvm_func.getParam(llvm_arg_i); |
| 846 | 851 | llvm_arg_i += 1; |
| ... | ... | @@ -3401,6 +3406,13 @@ pub const DeclGen = struct { |
| 3401 | 3406 | const union_obj = tv.ty.cast(Type.Payload.Union).?.data; |
| 3402 | 3407 | const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, dg.module).?; |
| 3403 | 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 | 3416 | const field_ty = union_obj.fields.values()[field_index].ty; |
| 3405 | 3417 | const payload = p: { |
| 3406 | 3418 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) { |
| ... | ... | @@ -3408,6 +3420,7 @@ pub const DeclGen = struct { |
| 3408 | 3420 | break :p dg.context.intType(8).arrayType(padding_len).getUndef(); |
| 3409 | 3421 | } |
| 3410 | 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 | 3424 | const field_size = field_ty.abiSize(target); |
| 3412 | 3425 | if (field_size == layout.payload_size) { |
| 3413 | 3426 | break :p field; |
| ... | ... | @@ -3419,12 +3432,6 @@ pub const DeclGen = struct { |
| 3419 | 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 | 3435 | if (layout.tag_size == 0) { |
| 3429 | 3436 | const fields: [1]*const llvm.Value = .{payload}; |
| 3430 | 3437 | if (need_unnamed) { |
src/target.zig+18-1| ... | ... | @@ -204,7 +204,24 @@ pub fn hasValgrindSupport(target: std.Target) bool { |
| 204 | 204 | /// The set of targets that LLVM has non-experimental support for. |
| 205 | 205 | /// Used to select between LLVM backend and self-hosted backend when compiling in |
| 206 | 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 | 225 | return switch (target.cpu.arch) { |
| 209 | 226 | .arm, |
| 210 | 227 | .armeb, |
src/type.zig+7-3| ... | ... | @@ -2906,9 +2906,13 @@ pub const Type = extern union { |
| 2906 | 2906 | |
| 2907 | 2907 | .array, .array_sentinel => return ty.elemType().abiAlignmentAdvanced(target, strat), |
| 2908 | 2908 | |
| 2909 | // TODO audit this - is there any more complicated logic to determine | |
| 2910 | // ABI alignment of vectors? | |
| 2911 | .vector => return AbiAlignmentAdvanced{ .scalar = 16 }, | |
| 2909 | .vector => { | |
| 2910 | const len = ty.arrayLen(); | |
| 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 | 2917 | .i16, .u16 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(16, target) }, |
| 2914 | 2918 | .u29 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(29, target) }, |
test/behavior/vector.zig+24| ... | ... | @@ -1048,3 +1048,27 @@ test "@shlWithOverflow" { |
| 1048 | 1048 | try S.doTheTest(); |
| 1049 | 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 | // |