From 9b715cb46250cbdd610f081b976b2e161df57218 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 17 Jan 2022 18:52:53 +0100 Subject: [PATCH 1/3] stage2: implement airArrayToSlice for x86_64 * implement `genSetStack` for `ptr_stack_offset` * handle `ptr_add` * implement storing from register into pointer in register * split alignment and array tests into those that pass on x86_64 and those that do not * pass more tests on x86_64 --- src/arch/x86_64/CodeGen.zig | 33 ++- test/behavior.zig | 376 +++++++++++++++++---------------- test/behavior/align.zig | 95 --------- test/behavior/align_simple.zig | 99 +++++++++ test/behavior/array_simple.zig | 15 ++ 5 files changed, 331 insertions(+), 287 deletions(-) create mode 100644 test/behavior/align_simple.zig create mode 100644 test/behavior/array_simple.zig diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 8f7f4746ec..961bf365d6 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1659,6 +1659,18 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type }, } }, + .register => |src_reg| { + const abi_size = value_ty.abiSize(self.target.*); + _ = try self.addInst(.{ + .tag = .mov, + .ops = (Mir.Ops{ + .reg1 = reg.to64(), + .reg2 = registerAlias(src_reg, @intCast(u32, abi_size)), + .flags = 0b10, + }).encode(), + .data = .{ .imm = 0 }, + }); + }, else => |other| { return self.fail("TODO implement set pointee with {}", .{other}); }, @@ -1822,7 +1834,7 @@ fn genBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: const dst_ty = self.air.typeOfIndex(inst); const air_tags = self.air.instructions.items(.tag); switch (air_tags[inst]) { - .add, .addwrap => try self.genBinMathOpMir(.add, dst_ty, .unsigned, dst_mcv, src_mcv), + .add, .addwrap, .ptr_add => try self.genBinMathOpMir(.add, dst_ty, .unsigned, dst_mcv, src_mcv), .bool_or, .bit_or => try self.genBinMathOpMir(.@"or", dst_ty, .unsigned, dst_mcv, src_mcv), .bool_and, .bit_and => try self.genBinMathOpMir(.@"and", dst_ty, .unsigned, dst_mcv, src_mcv), .sub, .subwrap => try self.genBinMathOpMir(.sub, dst_ty, .unsigned, dst_mcv, src_mcv), @@ -3125,7 +3137,6 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void { fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void { switch (mcv) { .dead => unreachable, - .ptr_stack_offset => unreachable, .ptr_embedded_in_code => unreachable, .unreach, .none => return, // Nothing to do. .undef => { @@ -3241,7 +3252,9 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro } return self.fail("TODO implement memcpy for setting stack from {}", .{mcv}); }, - .stack_offset => |off| { + .ptr_stack_offset, + .stack_offset, + => |off| { if (stack_offset == off) { // Copy stack variable to itself; nothing to do. return; @@ -3618,10 +3631,16 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement airArrayToSlice for {}", .{self.target.cpu.arch}); + const ptr_ty = self.air.typeOf(ty_op.operand); + const ptr = try self.resolveInst(ty_op.operand); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: { + const stack_offset = try self.allocMem(inst, 16, 16); + const array_ty = ptr_ty.childType(); + const array_len = array_ty.arrayLenIncludingSentinel(); + try self.genSetStack(Type.initTag(.usize), stack_offset + 8, ptr); + try self.genSetStack(Type.initTag(.u64), stack_offset + 16, .{ .immediate = array_len }); + break :blk .{ .stack_offset = stack_offset }; + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } diff --git a/test/behavior.zig b/test/behavior.zig index 59377a753a..61f1ea7bbb 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -17,195 +17,201 @@ test { _ = @import("behavior/bugs/655.zig"); _ = @import("behavior/bool.zig"); - if (builtin.zig_backend != .stage2_arm and builtin.zig_backend != .stage2_x86_64) { - // Tests that pass for stage1, llvm backend, C backend, wasm backend. - _ = @import("behavior/align.zig"); - _ = @import("behavior/array.zig"); - _ = @import("behavior/basic.zig"); - _ = @import("behavior/bitcast.zig"); - _ = @import("behavior/bugs/624.zig"); - _ = @import("behavior/bugs/704.zig"); - _ = @import("behavior/bugs/1486.zig"); - _ = @import("behavior/bugs/2692.zig"); - _ = @import("behavior/bugs/2889.zig"); - _ = @import("behavior/bugs/3046.zig"); - _ = @import("behavior/bugs/3586.zig"); - _ = @import("behavior/bugs/4560.zig"); - _ = @import("behavior/bugs/4769_a.zig"); - _ = @import("behavior/bugs/4769_b.zig"); - _ = @import("behavior/bugs/4954.zig"); - _ = @import("behavior/byval_arg_var.zig"); - _ = @import("behavior/call.zig"); - _ = @import("behavior/cast.zig"); - _ = @import("behavior/defer.zig"); - _ = @import("behavior/enum.zig"); - _ = @import("behavior/error.zig"); - _ = @import("behavior/for.zig"); - _ = @import("behavior/generics.zig"); - _ = @import("behavior/if.zig"); - _ = @import("behavior/import.zig"); - _ = @import("behavior/incomplete_struct_param_tld.zig"); - _ = @import("behavior/inttoptr.zig"); - _ = @import("behavior/member_func.zig"); - _ = @import("behavior/null.zig"); - _ = @import("behavior/optional.zig"); - _ = @import("behavior/pointers.zig"); - _ = @import("behavior/ptrcast.zig"); - _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); - _ = @import("behavior/src.zig"); - _ = @import("behavior/struct.zig"); - _ = @import("behavior/this.zig"); - _ = @import("behavior/truncate.zig"); - _ = @import("behavior/try.zig"); - _ = @import("behavior/undefined.zig"); - _ = @import("behavior/underscore.zig"); - _ = @import("behavior/usingnamespace.zig"); - _ = @import("behavior/void.zig"); - _ = @import("behavior/while.zig"); + if (builtin.zig_backend != .stage2_arm) { + // Tests that pass for stage1, llvm backend, C backend, wasm backend and x86_64 backend. + _ = @import("behavior/align_simple.zig"); + _ = @import("behavior/array_simple.zig"); - if (builtin.zig_backend != .stage2_wasm) { - // Tests that pass for stage1, llvm backend, C backend - _ = @import("behavior/cast_int.zig"); - _ = @import("behavior/int128.zig"); - _ = @import("behavior/translate_c_macros.zig"); + if (builtin.zig_backend != .stage2_arm and builtin.zig_backend != .stage2_x86_64) { + // Tests that pass for stage1, llvm backend, C backend, wasm backend. + _ = @import("behavior/align.zig"); + _ = @import("behavior/array.zig"); + _ = @import("behavior/basic.zig"); + _ = @import("behavior/bitcast.zig"); + _ = @import("behavior/bugs/624.zig"); + _ = @import("behavior/bugs/704.zig"); + _ = @import("behavior/bugs/1486.zig"); + _ = @import("behavior/bugs/2692.zig"); + _ = @import("behavior/bugs/2889.zig"); + _ = @import("behavior/bugs/3046.zig"); + _ = @import("behavior/bugs/3586.zig"); + _ = @import("behavior/bugs/4560.zig"); + _ = @import("behavior/bugs/4769_a.zig"); + _ = @import("behavior/bugs/4769_b.zig"); + _ = @import("behavior/bugs/4954.zig"); + _ = @import("behavior/byval_arg_var.zig"); + _ = @import("behavior/call.zig"); + _ = @import("behavior/cast.zig"); + _ = @import("behavior/defer.zig"); + _ = @import("behavior/enum.zig"); + _ = @import("behavior/error.zig"); + _ = @import("behavior/for.zig"); + _ = @import("behavior/generics.zig"); + _ = @import("behavior/if.zig"); + _ = @import("behavior/import.zig"); + _ = @import("behavior/incomplete_struct_param_tld.zig"); + _ = @import("behavior/inttoptr.zig"); + _ = @import("behavior/member_func.zig"); + _ = @import("behavior/null.zig"); + _ = @import("behavior/optional.zig"); + _ = @import("behavior/pointers.zig"); + _ = @import("behavior/ptrcast.zig"); + _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); + _ = @import("behavior/src.zig"); + _ = @import("behavior/struct.zig"); + _ = @import("behavior/this.zig"); + _ = @import("behavior/truncate.zig"); + _ = @import("behavior/try.zig"); + _ = @import("behavior/undefined.zig"); + _ = @import("behavior/underscore.zig"); + _ = @import("behavior/usingnamespace.zig"); + _ = @import("behavior/void.zig"); + _ = @import("behavior/while.zig"); - if (builtin.zig_backend != .stage2_c) { - // Tests that pass for stage1 and the llvm backend. - _ = @import("behavior/align_llvm.zig"); - _ = @import("behavior/alignof.zig"); - _ = @import("behavior/array_llvm.zig"); - _ = @import("behavior/atomics.zig"); - _ = @import("behavior/basic_llvm.zig"); - _ = @import("behavior/bit_shifting.zig"); - _ = @import("behavior/bugs/394.zig"); - _ = @import("behavior/bugs/656.zig"); - _ = @import("behavior/bugs/1277.zig"); - _ = @import("behavior/bugs/1310.zig"); - _ = @import("behavior/bugs/1381.zig"); - _ = @import("behavior/bugs/1500.zig"); - _ = @import("behavior/bugs/1735.zig"); - _ = @import("behavior/bugs/1741.zig"); - _ = @import("behavior/bugs/2006.zig"); - _ = @import("behavior/bugs/2578.zig"); - _ = @import("behavior/bugs/3007.zig"); - _ = @import("behavior/bugs/3112.zig"); - _ = @import("behavior/bugs/3367.zig"); - _ = @import("behavior/bugs/7250.zig"); - _ = @import("behavior/bugs/9584.zig"); - _ = @import("behavior/cast_llvm.zig"); - _ = @import("behavior/enum_llvm.zig"); - _ = @import("behavior/error_llvm.zig"); - _ = @import("behavior/eval.zig"); - _ = @import("behavior/floatop.zig"); - _ = @import("behavior/fn.zig"); - _ = @import("behavior/generics_llvm.zig"); - _ = @import("behavior/math.zig"); - _ = @import("behavior/maximum_minimum.zig"); - _ = @import("behavior/merge_error_sets.zig"); - _ = @import("behavior/namespace_depends_on_compile_var.zig"); - _ = @import("behavior/null_llvm.zig"); - _ = @import("behavior/optional_llvm.zig"); - _ = @import("behavior/popcount.zig"); - _ = @import("behavior/saturating_arithmetic.zig"); - _ = @import("behavior/sizeof_and_typeof.zig"); - _ = @import("behavior/slice.zig"); - _ = @import("behavior/struct_llvm.zig"); - _ = @import("behavior/switch.zig"); - _ = @import("behavior/union.zig"); - _ = @import("behavior/widening.zig"); + if (builtin.zig_backend != .stage2_wasm) { + // Tests that pass for stage1, llvm backend, C backend + _ = @import("behavior/cast_int.zig"); + _ = @import("behavior/int128.zig"); + _ = @import("behavior/translate_c_macros.zig"); - if (builtin.zig_backend != .stage1) { - // When all comptime_memory.zig tests pass, #9646 can be closed. - // _ = @import("behavior/comptime_memory.zig"); - _ = @import("behavior/slice_stage2.zig"); - } else { - // Tests that only pass for the stage1 backend. - _ = @import("behavior/align_stage1.zig"); - if (builtin.os.tag != .wasi) { - _ = @import("behavior/asm.zig"); - _ = @import("behavior/async_fn.zig"); + if (builtin.zig_backend != .stage2_c) { + // Tests that pass for stage1 and the llvm backend. + _ = @import("behavior/align_llvm.zig"); + _ = @import("behavior/alignof.zig"); + _ = @import("behavior/array_llvm.zig"); + _ = @import("behavior/atomics.zig"); + _ = @import("behavior/basic_llvm.zig"); + _ = @import("behavior/bit_shifting.zig"); + _ = @import("behavior/bugs/394.zig"); + _ = @import("behavior/bugs/656.zig"); + _ = @import("behavior/bugs/1277.zig"); + _ = @import("behavior/bugs/1310.zig"); + _ = @import("behavior/bugs/1381.zig"); + _ = @import("behavior/bugs/1500.zig"); + _ = @import("behavior/bugs/1735.zig"); + _ = @import("behavior/bugs/1741.zig"); + _ = @import("behavior/bugs/2006.zig"); + _ = @import("behavior/bugs/2578.zig"); + _ = @import("behavior/bugs/3007.zig"); + _ = @import("behavior/bugs/3112.zig"); + _ = @import("behavior/bugs/3367.zig"); + _ = @import("behavior/bugs/7250.zig"); + _ = @import("behavior/bugs/9584.zig"); + _ = @import("behavior/cast_llvm.zig"); + _ = @import("behavior/enum_llvm.zig"); + _ = @import("behavior/error_llvm.zig"); + _ = @import("behavior/eval.zig"); + _ = @import("behavior/floatop.zig"); + _ = @import("behavior/fn.zig"); + _ = @import("behavior/generics_llvm.zig"); + _ = @import("behavior/math.zig"); + _ = @import("behavior/maximum_minimum.zig"); + _ = @import("behavior/merge_error_sets.zig"); + _ = @import("behavior/namespace_depends_on_compile_var.zig"); + _ = @import("behavior/null_llvm.zig"); + _ = @import("behavior/optional_llvm.zig"); + _ = @import("behavior/popcount.zig"); + _ = @import("behavior/saturating_arithmetic.zig"); + _ = @import("behavior/sizeof_and_typeof.zig"); + _ = @import("behavior/slice.zig"); + _ = @import("behavior/struct_llvm.zig"); + _ = @import("behavior/switch.zig"); + _ = @import("behavior/union.zig"); + _ = @import("behavior/widening.zig"); + + if (builtin.zig_backend != .stage1) { + // When all comptime_memory.zig tests pass, #9646 can be closed. + // _ = @import("behavior/comptime_memory.zig"); + _ = @import("behavior/slice_stage2.zig"); + } else { + // Tests that only pass for the stage1 backend. + _ = @import("behavior/align_stage1.zig"); + if (builtin.os.tag != .wasi) { + _ = @import("behavior/asm.zig"); + _ = @import("behavior/async_fn.zig"); + } + _ = @import("behavior/await_struct.zig"); + _ = @import("behavior/bitcast_stage1.zig"); + _ = @import("behavior/bitreverse.zig"); + _ = @import("behavior/bugs/421.zig"); + _ = @import("behavior/bugs/529.zig"); + _ = @import("behavior/bugs/718.zig"); + _ = @import("behavior/bugs/726.zig"); + _ = @import("behavior/bugs/828.zig"); + _ = @import("behavior/bugs/920.zig"); + _ = @import("behavior/bugs/1025.zig"); + _ = @import("behavior/bugs/1076.zig"); + _ = @import("behavior/bugs/1120.zig"); + _ = @import("behavior/bugs/1421.zig"); + _ = @import("behavior/bugs/1442.zig"); + _ = @import("behavior/bugs/1607.zig"); + _ = @import("behavior/bugs/1851.zig"); + _ = @import("behavior/bugs/1914.zig"); + _ = @import("behavior/bugs/2114.zig"); + _ = @import("behavior/bugs/3384.zig"); + _ = @import("behavior/bugs/3742.zig"); + _ = @import("behavior/bugs/3779.zig"); + _ = @import("behavior/bugs/4328.zig"); + _ = @import("behavior/bugs/5398.zig"); + _ = @import("behavior/bugs/5413.zig"); + _ = @import("behavior/bugs/5474.zig"); + _ = @import("behavior/bugs/5487.zig"); + _ = @import("behavior/bugs/6456.zig"); + _ = @import("behavior/bugs/6781.zig"); + _ = @import("behavior/bugs/7003.zig"); + _ = @import("behavior/bugs/7027.zig"); + _ = @import("behavior/bugs/7047.zig"); + _ = @import("behavior/bugs/10147.zig"); + _ = @import("behavior/byteswap.zig"); + _ = @import("behavior/call_stage1.zig"); + _ = @import("behavior/cast_stage1.zig"); + _ = @import("behavior/const_slice_child.zig"); + _ = @import("behavior/defer_stage1.zig"); + _ = @import("behavior/enum_stage1.zig"); + _ = @import("behavior/error_stage1.zig"); + _ = @import("behavior/eval_stage1.zig"); + _ = @import("behavior/field_parent_ptr.zig"); + _ = @import("behavior/floatop_stage1.zig"); + _ = @import("behavior/fn_stage1.zig"); + _ = @import("behavior/fn_delegation.zig"); + _ = @import("behavior/for_stage1.zig"); + _ = @import("behavior/if_stage1.zig"); + _ = @import("behavior/ir_block_deps.zig"); + _ = @import("behavior/math_stage1.zig"); + _ = @import("behavior/misc.zig"); + _ = @import("behavior/muladd.zig"); + _ = @import("behavior/null_stage1.zig"); + _ = @import("behavior/optional_stage1.zig"); + _ = @import("behavior/pointers_stage1.zig"); + _ = @import("behavior/popcount_stage1.zig"); + _ = @import("behavior/ptrcast_stage1.zig"); + _ = @import("behavior/reflection.zig"); + _ = @import("behavior/saturating_arithmetic_stage1.zig"); + _ = @import("behavior/select.zig"); + _ = @import("behavior/shuffle.zig"); + _ = @import("behavior/sizeof_and_typeof_stage1.zig"); + _ = @import("behavior/slice_stage1.zig"); + _ = @import("behavior/struct_contains_null_ptr_itself.zig"); + _ = @import("behavior/struct_contains_slice_of_itself.zig"); + _ = @import("behavior/struct_stage1.zig"); + _ = @import("behavior/switch_prong_err_enum.zig"); + _ = @import("behavior/switch_prong_implicit_cast.zig"); + _ = @import("behavior/switch_stage1.zig"); + _ = @import("behavior/truncate_stage1.zig"); + _ = @import("behavior/tuple.zig"); + _ = @import("behavior/type_stage1.zig"); + _ = @import("behavior/type_info_stage1.zig"); + _ = @import("behavior/typename.zig"); + _ = @import("behavior/union_stage1.zig"); + _ = @import("behavior/union_with_members.zig"); + _ = @import("behavior/var_args.zig"); + _ = @import("behavior/vector.zig"); + if (builtin.target.cpu.arch == .wasm32) { + _ = @import("behavior/wasm.zig"); + } + _ = @import("behavior/while_stage1.zig"); + _ = @import("behavior/translate_c_macros_stage1.zig"); } - _ = @import("behavior/await_struct.zig"); - _ = @import("behavior/bitcast_stage1.zig"); - _ = @import("behavior/bitreverse.zig"); - _ = @import("behavior/bugs/421.zig"); - _ = @import("behavior/bugs/529.zig"); - _ = @import("behavior/bugs/718.zig"); - _ = @import("behavior/bugs/726.zig"); - _ = @import("behavior/bugs/828.zig"); - _ = @import("behavior/bugs/920.zig"); - _ = @import("behavior/bugs/1025.zig"); - _ = @import("behavior/bugs/1076.zig"); - _ = @import("behavior/bugs/1120.zig"); - _ = @import("behavior/bugs/1421.zig"); - _ = @import("behavior/bugs/1442.zig"); - _ = @import("behavior/bugs/1607.zig"); - _ = @import("behavior/bugs/1851.zig"); - _ = @import("behavior/bugs/1914.zig"); - _ = @import("behavior/bugs/2114.zig"); - _ = @import("behavior/bugs/3384.zig"); - _ = @import("behavior/bugs/3742.zig"); - _ = @import("behavior/bugs/3779.zig"); - _ = @import("behavior/bugs/4328.zig"); - _ = @import("behavior/bugs/5398.zig"); - _ = @import("behavior/bugs/5413.zig"); - _ = @import("behavior/bugs/5474.zig"); - _ = @import("behavior/bugs/5487.zig"); - _ = @import("behavior/bugs/6456.zig"); - _ = @import("behavior/bugs/6781.zig"); - _ = @import("behavior/bugs/7003.zig"); - _ = @import("behavior/bugs/7027.zig"); - _ = @import("behavior/bugs/7047.zig"); - _ = @import("behavior/bugs/10147.zig"); - _ = @import("behavior/byteswap.zig"); - _ = @import("behavior/call_stage1.zig"); - _ = @import("behavior/cast_stage1.zig"); - _ = @import("behavior/const_slice_child.zig"); - _ = @import("behavior/defer_stage1.zig"); - _ = @import("behavior/enum_stage1.zig"); - _ = @import("behavior/error_stage1.zig"); - _ = @import("behavior/eval_stage1.zig"); - _ = @import("behavior/field_parent_ptr.zig"); - _ = @import("behavior/floatop_stage1.zig"); - _ = @import("behavior/fn_stage1.zig"); - _ = @import("behavior/fn_delegation.zig"); - _ = @import("behavior/for_stage1.zig"); - _ = @import("behavior/if_stage1.zig"); - _ = @import("behavior/ir_block_deps.zig"); - _ = @import("behavior/math_stage1.zig"); - _ = @import("behavior/misc.zig"); - _ = @import("behavior/muladd.zig"); - _ = @import("behavior/null_stage1.zig"); - _ = @import("behavior/optional_stage1.zig"); - _ = @import("behavior/pointers_stage1.zig"); - _ = @import("behavior/popcount_stage1.zig"); - _ = @import("behavior/ptrcast_stage1.zig"); - _ = @import("behavior/reflection.zig"); - _ = @import("behavior/saturating_arithmetic_stage1.zig"); - _ = @import("behavior/select.zig"); - _ = @import("behavior/shuffle.zig"); - _ = @import("behavior/sizeof_and_typeof_stage1.zig"); - _ = @import("behavior/slice_stage1.zig"); - _ = @import("behavior/struct_contains_null_ptr_itself.zig"); - _ = @import("behavior/struct_contains_slice_of_itself.zig"); - _ = @import("behavior/struct_stage1.zig"); - _ = @import("behavior/switch_prong_err_enum.zig"); - _ = @import("behavior/switch_prong_implicit_cast.zig"); - _ = @import("behavior/switch_stage1.zig"); - _ = @import("behavior/truncate_stage1.zig"); - _ = @import("behavior/tuple.zig"); - _ = @import("behavior/type_stage1.zig"); - _ = @import("behavior/type_info_stage1.zig"); - _ = @import("behavior/typename.zig"); - _ = @import("behavior/union_stage1.zig"); - _ = @import("behavior/union_with_members.zig"); - _ = @import("behavior/var_args.zig"); - _ = @import("behavior/vector.zig"); - if (builtin.target.cpu.arch == .wasm32) { - _ = @import("behavior/wasm.zig"); - } - _ = @import("behavior/while_stage1.zig"); - _ = @import("behavior/translate_c_macros_stage1.zig"); } } } diff --git a/test/behavior/align.zig b/test/behavior/align.zig index 77d2eea6a8..0fa96acc6d 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -3,36 +3,6 @@ const expect = std.testing.expect; const builtin = @import("builtin"); const native_arch = builtin.target.cpu.arch; -var foo: u8 align(4) = 100; - -test "global variable alignment" { - comptime try expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4); - comptime try expect(@TypeOf(&foo) == *align(4) u8); - { - const slice = @as(*[1]u8, &foo)[0..]; - comptime try expect(@TypeOf(slice) == *align(4) [1]u8); - } - { - var runtime_zero: usize = 0; - const slice = @as(*[1]u8, &foo)[runtime_zero..]; - comptime try expect(@TypeOf(slice) == []align(4) u8); - } -} - -test "default alignment allows unspecified in type syntax" { - try expect(*u32 == *align(@alignOf(u32)) u32); -} - -test "implicitly decreasing pointer alignment" { - const a: u32 align(4) = 3; - const b: u32 align(8) = 4; - try expect(addUnaligned(&a, &b) == 7); -} - -fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 { - return a.* + b.*; -} - test "implicitly decreasing slice alignment" { const a: u32 align(4) = 3; const b: u32 align(8) = 4; @@ -42,18 +12,6 @@ fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 { return a[0] + b[0]; } -test "@alignCast pointers" { - var x: u32 align(4) = 1; - expectsOnly1(&x); - try expect(x == 2); -} -fn expectsOnly1(x: *align(1) u32) void { - expects4(@alignCast(4, x)); -} -fn expects4(x: *align(4) u32) void { - x.* += 1; -} - test "specifying alignment allows pointer cast" { try testBytesAlign(0x33); } @@ -76,62 +34,9 @@ fn sliceExpects4(slice: []align(4) u32) void { slice[0] += 1; } -test "alignment of structs" { - try expect(@alignOf(struct { - a: i32, - b: *i32, - }) == @alignOf(usize)); -} - test "return error union with 128-bit integer" { try expect(3 == try give()); } fn give() anyerror!u128 { return 3; } - -test "alignment of >= 128-bit integer type" { - try expect(@alignOf(u128) == 16); - try expect(@alignOf(u129) == 16); -} - -test "alignment of struct with 128-bit field" { - try expect(@alignOf(struct { - x: u128, - }) == 16); - - comptime { - try expect(@alignOf(struct { - x: u128, - }) == 16); - } -} - -test "size of extern struct with 128-bit field" { - try expect(@sizeOf(extern struct { - x: u128, - y: u8, - }) == 32); - - comptime { - try expect(@sizeOf(extern struct { - x: u128, - y: u8, - }) == 32); - } -} - -test "@ptrCast preserves alignment of bigger source" { - var x: u32 align(16) = 1234; - const ptr = @ptrCast(*u8, &x); - try expect(@TypeOf(ptr) == *align(16) u8); -} - -test "alignstack" { - try expect(fnWithAlignedStack() == 1234); -} - -fn fnWithAlignedStack() i32 { - @setAlignStack(256); - return 1234; -} diff --git a/test/behavior/align_simple.zig b/test/behavior/align_simple.zig new file mode 100644 index 0000000000..9afb224f71 --- /dev/null +++ b/test/behavior/align_simple.zig @@ -0,0 +1,99 @@ +const std = @import("std"); +const expect = std.testing.expect; +const builtin = @import("builtin"); +const native_arch = builtin.target.cpu.arch; + +var foo: u8 align(4) = 100; + +test "global variable alignment" { + comptime try expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4); + comptime try expect(@TypeOf(&foo) == *align(4) u8); + { + const slice = @as(*[1]u8, &foo)[0..]; + comptime try expect(@TypeOf(slice) == *align(4) [1]u8); + } + { + var runtime_zero: usize = 0; + const slice = @as(*[1]u8, &foo)[runtime_zero..]; + comptime try expect(@TypeOf(slice) == []align(4) u8); + } +} + +test "default alignment allows unspecified in type syntax" { + try expect(*u32 == *align(@alignOf(u32)) u32); +} + +test "implicitly decreasing pointer alignment" { + const a: u32 align(4) = 3; + const b: u32 align(8) = 4; + try expect(addUnaligned(&a, &b) == 7); +} + +fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 { + return a.* + b.*; +} + +test "@alignCast pointers" { + var x: u32 align(4) = 1; + expectsOnly1(&x); + try expect(x == 2); +} +fn expectsOnly1(x: *align(1) u32) void { + expects4(@alignCast(4, x)); +} +fn expects4(x: *align(4) u32) void { + x.* += 1; +} + +test "alignment of structs" { + try expect(@alignOf(struct { + a: i32, + b: *i32, + }) == @alignOf(usize)); +} + +test "alignment of >= 128-bit integer type" { + try expect(@alignOf(u128) == 16); + try expect(@alignOf(u129) == 16); +} + +test "alignment of struct with 128-bit field" { + try expect(@alignOf(struct { + x: u128, + }) == 16); + + comptime { + try expect(@alignOf(struct { + x: u128, + }) == 16); + } +} + +test "size of extern struct with 128-bit field" { + try expect(@sizeOf(extern struct { + x: u128, + y: u8, + }) == 32); + + comptime { + try expect(@sizeOf(extern struct { + x: u128, + y: u8, + }) == 32); + } +} + +test "@ptrCast preserves alignment of bigger source" { + var x: u32 align(16) = 1234; + const ptr = @ptrCast(*u8, &x); + try expect(@TypeOf(ptr) == *align(16) u8); +} + +test "alignstack" { + try expect(fnWithAlignedStack() == 1234); +} + +fn fnWithAlignedStack() i32 { + @setAlignStack(256); + return 1234; +} diff --git a/test/behavior/array_simple.zig b/test/behavior/array_simple.zig new file mode 100644 index 0000000000..0de92c9eb7 --- /dev/null +++ b/test/behavior/array_simple.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const testing = std.testing; +const expect = testing.expect; + +test "array to slice" { + const a: u32 align(4) = 3; + const b: u32 align(8) = 4; + const a_slice: []align(1) const u32 = @as(*const [1]u32, &a)[0..]; + const b_slice: []align(1) const u32 = @as(*const [1]u32, &b)[0..]; + try expect(a_slice[0] + b_slice[0] == 7); + + const d: []const u32 = &[2]u32{ 1, 2 }; + const e: []const u32 = &[3]u32{ 3, 4, 5 }; + try expect(d[0] + e[0] + d[1] + e[1] == 10); +} From ab204f81b0632661f9f839ba33df19dfa0b5a84a Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 17 Jan 2022 20:30:44 +0100 Subject: [PATCH 2/3] stage2: return error.SkipZigTest in unsupported behavior tests --- test/behavior.zig | 376 ++++++++++++++++----------------- test/behavior/align.zig | 123 +++++++++++ test/behavior/align_simple.zig | 99 --------- test/behavior/array.zig | 42 ++++ test/behavior/array_simple.zig | 15 -- 5 files changed, 350 insertions(+), 305 deletions(-) delete mode 100644 test/behavior/align_simple.zig delete mode 100644 test/behavior/array_simple.zig diff --git a/test/behavior.zig b/test/behavior.zig index 61f1ea7bbb..a89a36b879 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -16,202 +16,196 @@ test { _ = @import("behavior/type.zig"); _ = @import("behavior/bugs/655.zig"); _ = @import("behavior/bool.zig"); + _ = @import("behavior/align.zig"); + _ = @import("behavior/array.zig"); - if (builtin.zig_backend != .stage2_arm) { - // Tests that pass for stage1, llvm backend, C backend, wasm backend and x86_64 backend. - _ = @import("behavior/align_simple.zig"); - _ = @import("behavior/array_simple.zig"); + if (builtin.zig_backend != .stage2_arm and builtin.zig_backend != .stage2_x86_64) { + // Tests that pass for stage1, llvm backend, C backend, wasm backend. + _ = @import("behavior/basic.zig"); + _ = @import("behavior/bitcast.zig"); + _ = @import("behavior/bugs/624.zig"); + _ = @import("behavior/bugs/704.zig"); + _ = @import("behavior/bugs/1486.zig"); + _ = @import("behavior/bugs/2692.zig"); + _ = @import("behavior/bugs/2889.zig"); + _ = @import("behavior/bugs/3046.zig"); + _ = @import("behavior/bugs/3586.zig"); + _ = @import("behavior/bugs/4560.zig"); + _ = @import("behavior/bugs/4769_a.zig"); + _ = @import("behavior/bugs/4769_b.zig"); + _ = @import("behavior/bugs/4954.zig"); + _ = @import("behavior/byval_arg_var.zig"); + _ = @import("behavior/call.zig"); + _ = @import("behavior/cast.zig"); + _ = @import("behavior/defer.zig"); + _ = @import("behavior/enum.zig"); + _ = @import("behavior/error.zig"); + _ = @import("behavior/for.zig"); + _ = @import("behavior/generics.zig"); + _ = @import("behavior/if.zig"); + _ = @import("behavior/import.zig"); + _ = @import("behavior/incomplete_struct_param_tld.zig"); + _ = @import("behavior/inttoptr.zig"); + _ = @import("behavior/member_func.zig"); + _ = @import("behavior/null.zig"); + _ = @import("behavior/optional.zig"); + _ = @import("behavior/pointers.zig"); + _ = @import("behavior/ptrcast.zig"); + _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); + _ = @import("behavior/src.zig"); + _ = @import("behavior/struct.zig"); + _ = @import("behavior/this.zig"); + _ = @import("behavior/truncate.zig"); + _ = @import("behavior/try.zig"); + _ = @import("behavior/undefined.zig"); + _ = @import("behavior/underscore.zig"); + _ = @import("behavior/usingnamespace.zig"); + _ = @import("behavior/void.zig"); + _ = @import("behavior/while.zig"); - if (builtin.zig_backend != .stage2_arm and builtin.zig_backend != .stage2_x86_64) { - // Tests that pass for stage1, llvm backend, C backend, wasm backend. - _ = @import("behavior/align.zig"); - _ = @import("behavior/array.zig"); - _ = @import("behavior/basic.zig"); - _ = @import("behavior/bitcast.zig"); - _ = @import("behavior/bugs/624.zig"); - _ = @import("behavior/bugs/704.zig"); - _ = @import("behavior/bugs/1486.zig"); - _ = @import("behavior/bugs/2692.zig"); - _ = @import("behavior/bugs/2889.zig"); - _ = @import("behavior/bugs/3046.zig"); - _ = @import("behavior/bugs/3586.zig"); - _ = @import("behavior/bugs/4560.zig"); - _ = @import("behavior/bugs/4769_a.zig"); - _ = @import("behavior/bugs/4769_b.zig"); - _ = @import("behavior/bugs/4954.zig"); - _ = @import("behavior/byval_arg_var.zig"); - _ = @import("behavior/call.zig"); - _ = @import("behavior/cast.zig"); - _ = @import("behavior/defer.zig"); - _ = @import("behavior/enum.zig"); - _ = @import("behavior/error.zig"); - _ = @import("behavior/for.zig"); - _ = @import("behavior/generics.zig"); - _ = @import("behavior/if.zig"); - _ = @import("behavior/import.zig"); - _ = @import("behavior/incomplete_struct_param_tld.zig"); - _ = @import("behavior/inttoptr.zig"); - _ = @import("behavior/member_func.zig"); - _ = @import("behavior/null.zig"); - _ = @import("behavior/optional.zig"); - _ = @import("behavior/pointers.zig"); - _ = @import("behavior/ptrcast.zig"); - _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); - _ = @import("behavior/src.zig"); - _ = @import("behavior/struct.zig"); - _ = @import("behavior/this.zig"); - _ = @import("behavior/truncate.zig"); - _ = @import("behavior/try.zig"); - _ = @import("behavior/undefined.zig"); - _ = @import("behavior/underscore.zig"); - _ = @import("behavior/usingnamespace.zig"); - _ = @import("behavior/void.zig"); - _ = @import("behavior/while.zig"); + if (builtin.zig_backend != .stage2_wasm) { + // Tests that pass for stage1, llvm backend, C backend + _ = @import("behavior/cast_int.zig"); + _ = @import("behavior/int128.zig"); + _ = @import("behavior/translate_c_macros.zig"); - if (builtin.zig_backend != .stage2_wasm) { - // Tests that pass for stage1, llvm backend, C backend - _ = @import("behavior/cast_int.zig"); - _ = @import("behavior/int128.zig"); - _ = @import("behavior/translate_c_macros.zig"); + if (builtin.zig_backend != .stage2_c) { + // Tests that pass for stage1 and the llvm backend. + _ = @import("behavior/align_llvm.zig"); + _ = @import("behavior/alignof.zig"); + _ = @import("behavior/array_llvm.zig"); + _ = @import("behavior/atomics.zig"); + _ = @import("behavior/basic_llvm.zig"); + _ = @import("behavior/bit_shifting.zig"); + _ = @import("behavior/bugs/394.zig"); + _ = @import("behavior/bugs/656.zig"); + _ = @import("behavior/bugs/1277.zig"); + _ = @import("behavior/bugs/1310.zig"); + _ = @import("behavior/bugs/1381.zig"); + _ = @import("behavior/bugs/1500.zig"); + _ = @import("behavior/bugs/1735.zig"); + _ = @import("behavior/bugs/1741.zig"); + _ = @import("behavior/bugs/2006.zig"); + _ = @import("behavior/bugs/2578.zig"); + _ = @import("behavior/bugs/3007.zig"); + _ = @import("behavior/bugs/3112.zig"); + _ = @import("behavior/bugs/3367.zig"); + _ = @import("behavior/bugs/7250.zig"); + _ = @import("behavior/bugs/9584.zig"); + _ = @import("behavior/cast_llvm.zig"); + _ = @import("behavior/enum_llvm.zig"); + _ = @import("behavior/error_llvm.zig"); + _ = @import("behavior/eval.zig"); + _ = @import("behavior/floatop.zig"); + _ = @import("behavior/fn.zig"); + _ = @import("behavior/generics_llvm.zig"); + _ = @import("behavior/math.zig"); + _ = @import("behavior/maximum_minimum.zig"); + _ = @import("behavior/merge_error_sets.zig"); + _ = @import("behavior/namespace_depends_on_compile_var.zig"); + _ = @import("behavior/null_llvm.zig"); + _ = @import("behavior/optional_llvm.zig"); + _ = @import("behavior/popcount.zig"); + _ = @import("behavior/saturating_arithmetic.zig"); + _ = @import("behavior/sizeof_and_typeof.zig"); + _ = @import("behavior/slice.zig"); + _ = @import("behavior/struct_llvm.zig"); + _ = @import("behavior/switch.zig"); + _ = @import("behavior/union.zig"); + _ = @import("behavior/widening.zig"); - if (builtin.zig_backend != .stage2_c) { - // Tests that pass for stage1 and the llvm backend. - _ = @import("behavior/align_llvm.zig"); - _ = @import("behavior/alignof.zig"); - _ = @import("behavior/array_llvm.zig"); - _ = @import("behavior/atomics.zig"); - _ = @import("behavior/basic_llvm.zig"); - _ = @import("behavior/bit_shifting.zig"); - _ = @import("behavior/bugs/394.zig"); - _ = @import("behavior/bugs/656.zig"); - _ = @import("behavior/bugs/1277.zig"); - _ = @import("behavior/bugs/1310.zig"); - _ = @import("behavior/bugs/1381.zig"); - _ = @import("behavior/bugs/1500.zig"); - _ = @import("behavior/bugs/1735.zig"); - _ = @import("behavior/bugs/1741.zig"); - _ = @import("behavior/bugs/2006.zig"); - _ = @import("behavior/bugs/2578.zig"); - _ = @import("behavior/bugs/3007.zig"); - _ = @import("behavior/bugs/3112.zig"); - _ = @import("behavior/bugs/3367.zig"); - _ = @import("behavior/bugs/7250.zig"); - _ = @import("behavior/bugs/9584.zig"); - _ = @import("behavior/cast_llvm.zig"); - _ = @import("behavior/enum_llvm.zig"); - _ = @import("behavior/error_llvm.zig"); - _ = @import("behavior/eval.zig"); - _ = @import("behavior/floatop.zig"); - _ = @import("behavior/fn.zig"); - _ = @import("behavior/generics_llvm.zig"); - _ = @import("behavior/math.zig"); - _ = @import("behavior/maximum_minimum.zig"); - _ = @import("behavior/merge_error_sets.zig"); - _ = @import("behavior/namespace_depends_on_compile_var.zig"); - _ = @import("behavior/null_llvm.zig"); - _ = @import("behavior/optional_llvm.zig"); - _ = @import("behavior/popcount.zig"); - _ = @import("behavior/saturating_arithmetic.zig"); - _ = @import("behavior/sizeof_and_typeof.zig"); - _ = @import("behavior/slice.zig"); - _ = @import("behavior/struct_llvm.zig"); - _ = @import("behavior/switch.zig"); - _ = @import("behavior/union.zig"); - _ = @import("behavior/widening.zig"); - - if (builtin.zig_backend != .stage1) { - // When all comptime_memory.zig tests pass, #9646 can be closed. - // _ = @import("behavior/comptime_memory.zig"); - _ = @import("behavior/slice_stage2.zig"); - } else { - // Tests that only pass for the stage1 backend. - _ = @import("behavior/align_stage1.zig"); - if (builtin.os.tag != .wasi) { - _ = @import("behavior/asm.zig"); - _ = @import("behavior/async_fn.zig"); - } - _ = @import("behavior/await_struct.zig"); - _ = @import("behavior/bitcast_stage1.zig"); - _ = @import("behavior/bitreverse.zig"); - _ = @import("behavior/bugs/421.zig"); - _ = @import("behavior/bugs/529.zig"); - _ = @import("behavior/bugs/718.zig"); - _ = @import("behavior/bugs/726.zig"); - _ = @import("behavior/bugs/828.zig"); - _ = @import("behavior/bugs/920.zig"); - _ = @import("behavior/bugs/1025.zig"); - _ = @import("behavior/bugs/1076.zig"); - _ = @import("behavior/bugs/1120.zig"); - _ = @import("behavior/bugs/1421.zig"); - _ = @import("behavior/bugs/1442.zig"); - _ = @import("behavior/bugs/1607.zig"); - _ = @import("behavior/bugs/1851.zig"); - _ = @import("behavior/bugs/1914.zig"); - _ = @import("behavior/bugs/2114.zig"); - _ = @import("behavior/bugs/3384.zig"); - _ = @import("behavior/bugs/3742.zig"); - _ = @import("behavior/bugs/3779.zig"); - _ = @import("behavior/bugs/4328.zig"); - _ = @import("behavior/bugs/5398.zig"); - _ = @import("behavior/bugs/5413.zig"); - _ = @import("behavior/bugs/5474.zig"); - _ = @import("behavior/bugs/5487.zig"); - _ = @import("behavior/bugs/6456.zig"); - _ = @import("behavior/bugs/6781.zig"); - _ = @import("behavior/bugs/7003.zig"); - _ = @import("behavior/bugs/7027.zig"); - _ = @import("behavior/bugs/7047.zig"); - _ = @import("behavior/bugs/10147.zig"); - _ = @import("behavior/byteswap.zig"); - _ = @import("behavior/call_stage1.zig"); - _ = @import("behavior/cast_stage1.zig"); - _ = @import("behavior/const_slice_child.zig"); - _ = @import("behavior/defer_stage1.zig"); - _ = @import("behavior/enum_stage1.zig"); - _ = @import("behavior/error_stage1.zig"); - _ = @import("behavior/eval_stage1.zig"); - _ = @import("behavior/field_parent_ptr.zig"); - _ = @import("behavior/floatop_stage1.zig"); - _ = @import("behavior/fn_stage1.zig"); - _ = @import("behavior/fn_delegation.zig"); - _ = @import("behavior/for_stage1.zig"); - _ = @import("behavior/if_stage1.zig"); - _ = @import("behavior/ir_block_deps.zig"); - _ = @import("behavior/math_stage1.zig"); - _ = @import("behavior/misc.zig"); - _ = @import("behavior/muladd.zig"); - _ = @import("behavior/null_stage1.zig"); - _ = @import("behavior/optional_stage1.zig"); - _ = @import("behavior/pointers_stage1.zig"); - _ = @import("behavior/popcount_stage1.zig"); - _ = @import("behavior/ptrcast_stage1.zig"); - _ = @import("behavior/reflection.zig"); - _ = @import("behavior/saturating_arithmetic_stage1.zig"); - _ = @import("behavior/select.zig"); - _ = @import("behavior/shuffle.zig"); - _ = @import("behavior/sizeof_and_typeof_stage1.zig"); - _ = @import("behavior/slice_stage1.zig"); - _ = @import("behavior/struct_contains_null_ptr_itself.zig"); - _ = @import("behavior/struct_contains_slice_of_itself.zig"); - _ = @import("behavior/struct_stage1.zig"); - _ = @import("behavior/switch_prong_err_enum.zig"); - _ = @import("behavior/switch_prong_implicit_cast.zig"); - _ = @import("behavior/switch_stage1.zig"); - _ = @import("behavior/truncate_stage1.zig"); - _ = @import("behavior/tuple.zig"); - _ = @import("behavior/type_stage1.zig"); - _ = @import("behavior/type_info_stage1.zig"); - _ = @import("behavior/typename.zig"); - _ = @import("behavior/union_stage1.zig"); - _ = @import("behavior/union_with_members.zig"); - _ = @import("behavior/var_args.zig"); - _ = @import("behavior/vector.zig"); - if (builtin.target.cpu.arch == .wasm32) { - _ = @import("behavior/wasm.zig"); - } - _ = @import("behavior/while_stage1.zig"); - _ = @import("behavior/translate_c_macros_stage1.zig"); + if (builtin.zig_backend != .stage1) { + // When all comptime_memory.zig tests pass, #9646 can be closed. + // _ = @import("behavior/comptime_memory.zig"); + _ = @import("behavior/slice_stage2.zig"); + } else { + // Tests that only pass for the stage1 backend. + _ = @import("behavior/align_stage1.zig"); + if (builtin.os.tag != .wasi) { + _ = @import("behavior/asm.zig"); + _ = @import("behavior/async_fn.zig"); } + _ = @import("behavior/await_struct.zig"); + _ = @import("behavior/bitcast_stage1.zig"); + _ = @import("behavior/bitreverse.zig"); + _ = @import("behavior/bugs/421.zig"); + _ = @import("behavior/bugs/529.zig"); + _ = @import("behavior/bugs/718.zig"); + _ = @import("behavior/bugs/726.zig"); + _ = @import("behavior/bugs/828.zig"); + _ = @import("behavior/bugs/920.zig"); + _ = @import("behavior/bugs/1025.zig"); + _ = @import("behavior/bugs/1076.zig"); + _ = @import("behavior/bugs/1120.zig"); + _ = @import("behavior/bugs/1421.zig"); + _ = @import("behavior/bugs/1442.zig"); + _ = @import("behavior/bugs/1607.zig"); + _ = @import("behavior/bugs/1851.zig"); + _ = @import("behavior/bugs/1914.zig"); + _ = @import("behavior/bugs/2114.zig"); + _ = @import("behavior/bugs/3384.zig"); + _ = @import("behavior/bugs/3742.zig"); + _ = @import("behavior/bugs/3779.zig"); + _ = @import("behavior/bugs/4328.zig"); + _ = @import("behavior/bugs/5398.zig"); + _ = @import("behavior/bugs/5413.zig"); + _ = @import("behavior/bugs/5474.zig"); + _ = @import("behavior/bugs/5487.zig"); + _ = @import("behavior/bugs/6456.zig"); + _ = @import("behavior/bugs/6781.zig"); + _ = @import("behavior/bugs/7003.zig"); + _ = @import("behavior/bugs/7027.zig"); + _ = @import("behavior/bugs/7047.zig"); + _ = @import("behavior/bugs/10147.zig"); + _ = @import("behavior/byteswap.zig"); + _ = @import("behavior/call_stage1.zig"); + _ = @import("behavior/cast_stage1.zig"); + _ = @import("behavior/const_slice_child.zig"); + _ = @import("behavior/defer_stage1.zig"); + _ = @import("behavior/enum_stage1.zig"); + _ = @import("behavior/error_stage1.zig"); + _ = @import("behavior/eval_stage1.zig"); + _ = @import("behavior/field_parent_ptr.zig"); + _ = @import("behavior/floatop_stage1.zig"); + _ = @import("behavior/fn_stage1.zig"); + _ = @import("behavior/fn_delegation.zig"); + _ = @import("behavior/for_stage1.zig"); + _ = @import("behavior/if_stage1.zig"); + _ = @import("behavior/ir_block_deps.zig"); + _ = @import("behavior/math_stage1.zig"); + _ = @import("behavior/misc.zig"); + _ = @import("behavior/muladd.zig"); + _ = @import("behavior/null_stage1.zig"); + _ = @import("behavior/optional_stage1.zig"); + _ = @import("behavior/pointers_stage1.zig"); + _ = @import("behavior/popcount_stage1.zig"); + _ = @import("behavior/ptrcast_stage1.zig"); + _ = @import("behavior/reflection.zig"); + _ = @import("behavior/saturating_arithmetic_stage1.zig"); + _ = @import("behavior/select.zig"); + _ = @import("behavior/shuffle.zig"); + _ = @import("behavior/sizeof_and_typeof_stage1.zig"); + _ = @import("behavior/slice_stage1.zig"); + _ = @import("behavior/struct_contains_null_ptr_itself.zig"); + _ = @import("behavior/struct_contains_slice_of_itself.zig"); + _ = @import("behavior/struct_stage1.zig"); + _ = @import("behavior/switch_prong_err_enum.zig"); + _ = @import("behavior/switch_prong_implicit_cast.zig"); + _ = @import("behavior/switch_stage1.zig"); + _ = @import("behavior/truncate_stage1.zig"); + _ = @import("behavior/tuple.zig"); + _ = @import("behavior/type_stage1.zig"); + _ = @import("behavior/type_info_stage1.zig"); + _ = @import("behavior/typename.zig"); + _ = @import("behavior/union_stage1.zig"); + _ = @import("behavior/union_with_members.zig"); + _ = @import("behavior/var_args.zig"); + _ = @import("behavior/vector.zig"); + if (builtin.target.cpu.arch == .wasm32) { + _ = @import("behavior/wasm.zig"); + } + _ = @import("behavior/while_stage1.zig"); + _ = @import("behavior/translate_c_macros_stage1.zig"); } } } diff --git a/test/behavior/align.zig b/test/behavior/align.zig index 0fa96acc6d..fe57c79353 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -3,7 +3,124 @@ const expect = std.testing.expect; const builtin = @import("builtin"); const native_arch = builtin.target.cpu.arch; +var foo: u8 align(4) = 100; + +test "global variable alignment" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + + comptime try expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4); + comptime try expect(@TypeOf(&foo) == *align(4) u8); + { + const slice = @as(*[1]u8, &foo)[0..]; + comptime try expect(@TypeOf(slice) == *align(4) [1]u8); + } + { + var runtime_zero: usize = 0; + const slice = @as(*[1]u8, &foo)[runtime_zero..]; + comptime try expect(@TypeOf(slice) == []align(4) u8); + } +} + +test "default alignment allows unspecified in type syntax" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + + try expect(*u32 == *align(@alignOf(u32)) u32); +} + +test "implicitly decreasing pointer alignment" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + + const a: u32 align(4) = 3; + const b: u32 align(8) = 4; + try expect(addUnaligned(&a, &b) == 7); +} + +fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 { + return a.* + b.*; +} + +test "@alignCast pointers" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + + var x: u32 align(4) = 1; + expectsOnly1(&x); + try expect(x == 2); +} +fn expectsOnly1(x: *align(1) u32) void { + expects4(@alignCast(4, x)); +} +fn expects4(x: *align(4) u32) void { + x.* += 1; +} + +test "alignment of structs" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + + try expect(@alignOf(struct { + a: i32, + b: *i32, + }) == @alignOf(usize)); +} + +test "alignment of >= 128-bit integer type" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + + try expect(@alignOf(u128) == 16); + try expect(@alignOf(u129) == 16); +} + +test "alignment of struct with 128-bit field" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + + try expect(@alignOf(struct { + x: u128, + }) == 16); + + comptime { + try expect(@alignOf(struct { + x: u128, + }) == 16); + } +} + +test "size of extern struct with 128-bit field" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + + try expect(@sizeOf(extern struct { + x: u128, + y: u8, + }) == 32); + + comptime { + try expect(@sizeOf(extern struct { + x: u128, + y: u8, + }) == 32); + } +} + +test "@ptrCast preserves alignment of bigger source" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + + var x: u32 align(16) = 1234; + const ptr = @ptrCast(*u8, &x); + try expect(@TypeOf(ptr) == *align(16) u8); +} + +test "alignstack" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + + try expect(fnWithAlignedStack() == 1234); +} + +fn fnWithAlignedStack() i32 { + @setAlignStack(256); + return 1234; +} + test "implicitly decreasing slice alignment" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + const a: u32 align(4) = 3; const b: u32 align(8) = 4; try expect(addUnalignedSlice(@as(*const [1]u32, &a)[0..], @as(*const [1]u32, &b)[0..]) == 7); @@ -13,6 +130,8 @@ fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 { } test "specifying alignment allows pointer cast" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + try testBytesAlign(0x33); } fn testBytesAlign(b: u8) !void { @@ -22,6 +141,8 @@ fn testBytesAlign(b: u8) !void { } test "@alignCast slices" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + var array align(4) = [_]u32{ 1, 1 }; const slice = array[0..]; sliceExpectsOnly1(slice); @@ -35,6 +156,8 @@ fn sliceExpects4(slice: []align(4) u32) void { } test "return error union with 128-bit integer" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + try expect(3 == try give()); } fn give() anyerror!u128 { diff --git a/test/behavior/align_simple.zig b/test/behavior/align_simple.zig deleted file mode 100644 index 9afb224f71..0000000000 --- a/test/behavior/align_simple.zig +++ /dev/null @@ -1,99 +0,0 @@ -const std = @import("std"); -const expect = std.testing.expect; -const builtin = @import("builtin"); -const native_arch = builtin.target.cpu.arch; - -var foo: u8 align(4) = 100; - -test "global variable alignment" { - comptime try expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4); - comptime try expect(@TypeOf(&foo) == *align(4) u8); - { - const slice = @as(*[1]u8, &foo)[0..]; - comptime try expect(@TypeOf(slice) == *align(4) [1]u8); - } - { - var runtime_zero: usize = 0; - const slice = @as(*[1]u8, &foo)[runtime_zero..]; - comptime try expect(@TypeOf(slice) == []align(4) u8); - } -} - -test "default alignment allows unspecified in type syntax" { - try expect(*u32 == *align(@alignOf(u32)) u32); -} - -test "implicitly decreasing pointer alignment" { - const a: u32 align(4) = 3; - const b: u32 align(8) = 4; - try expect(addUnaligned(&a, &b) == 7); -} - -fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 { - return a.* + b.*; -} - -test "@alignCast pointers" { - var x: u32 align(4) = 1; - expectsOnly1(&x); - try expect(x == 2); -} -fn expectsOnly1(x: *align(1) u32) void { - expects4(@alignCast(4, x)); -} -fn expects4(x: *align(4) u32) void { - x.* += 1; -} - -test "alignment of structs" { - try expect(@alignOf(struct { - a: i32, - b: *i32, - }) == @alignOf(usize)); -} - -test "alignment of >= 128-bit integer type" { - try expect(@alignOf(u128) == 16); - try expect(@alignOf(u129) == 16); -} - -test "alignment of struct with 128-bit field" { - try expect(@alignOf(struct { - x: u128, - }) == 16); - - comptime { - try expect(@alignOf(struct { - x: u128, - }) == 16); - } -} - -test "size of extern struct with 128-bit field" { - try expect(@sizeOf(extern struct { - x: u128, - y: u8, - }) == 32); - - comptime { - try expect(@sizeOf(extern struct { - x: u128, - y: u8, - }) == 32); - } -} - -test "@ptrCast preserves alignment of bigger source" { - var x: u32 align(16) = 1234; - const ptr = @ptrCast(*u8, &x); - try expect(@TypeOf(ptr) == *align(16) u8); -} - -test "alignstack" { - try expect(fnWithAlignedStack() == 1234); -} - -fn fnWithAlignedStack() i32 { - @setAlignStack(256); - return 1234; -} diff --git a/test/behavior/array.zig b/test/behavior/array.zig index cd2d029e22..017d15a64b 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -5,7 +5,23 @@ const mem = std.mem; const expect = testing.expect; const expectEqual = testing.expectEqual; +test "array to slice" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + + const a: u32 align(4) = 3; + const b: u32 align(8) = 4; + const a_slice: []align(1) const u32 = @as(*const [1]u32, &a)[0..]; + const b_slice: []align(1) const u32 = @as(*const [1]u32, &b)[0..]; + try expect(a_slice[0] + b_slice[0] == 7); + + const d: []const u32 = &[2]u32{ 1, 2 }; + const e: []const u32 = &[3]u32{ 3, 4, 5 }; + try expect(d[0] + e[0] + d[1] + e[1] == 10); +} + test "arrays" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + var array: [5]u32 = undefined; var i: u32 = 0; @@ -30,6 +46,8 @@ fn getArrayLen(a: []const u32) usize { } test "array init with mult" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + const a = 'a'; var i: [8]u8 = [2]u8{ a, 'b' } ** 4; try expect(std.mem.eql(u8, &i, "abababab")); @@ -39,6 +57,8 @@ test "array init with mult" { } test "array literal with explicit type" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + const hex_mult: [4]u16 = .{ 4096, 256, 16, 1 }; try expect(hex_mult.len == 4); @@ -46,6 +66,8 @@ test "array literal with explicit type" { } test "array literal with inferred length" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + const hex_mult = [_]u16{ 4096, 256, 16, 1 }; try expect(hex_mult.len == 4); @@ -53,6 +75,8 @@ test "array literal with inferred length" { } test "array dot len const expr" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + try expect(comptime x: { break :x some_array.len == 4; }); @@ -64,12 +88,16 @@ const ArrayDotLenConstExpr = struct { const some_array = [_]u8{ 0, 1, 2, 3 }; test "array literal with specified size" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + var array = [2]u8{ 1, 2 }; try expect(array[0] == 1); try expect(array[1] == 2); } test "array len field" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + var arr = [4]u8{ 0, 0, 0, 0 }; var ptr = &arr; try expect(arr.len == 4); @@ -79,6 +107,8 @@ test "array len field" { } test "array with sentinels" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + const S = struct { fn doTheTest(is_ct: bool) !void { if (is_ct or builtin.zig_is_stage2) { @@ -106,6 +136,8 @@ test "array with sentinels" { } test "void arrays" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + var array: [4]void = undefined; array[0] = void{}; array[1] = array[2]; @@ -114,6 +146,8 @@ test "void arrays" { } test "nested arrays" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_wasm) { // TODO this is a recent stage2 test case regression due to an enhancement; // now arrays are properly detected as comptime. This exercised a new code @@ -132,6 +166,8 @@ test "nested arrays" { } test "implicit comptime in array type size" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + var arr: [plusOne(10)]bool = undefined; try expect(arr.len == 11); } @@ -141,6 +177,8 @@ fn plusOne(x: u32) u32 { } test "single-item pointer to array indexing and slicing" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + try testSingleItemPtrArrayIndexSlice(); comptime try testSingleItemPtrArrayIndexSlice(); } @@ -164,6 +202,8 @@ fn doSomeMangling(array: *[4]u8) void { } test "implicit cast zero sized array ptr to slice" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + { var b = "".*; const c: []const u8 = &b; @@ -177,6 +217,8 @@ test "implicit cast zero sized array ptr to slice" { } test "anonymous list literal syntax" { + if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + const S = struct { fn doTheTest() !void { var array: [4]u8 = .{ 1, 2, 3, 4 }; diff --git a/test/behavior/array_simple.zig b/test/behavior/array_simple.zig deleted file mode 100644 index 0de92c9eb7..0000000000 --- a/test/behavior/array_simple.zig +++ /dev/null @@ -1,15 +0,0 @@ -const std = @import("std"); -const testing = std.testing; -const expect = testing.expect; - -test "array to slice" { - const a: u32 align(4) = 3; - const b: u32 align(8) = 4; - const a_slice: []align(1) const u32 = @as(*const [1]u32, &a)[0..]; - const b_slice: []align(1) const u32 = @as(*const [1]u32, &b)[0..]; - try expect(a_slice[0] + b_slice[0] == 7); - - const d: []const u32 = &[2]u32{ 1, 2 }; - const e: []const u32 = &[3]u32{ 3, 4, 5 }; - try expect(d[0] + e[0] + d[1] + e[1] == 10); -} From 3145fa97c21704d8822db928e5f988f22497b1b8 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 17 Jan 2022 21:52:15 +0100 Subject: [PATCH 3/3] stage2: separate ptr and stack offset codepaths in genSetStack --- src/arch/x86_64/CodeGen.zig | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 961bf365d6..2cf585fe4e 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -3252,9 +3252,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro } return self.fail("TODO implement memcpy for setting stack from {}", .{mcv}); }, - .ptr_stack_offset, - .stack_offset, - => |off| { + .ptr_stack_offset => { + const reg = try self.copyToTmpRegister(ty, mcv); + return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); + }, + .stack_offset => |off| { if (stack_offset == off) { // Copy stack variable to itself; nothing to do. return;