authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-15 15:09:23-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-15 15:09:48-07:00
logd4a0d5f959b88ffc23edc4593bc75b6168acaea9
tree0353583e171a4c9ac92f50b4976595c51d58c32f
parentea4d2759a51f2805e8345fe85500feefef3f504c

Sema: implement `@truncate` for SIMD vectors


7 files changed, 196 insertions(+), 40 deletions(-)

src/Compilation.zig-5
...@@ -4513,8 +4513,6 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca...@@ -4513,8 +4513,6 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca
4513 const target = comp.getTarget();4513 const target = comp.getTarget();
4514 const generic_arch_name = target.cpu.arch.genericName();4514 const generic_arch_name = target.cpu.arch.genericName();
4515 const use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1;4515 const use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1;
4516 const stage2_x86_cx16 = target.cpu.arch == .x86_64 and
4517 std.Target.x86.featureSetHas(target.cpu.features, .cx16);
45184516
4519 const zig_backend: std.builtin.CompilerBackend = blk: {4517 const zig_backend: std.builtin.CompilerBackend = blk: {
4520 if (use_stage1) break :blk .stage1;4518 if (use_stage1) break :blk .stage1;
...@@ -4540,8 +4538,6 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca...@@ -4540,8 +4538,6 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca
4540 \\pub const zig_backend = std.builtin.CompilerBackend.{};4538 \\pub const zig_backend = std.builtin.CompilerBackend.{};
4541 \\/// Temporary until self-hosted supports the `cpu.arch` value.4539 \\/// Temporary until self-hosted supports the `cpu.arch` value.
4542 \\pub const stage2_arch: std.Target.Cpu.Arch = .{};4540 \\pub const stage2_arch: std.Target.Cpu.Arch = .{};
4543 \\/// Temporary until self-hosted can call `std.Target.x86.featureSetHas` at comptime.
4544 \\pub const stage2_x86_cx16 = {};
4545 \\4541 \\
4546 \\pub const output_mode = std.builtin.OutputMode.{};4542 \\pub const output_mode = std.builtin.OutputMode.{};
4547 \\pub const link_mode = std.builtin.LinkMode.{};4543 \\pub const link_mode = std.builtin.LinkMode.{};
...@@ -4557,7 +4553,6 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca...@@ -4557,7 +4553,6 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca
4557 build_options.version,4553 build_options.version,
4558 std.zig.fmtId(@tagName(zig_backend)),4554 std.zig.fmtId(@tagName(zig_backend)),
4559 std.zig.fmtId(@tagName(target.cpu.arch)),4555 std.zig.fmtId(@tagName(target.cpu.arch)),
4560 stage2_x86_cx16,
4561 std.zig.fmtId(@tagName(comp.bin_file.options.output_mode)),4556 std.zig.fmtId(@tagName(comp.bin_file.options.output_mode)),
4562 std.zig.fmtId(@tagName(comp.bin_file.options.link_mode)),4557 std.zig.fmtId(@tagName(comp.bin_file.options.link_mode)),
4563 comp.bin_file.options.is_test,4558 comp.bin_file.options.is_test,
src/Sema.zig+87-21
...@@ -13229,35 +13229,54 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13229,35 +13229,54 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13229 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };13229 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
13230 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };13230 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
13231 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;13231 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
13232 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);13232 const dest_scalar_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
13233 const operand = sema.resolveInst(extra.rhs);13233 const operand = sema.resolveInst(extra.rhs);
13234 const dest_is_comptime_int = try sema.checkIntType(block, dest_ty_src, dest_scalar_ty);
13235 const operand_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand, operand_src);
13234 const operand_ty = sema.typeOf(operand);13236 const operand_ty = sema.typeOf(operand);
13235 const dest_is_comptime_int = try sema.checkIntType(block, dest_ty_src, dest_ty);13237 const is_vector = operand_ty.zigTypeTag() == .Vector;
13236 const src_is_comptime_int = try sema.checkIntType(block, operand_src, operand_ty);13238 const dest_ty = if (is_vector)
13239 try Type.vector(sema.arena, operand_ty.vectorLen(), dest_scalar_ty)
13240 else
13241 dest_scalar_ty;
1323713242
13238 if (dest_is_comptime_int) {13243 if (dest_is_comptime_int) {
13239 return sema.coerce(block, dest_ty, operand, operand_src);13244 return sema.coerce(block, dest_ty, operand, operand_src);
13240 }13245 }
1324113246
13242 const target = sema.mod.getTarget();13247 const target = sema.mod.getTarget();
13243 const dest_info = dest_ty.intInfo(target);13248 const dest_info = dest_scalar_ty.intInfo(target);
1324413249
13245 if (dest_info.bits == 0) {13250 if (dest_info.bits == 0) {
13246 return sema.addConstant(dest_ty, Value.zero);13251 if (is_vector) {
13252 return sema.addConstant(
13253 dest_ty,
13254 try Value.Tag.repeated.create(sema.arena, Value.zero),
13255 );
13256 } else {
13257 return sema.addConstant(dest_ty, Value.zero);
13258 }
13247 }13259 }
1324813260
13249 if (!src_is_comptime_int) {13261 if (operand_scalar_ty.zigTypeTag() != .ComptimeInt) {
13250 const src_info = operand_ty.intInfo(target);13262 const operand_info = operand_ty.intInfo(target);
13251 if (src_info.bits == 0) {13263 if (operand_info.bits == 0) {
13252 return sema.addConstant(dest_ty, Value.zero);13264 if (is_vector) {
13265 return sema.addConstant(
13266 dest_ty,
13267 try Value.Tag.repeated.create(sema.arena, Value.zero),
13268 );
13269 } else {
13270 return sema.addConstant(dest_ty, Value.zero);
13271 }
13253 }13272 }
1325413273
13255 if (src_info.signedness != dest_info.signedness) {13274 if (operand_info.signedness != dest_info.signedness) {
13256 return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{13275 return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{
13257 @tagName(dest_info.signedness), operand_ty,13276 @tagName(dest_info.signedness), operand_ty,
13258 });13277 });
13259 }13278 }
13260 if (src_info.bits > 0 and src_info.bits < dest_info.bits) {13279 if (operand_info.bits < dest_info.bits) {
13261 const msg = msg: {13280 const msg = msg: {
13262 const msg = try sema.errMsg(13281 const msg = try sema.errMsg(
13263 block,13282 block,
...@@ -13269,8 +13288,8 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13269,8 +13288,8 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13269 try sema.errNote(block, dest_ty_src, msg, "destination type has {d} bits", .{13288 try sema.errNote(block, dest_ty_src, msg, "destination type has {d} bits", .{
13270 dest_info.bits,13289 dest_info.bits,
13271 });13290 });
13272 try sema.errNote(block, operand_src, msg, "source type has {d} bits", .{13291 try sema.errNote(block, operand_src, msg, "operand type has {d} bits", .{
13273 src_info.bits,13292 operand_info.bits,
13274 });13293 });
13275 break :msg msg;13294 break :msg msg;
13276 };13295 };
...@@ -13280,7 +13299,22 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13280,7 +13299,22 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1328013299
13281 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {13300 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {
13282 if (val.isUndef()) return sema.addConstUndef(dest_ty);13301 if (val.isUndef()) return sema.addConstUndef(dest_ty);
13283 return sema.addConstant(dest_ty, try val.intTrunc(sema.arena, dest_info.signedness, dest_info.bits));13302 if (!is_vector) {
13303 return sema.addConstant(
13304 dest_ty,
13305 try val.intTrunc(sema.arena, dest_info.signedness, dest_info.bits),
13306 );
13307 }
13308 var elem_buf: Value.ElemValueBuffer = undefined;
13309 const elems = try sema.arena.alloc(Value, operand_ty.vectorLen());
13310 for (elems) |*elem, i| {
13311 const elem_val = val.elemValueBuffer(i, &elem_buf);
13312 elem.* = try elem_val.intTrunc(sema.arena, dest_info.signedness, dest_info.bits);
13313 }
13314 return sema.addConstant(
13315 dest_ty,
13316 try Value.Tag.aggregate.create(sema.arena, elems),
13317 );
13284 }13318 }
1328513319
13286 try sema.requireRuntimeBlock(block, src);13320 try sema.requireRuntimeBlock(block, src);
...@@ -13330,13 +13364,13 @@ fn zirBitCount(...@@ -13330,13 +13364,13 @@ fn zirBitCount(
13330 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };13364 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
13331 const operand = sema.resolveInst(inst_data.operand);13365 const operand = sema.resolveInst(inst_data.operand);
13332 const operand_ty = sema.typeOf(operand);13366 const operand_ty = sema.typeOf(operand);
13333 try checkIntOrVector(sema, block, operand, operand_src);13367 _ = try checkIntOrVector(sema, block, operand, operand_src);
13334 const target = sema.mod.getTarget();13368 const target = sema.mod.getTarget();
13335 const bits = operand_ty.intInfo(target).bits;13369 const bits = operand_ty.intInfo(target).bits;
13336 if (bits == 0) {13370 if (bits == 0) {
13337 switch (operand_ty.zigTypeTag()) {13371 switch (operand_ty.zigTypeTag()) {
13338 .Vector => return sema.addConstant(13372 .Vector => return sema.addConstant(
13339 try Type.vector(sema.arena, operand_ty.arrayLen(), Type.comptime_int),13373 try Type.vector(sema.arena, operand_ty.vectorLen(), Type.comptime_int),
13340 try Value.Tag.repeated.create(sema.arena, Value.zero),13374 try Value.Tag.repeated.create(sema.arena, Value.zero),
13341 ),13375 ),
13342 .Int => return Air.Inst.Ref.zero,13376 .Int => return Air.Inst.Ref.zero,
...@@ -13512,7 +13546,7 @@ fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Com...@@ -13512,7 +13546,7 @@ fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Com
1351213546
13513/// Returns `true` if the type was a comptime_int.13547/// Returns `true` if the type was a comptime_int.
13514fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {13548fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {
13515 switch (ty.zigTypeTag()) {13549 switch (try ty.zigTypeTagOrPoison()) {
13516 .ComptimeInt => return true,13550 .ComptimeInt => return true,
13517 .Int => return false,13551 .Int => return false,
13518 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty}),13552 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty}),
...@@ -13714,11 +13748,43 @@ fn checkIntOrVector(...@@ -13714,11 +13748,43 @@ fn checkIntOrVector(
13714 block: *Block,13748 block: *Block,
13715 operand: Air.Inst.Ref,13749 operand: Air.Inst.Ref,
13716 operand_src: LazySrcLoc,13750 operand_src: LazySrcLoc,
13717) CompileError!void {13751) CompileError!Type {
13718 const operand_ty = sema.typeOf(operand);13752 const operand_ty = sema.typeOf(operand);
13719 const operand_zig_ty_tag = try operand_ty.zigTypeTagOrPoison();13753 switch (try operand_ty.zigTypeTagOrPoison()) {
13720 switch (operand_zig_ty_tag) {13754 .Int => return operand_ty,
13721 .Vector, .Int => return,13755 .Vector => {
13756 const elem_ty = operand_ty.childType();
13757 switch (try elem_ty.zigTypeTagOrPoison()) {
13758 .Int => return elem_ty,
13759 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
13760 elem_ty,
13761 }),
13762 }
13763 },
13764 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
13765 operand_ty,
13766 }),
13767 }
13768}
13769
13770fn checkIntOrVectorAllowComptime(
13771 sema: *Sema,
13772 block: *Block,
13773 operand: Air.Inst.Ref,
13774 operand_src: LazySrcLoc,
13775) CompileError!Type {
13776 const operand_ty = sema.typeOf(operand);
13777 switch (try operand_ty.zigTypeTagOrPoison()) {
13778 .Int, .ComptimeInt => return operand_ty,
13779 .Vector => {
13780 const elem_ty = operand_ty.childType();
13781 switch (try elem_ty.zigTypeTagOrPoison()) {
13782 .Int, .ComptimeInt => return elem_ty,
13783 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
13784 elem_ty,
13785 }),
13786 }
13787 },
13722 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{13788 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
13723 operand_ty,13789 operand_ty,
13724 }),13790 }),
test/behavior.zig+3-3
...@@ -4,6 +4,7 @@ test {...@@ -4,6 +4,7 @@ test {
4 _ = @import("behavior/align.zig");4 _ = @import("behavior/align.zig");
5 _ = @import("behavior/alignof.zig");5 _ = @import("behavior/alignof.zig");
6 _ = @import("behavior/array.zig");6 _ = @import("behavior/array.zig");
7 _ = @import("behavior/atomics.zig");
7 _ = @import("behavior/basic.zig");8 _ = @import("behavior/basic.zig");
8 _ = @import("behavior/bit_shifting.zig");9 _ = @import("behavior/bit_shifting.zig");
9 _ = @import("behavior/bitcast.zig");10 _ = @import("behavior/bitcast.zig");
...@@ -55,6 +56,7 @@ test {...@@ -55,6 +56,7 @@ test {
55 _ = @import("behavior/bugs/5413.zig");56 _ = @import("behavior/bugs/5413.zig");
56 _ = @import("behavior/bugs/5474.zig");57 _ = @import("behavior/bugs/5474.zig");
57 _ = @import("behavior/bugs/5487.zig");58 _ = @import("behavior/bugs/5487.zig");
59 _ = @import("behavior/bugs/6456.zig");
58 _ = @import("behavior/bugs/6850.zig");60 _ = @import("behavior/bugs/6850.zig");
59 _ = @import("behavior/bugs/7003.zig");61 _ = @import("behavior/bugs/7003.zig");
60 _ = @import("behavior/bugs/7047.zig");62 _ = @import("behavior/bugs/7047.zig");
...@@ -67,6 +69,7 @@ test {...@@ -67,6 +69,7 @@ test {
67 _ = @import("behavior/call.zig");69 _ = @import("behavior/call.zig");
68 _ = @import("behavior/cast.zig");70 _ = @import("behavior/cast.zig");
69 _ = @import("behavior/comptime_memory.zig");71 _ = @import("behavior/comptime_memory.zig");
72 _ = @import("behavior/const_slice_child.zig");
70 _ = @import("behavior/defer.zig");73 _ = @import("behavior/defer.zig");
71 _ = @import("behavior/enum.zig");74 _ = @import("behavior/enum.zig");
72 _ = @import("behavior/error.zig");75 _ = @import("behavior/error.zig");
...@@ -147,7 +150,6 @@ test {...@@ -147,7 +150,6 @@ test {
147150
148 if (builtin.zig_backend != .stage2_c) {151 if (builtin.zig_backend != .stage2_c) {
149 // Tests that pass for stage1 and the llvm backend.152 // Tests that pass for stage1 and the llvm backend.
150 _ = @import("behavior/atomics.zig");
151 _ = @import("behavior/export.zig");153 _ = @import("behavior/export.zig");
152 _ = @import("behavior/maximum_minimum.zig");154 _ = @import("behavior/maximum_minimum.zig");
153 _ = @import("behavior/saturating_arithmetic.zig");155 _ = @import("behavior/saturating_arithmetic.zig");
...@@ -168,10 +170,8 @@ test {...@@ -168,10 +170,8 @@ test {
168 _ = @import("behavior/bugs/920.zig");170 _ = @import("behavior/bugs/920.zig");
169 _ = @import("behavior/bugs/1120.zig");171 _ = @import("behavior/bugs/1120.zig");
170 _ = @import("behavior/bugs/1851.zig");172 _ = @import("behavior/bugs/1851.zig");
171 _ = @import("behavior/bugs/6456.zig");
172 _ = @import("behavior/bugs/6781.zig");173 _ = @import("behavior/bugs/6781.zig");
173 _ = @import("behavior/bugs/7027.zig");174 _ = @import("behavior/bugs/7027.zig");
174 _ = @import("behavior/const_slice_child.zig");
175 _ = @import("behavior/select.zig");175 _ = @import("behavior/select.zig");
176 _ = @import("behavior/struct_contains_slice_of_itself.zig");176 _ = @import("behavior/struct_contains_slice_of_itself.zig");
177 _ = @import("behavior/typename.zig");177 _ = @import("behavior/typename.zig");
test/behavior/atomics.zig+81-8
...@@ -4,6 +4,12 @@ const expect = std.testing.expect;...@@ -4,6 +4,12 @@ const expect = std.testing.expect;
4const expectEqual = std.testing.expectEqual;4const expectEqual = std.testing.expectEqual;
55
6test "cmpxchg" {6test "cmpxchg" {
7 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12
7 try testCmpxchg();13 try testCmpxchg();
8 comptime try testCmpxchg();14 comptime try testCmpxchg();
9}15}
...@@ -26,12 +32,24 @@ fn testCmpxchg() !void {...@@ -26,12 +32,24 @@ fn testCmpxchg() !void {
26}32}
2733
28test "fence" {34test "fence" {
35 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
36 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
37 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
38 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
39 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
40
29 var x: i32 = 1234;41 var x: i32 = 1234;
30 @fence(.SeqCst);42 @fence(.SeqCst);
31 x = 5678;43 x = 5678;
32}44}
3345
34test "atomicrmw and atomicload" {46test "atomicrmw and atomicload" {
47 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
48 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
49 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
50 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
51 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
52
35 var data: u8 = 200;53 var data: u8 = 200;
36 try testAtomicRmw(&data);54 try testAtomicRmw(&data);
37 try expect(data == 42);55 try expect(data == 42);
...@@ -55,6 +73,12 @@ fn testAtomicLoad(ptr: *u8) !void {...@@ -55,6 +73,12 @@ fn testAtomicLoad(ptr: *u8) !void {
55}73}
5674
57test "cmpxchg with ptr" {75test "cmpxchg with ptr" {
76 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
77 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
78 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
79 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
80 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
81
58 var data1: i32 = 1234;82 var data1: i32 = 1234;
59 var data2: i32 = 5678;83 var data2: i32 = 5678;
60 var data3: i32 = 9101;84 var data3: i32 = 9101;
...@@ -75,6 +99,12 @@ test "cmpxchg with ptr" {...@@ -75,6 +99,12 @@ test "cmpxchg with ptr" {
75}99}
76100
77test "cmpxchg with ignored result" {101test "cmpxchg with ignored result" {
102 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
103 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
104 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
105 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
106 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
107
78 var x: i32 = 1234;108 var x: i32 = 1234;
79109
80 _ = @cmpxchgStrong(i32, &x, 1234, 5678, .Monotonic, .Monotonic);110 _ = @cmpxchgStrong(i32, &x, 1234, 5678, .Monotonic, .Monotonic);
...@@ -83,19 +113,20 @@ test "cmpxchg with ignored result" {...@@ -83,19 +113,20 @@ test "cmpxchg with ignored result" {
83}113}
84114
85test "128-bit cmpxchg" {115test "128-bit cmpxchg" {
116 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
117 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
118 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
119 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
120 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
121
122 if (builtin.cpu.arch != .x86_64) return error.SkipZigTest;
123 if (comptime !std.Target.x86.featureSetHas(builtin.cpu.features, .cx16)) return error.SkipZigTest;
124
86 try test_u128_cmpxchg();125 try test_u128_cmpxchg();
87 comptime try test_u128_cmpxchg();126 comptime try test_u128_cmpxchg();
88}127}
89128
90fn test_u128_cmpxchg() !void {129fn test_u128_cmpxchg() !void {
91 if (builtin.zig_backend != .stage1) {
92 if (builtin.cpu.arch != .x86_64) return error.SkipZigTest;
93 if (!builtin.stage2_x86_cx16) return error.SkipZigTest;
94 } else {
95 if (builtin.cpu.arch != .x86_64) return error.SkipZigTest;
96 if (comptime !std.Target.x86.featureSetHas(builtin.cpu.features, .cx16)) return error.SkipZigTest;
97 }
98
99 var x: u128 = 1234;130 var x: u128 = 1234;
100 if (@cmpxchgWeak(u128, &x, 99, 5678, .SeqCst, .SeqCst)) |x1| {131 if (@cmpxchgWeak(u128, &x, 99, 5678, .SeqCst, .SeqCst)) |x1| {
101 try expect(x1 == 1234);132 try expect(x1 == 1234);
...@@ -115,6 +146,12 @@ fn test_u128_cmpxchg() !void {...@@ -115,6 +146,12 @@ fn test_u128_cmpxchg() !void {
115var a_global_variable = @as(u32, 1234);146var a_global_variable = @as(u32, 1234);
116147
117test "cmpxchg on a global variable" {148test "cmpxchg on a global variable" {
149 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
150 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
151 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
152 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
153 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
154
118 if ((builtin.zig_backend == .stage1 or builtin.zig_backend == .stage2_llvm) and155 if ((builtin.zig_backend == .stage1 or builtin.zig_backend == .stage2_llvm) and
119 builtin.cpu.arch == .aarch64)156 builtin.cpu.arch == .aarch64)
120 {157 {
...@@ -127,6 +164,12 @@ test "cmpxchg on a global variable" {...@@ -127,6 +164,12 @@ test "cmpxchg on a global variable" {
127}164}
128165
129test "atomic load and rmw with enum" {166test "atomic load and rmw with enum" {
167 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
168 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
169 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
170 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
171 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
172
130 const Value = enum(u8) { a, b, c };173 const Value = enum(u8) { a, b, c };
131 var x = Value.a;174 var x = Value.a;
132175
...@@ -139,6 +182,12 @@ test "atomic load and rmw with enum" {...@@ -139,6 +182,12 @@ test "atomic load and rmw with enum" {
139}182}
140183
141test "atomic store" {184test "atomic store" {
185 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
186 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
187 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
188 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
189 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
190
142 var x: u32 = 0;191 var x: u32 = 0;
143 @atomicStore(u32, &x, 1, .SeqCst);192 @atomicStore(u32, &x, 1, .SeqCst);
144 try expect(@atomicLoad(u32, &x, .SeqCst) == 1);193 try expect(@atomicLoad(u32, &x, .SeqCst) == 1);
...@@ -147,6 +196,12 @@ test "atomic store" {...@@ -147,6 +196,12 @@ test "atomic store" {
147}196}
148197
149test "atomic store comptime" {198test "atomic store comptime" {
199 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
200 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
201 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
202 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
203 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
204
150 comptime try testAtomicStore();205 comptime try testAtomicStore();
151 try testAtomicStore();206 try testAtomicStore();
152}207}
...@@ -160,6 +215,12 @@ fn testAtomicStore() !void {...@@ -160,6 +215,12 @@ fn testAtomicStore() !void {
160}215}
161216
162test "atomicrmw with floats" {217test "atomicrmw with floats" {
218 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
219 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
220 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
221 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
222 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
223
163 if ((builtin.zig_backend == .stage1 or builtin.zig_backend == .stage2_llvm) and224 if ((builtin.zig_backend == .stage1 or builtin.zig_backend == .stage2_llvm) and
164 builtin.cpu.arch == .aarch64)225 builtin.cpu.arch == .aarch64)
165 {226 {
...@@ -182,6 +243,12 @@ fn testAtomicRmwFloat() !void {...@@ -182,6 +243,12 @@ fn testAtomicRmwFloat() !void {
182}243}
183244
184test "atomicrmw with ints" {245test "atomicrmw with ints" {
246 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
247 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
248 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
249 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
250 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
251
185 try testAtomicRmwInt();252 try testAtomicRmwInt();
186 comptime try testAtomicRmwInt();253 comptime try testAtomicRmwInt();
187}254}
...@@ -210,6 +277,12 @@ fn testAtomicRmwInt() !void {...@@ -210,6 +277,12 @@ fn testAtomicRmwInt() !void {
210}277}
211278
212test "atomics with different types" {279test "atomics with different types" {
280 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
281 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
282 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
283 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
284 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
285
213 try testAtomicsWithType(bool, true, false);286 try testAtomicsWithType(bool, true, false);
214287
215 try testAtomicsWithType(u1, 0, 1);288 try testAtomicsWithType(u1, 0, 1);
test/behavior/bugs/6456.zig+7
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const testing = std.testing;3const testing = std.testing;
3const StructField = std.builtin.Type.StructField;4const StructField = std.builtin.Type.StructField;
...@@ -10,6 +11,12 @@ const text =...@@ -10,6 +11,12 @@ const text =
10;11;
1112
12test "issue 6456" {13test "issue 6456" {
14 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
15 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
18 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
19
13 comptime {20 comptime {
14 var fields: []const StructField = &[0]StructField{};21 var fields: []const StructField = &[0]StructField{};
1522
test/behavior/const_slice_child.zig+7-2
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const debug = std.debug;3const debug = std.debug;
3const testing = std.testing;4const testing = std.testing;
...@@ -6,6 +7,10 @@ const expect = testing.expect;...@@ -6,6 +7,10 @@ const expect = testing.expect;
6var argv: [*]const [*]const u8 = undefined;7var argv: [*]const [*]const u8 = undefined;
78
8test "const slice child" {9test "const slice child" {
10 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13
9 const strs = [_][*]const u8{ "one", "two", "three" };14 const strs = [_][*]const u8{ "one", "two", "three" };
10 argv = &strs;15 argv = &strs;
11 try bar(strs.len);16 try bar(strs.len);
...@@ -19,8 +24,8 @@ fn foo(args: [][]const u8) !void {...@@ -19,8 +24,8 @@ fn foo(args: [][]const u8) !void {
19}24}
2025
21fn bar(argc: usize) !void {26fn bar(argc: usize) !void {
22 const args = testing.allocator.alloc([]const u8, argc) catch unreachable;27 var args_buffer: [10][]const u8 = undefined;
23 defer testing.allocator.free(args);28 const args = args_buffer[0..argc];
24 for (args) |_, i| {29 for (args) |_, i| {
25 const ptr = argv[i];30 const ptr = argv[i];
26 args[i] = ptr[0..strlen(ptr)];31 args[i] = ptr[0..strlen(ptr)];
test/behavior/truncate.zig+11-1
...@@ -62,7 +62,16 @@ test "truncate on comptime integer" {...@@ -62,7 +62,16 @@ test "truncate on comptime integer" {
62}62}
6363
64test "truncate on vectors" {64test "truncate on vectors" {
65 if (builtin.zig_backend != .stage1) return error.SkipZigTest;65 if (builtin.zig_backend == .stage1) {
66 // stage1 fails the comptime test
67 return error.SkipZigTest;
68 }
69
70 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
71 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
72 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
73 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
74 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
6675
67 const S = struct {76 const S = struct {
68 fn doTheTest() !void {77 fn doTheTest() !void {
...@@ -71,5 +80,6 @@ test "truncate on vectors" {...@@ -71,5 +80,6 @@ test "truncate on vectors" {
71 try expect(std.mem.eql(u8, &@as([4]u8, v2), &[4]u8{ 0xbb, 0xdd, 0xff, 0x22 }));80 try expect(std.mem.eql(u8, &@as([4]u8, v2), &[4]u8{ 0xbb, 0xdd, 0xff, 0x22 }));
72 }81 }
73 };82 };
83 comptime try S.doTheTest();
74 try S.doTheTest();84 try S.doTheTest();
75}85}