authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-16 16:09:22-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-05-16 16:09:22-07:00
log958fba0eb715fe9f0b5eddcf53507db03e37ae09
tree2505c7bdfd50cebb986201271a42899fce12c21c
parentb754068fbc7492962953068d31386d4c04e37ae5
parent6fca3f8b72397d62dd7b2d2e07db843c88428ac3
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #15713 from alichraghi/ali-spirv

spirv: get more behavior tests passing

7 files changed, 114 insertions(+), 20 deletions(-)

src/codegen/spirv.zig+110-4
...@@ -369,6 +369,17 @@ pub const DeclGen = struct {...@@ -369,6 +369,17 @@ pub const DeclGen = struct {
369 .composite_integer,369 .composite_integer,
370 };370 };
371 },371 },
372 .Enum => blk: {
373 var buffer: Type.Payload.Bits = undefined;
374 const int_ty = ty.intTagType(&buffer);
375 const int_info = int_ty.intInfo(target);
376 break :blk ArithmeticTypeInfo{
377 .bits = int_info.bits,
378 .is_vector = false,
379 .signedness = int_info.signedness,
380 .class = .integer,
381 };
382 },
372 // As of yet, there is no vector support in the self-hosted compiler.383 // As of yet, there is no vector support in the self-hosted compiler.
373 .Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}),384 .Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}),
374 // TODO: For which types is this the case?385 // TODO: For which types is this the case?
...@@ -568,6 +579,28 @@ pub const DeclGen = struct {...@@ -568,6 +579,28 @@ pub const DeclGen = struct {
568 try self.addBytes(std.mem.asBytes(&int_bits)[0..@intCast(usize, len)]);579 try self.addBytes(std.mem.asBytes(&int_bits)[0..@intCast(usize, len)]);
569 }580 }
570581
582 fn addFloat(self: *@This(), ty: Type, val: Value) !void {
583 const target = self.dg.getTarget();
584 const len = ty.abiSize(target);
585
586 // TODO: Swap endianess if the compiler is big endian.
587 switch (ty.floatBits(target)) {
588 16 => {
589 const float_bits = val.toFloat(f16);
590 try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]);
591 },
592 32 => {
593 const float_bits = val.toFloat(f32);
594 try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]);
595 },
596 64 => {
597 const float_bits = val.toFloat(f64);
598 try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]);
599 },
600 else => unreachable,
601 }
602 }
603
571 fn addDeclRef(self: *@This(), ty: Type, decl_index: Decl.Index) !void {604 fn addDeclRef(self: *@This(), ty: Type, decl_index: Decl.Index) !void {
572 const dg = self.dg;605 const dg = self.dg;
573606
...@@ -618,6 +651,7 @@ pub const DeclGen = struct {...@@ -618,6 +651,7 @@ pub const DeclGen = struct {
618651
619 switch (ty.zigTypeTag()) {652 switch (ty.zigTypeTag()) {
620 .Int => try self.addInt(ty, val),653 .Int => try self.addInt(ty, val),
654 .Float => try self.addFloat(ty, val),
621 .Bool => try self.addConstBool(val.toBool()),655 .Bool => try self.addConstBool(val.toBool()),
622 .Array => switch (val.tag()) {656 .Array => switch (val.tag()) {
623 .aggregate => {657 .aggregate => {
...@@ -1690,6 +1724,9 @@ pub const DeclGen = struct {...@@ -1690,6 +1724,9 @@ pub const DeclGen = struct {
16901724
1691 .bitcast => try self.airBitcast(inst),1725 .bitcast => try self.airBitcast(inst),
1692 .intcast, .trunc => try self.airIntcast(inst),1726 .intcast, .trunc => try self.airIntcast(inst),
1727 .ptrtoint => try self.airPtrToInt(inst),
1728 .int_to_float => try self.airIntToFloat(inst),
1729 .float_to_int => try self.airFloatToInt(inst),
1693 .not => try self.airNot(inst),1730 .not => try self.airNot(inst),
16941731
1695 .slice_ptr => try self.airSliceField(inst, 0),1732 .slice_ptr => try self.airSliceField(inst, 0),
...@@ -1750,10 +1787,12 @@ pub const DeclGen = struct {...@@ -1750,10 +1787,12 @@ pub const DeclGen = struct {
1750 .call_never_tail => try self.airCall(inst, .never_tail),1787 .call_never_tail => try self.airCall(inst, .never_tail),
1751 .call_never_inline => try self.airCall(inst, .never_inline),1788 .call_never_inline => try self.airCall(inst, .never_inline),
17521789
1753 .dbg_var_ptr => return,1790 .dbg_inline_begin => return,
1754 .dbg_var_val => return,1791 .dbg_inline_end => return,
1755 .dbg_block_begin => return,1792 .dbg_var_ptr => return,
1756 .dbg_block_end => return,1793 .dbg_var_val => return,
1794 .dbg_block_begin => return,
1795 .dbg_block_end => return,
1757 // zig fmt: on1796 // zig fmt: on
17581797
1759 else => |tag| return self.todo("implement AIR tag {s}", .{@tagName(tag)}),1798 else => |tag| return self.todo("implement AIR tag {s}", .{@tagName(tag)}),
...@@ -2095,6 +2134,73 @@ pub const DeclGen = struct {...@@ -2095,6 +2134,73 @@ pub const DeclGen = struct {
2095 return result_id;2134 return result_id;
2096 }2135 }
20972136
2137 fn airPtrToInt(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2138 if (self.liveness.isUnused(inst)) return null;
2139
2140 const un_op = self.air.instructions.items(.data)[inst].un_op;
2141 const operand_id = try self.resolve(un_op);
2142 const result_type_id = try self.resolveTypeId(Type.usize);
2143
2144 const result_id = self.spv.allocId();
2145 try self.func.body.emit(self.spv.gpa, .OpConvertPtrToU, .{
2146 .id_result_type = result_type_id,
2147 .id_result = result_id,
2148 .pointer = operand_id,
2149 });
2150 return result_id;
2151 }
2152
2153 fn airIntToFloat(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2154 if (self.liveness.isUnused(inst)) return null;
2155
2156 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2157 const operand_ty = self.air.typeOf(ty_op.operand);
2158 const operand_id = try self.resolve(ty_op.operand);
2159 const operand_info = try self.arithmeticTypeInfo(operand_ty);
2160 const dest_ty = self.air.typeOfIndex(inst);
2161 const dest_ty_id = try self.resolveTypeId(dest_ty);
2162
2163 const result_id = self.spv.allocId();
2164 switch (operand_info.signedness) {
2165 .signed => try self.func.body.emit(self.spv.gpa, .OpConvertSToF, .{
2166 .id_result_type = dest_ty_id,
2167 .id_result = result_id,
2168 .signed_value = operand_id,
2169 }),
2170 .unsigned => try self.func.body.emit(self.spv.gpa, .OpConvertUToF, .{
2171 .id_result_type = dest_ty_id,
2172 .id_result = result_id,
2173 .unsigned_value = operand_id,
2174 }),
2175 }
2176 return result_id;
2177 }
2178
2179 fn airFloatToInt(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2180 if (self.liveness.isUnused(inst)) return null;
2181
2182 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2183 const operand_id = try self.resolve(ty_op.operand);
2184 const dest_ty = self.air.typeOfIndex(inst);
2185 const dest_info = try self.arithmeticTypeInfo(dest_ty);
2186 const dest_ty_id = try self.resolveTypeId(dest_ty);
2187
2188 const result_id = self.spv.allocId();
2189 switch (dest_info.signedness) {
2190 .signed => try self.func.body.emit(self.spv.gpa, .OpConvertFToS, .{
2191 .id_result_type = dest_ty_id,
2192 .id_result = result_id,
2193 .float_value = operand_id,
2194 }),
2195 .unsigned => try self.func.body.emit(self.spv.gpa, .OpConvertFToU, .{
2196 .id_result_type = dest_ty_id,
2197 .id_result = result_id,
2198 .float_value = operand_id,
2199 }),
2200 }
2201 return result_id;
2202 }
2203
2098 fn airNot(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2204 fn airNot(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2099 if (self.liveness.isUnused(inst)) return null;2205 if (self.liveness.isUnused(inst)) return null;
2100 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2206 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
test/behavior/cast.zig-10
...@@ -97,7 +97,6 @@ test "@intToFloat" {...@@ -97,7 +97,6 @@ test "@intToFloat" {
97 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO97 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
98 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO98 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
99 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO99 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
100 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
101100
102 const S = struct {101 const S = struct {
103 fn doTheTest() !void {102 fn doTheTest() !void {
...@@ -155,7 +154,6 @@ test "@floatToInt" {...@@ -155,7 +154,6 @@ test "@floatToInt" {
155 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO154 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
156 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO155 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
157 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO156 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
158 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
159157
160 try testFloatToInts();158 try testFloatToInts();
161 comptime try testFloatToInts();159 comptime try testFloatToInts();
...@@ -207,16 +205,12 @@ test "implicitly cast indirect pointer to maybe-indirect pointer" {...@@ -207,16 +205,12 @@ test "implicitly cast indirect pointer to maybe-indirect pointer" {
207}205}
208206
209test "@intCast comptime_int" {207test "@intCast comptime_int" {
210 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
211
212 const result = @intCast(i32, 1234);208 const result = @intCast(i32, 1234);
213 try expect(@TypeOf(result) == i32);209 try expect(@TypeOf(result) == i32);
214 try expect(result == 1234);210 try expect(result == 1234);
215}211}
216212
217test "@floatCast comptime_int and comptime_float" {213test "@floatCast comptime_int and comptime_float" {
218 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
219
220 {214 {
221 const result = @floatCast(f16, 1234);215 const result = @floatCast(f16, 1234);
222 try expect(@TypeOf(result) == f16);216 try expect(@TypeOf(result) == f16);
...@@ -1290,14 +1284,10 @@ test "implicit cast *[0]T to E![]const u8" {...@@ -1290,14 +1284,10 @@ test "implicit cast *[0]T to E![]const u8" {
12901284
1291var global_array: [4]u8 = undefined;1285var global_array: [4]u8 = undefined;
1292test "cast from array reference to fn: comptime fn ptr" {1286test "cast from array reference to fn: comptime fn ptr" {
1293 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1294
1295 const f = @ptrCast(*align(1) const fn () callconv(.C) void, &global_array);1287 const f = @ptrCast(*align(1) const fn () callconv(.C) void, &global_array);
1296 try expect(@ptrToInt(f) == @ptrToInt(&global_array));1288 try expect(@ptrToInt(f) == @ptrToInt(&global_array));
1297}1289}
1298test "cast from array reference to fn: runtime fn ptr" {1290test "cast from array reference to fn: runtime fn ptr" {
1299 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1300
1301 var f = @ptrCast(*align(1) const fn () callconv(.C) void, &global_array);1291 var f = @ptrCast(*align(1) const fn () callconv(.C) void, &global_array);
1302 try expect(@ptrToInt(f) == @ptrToInt(&global_array));1292 try expect(@ptrToInt(f) == @ptrToInt(&global_array));
1303}1293}
test/behavior/enum.zig-5
...@@ -27,7 +27,6 @@ const IntToEnumNumber = enum { Zero, One, Two, Three, Four };...@@ -27,7 +27,6 @@ const IntToEnumNumber = enum { Zero, One, Two, Three, Four };
27test "int to enum" {27test "int to enum" {
28 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;28 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
29 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO29 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
30 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
3130
32 try testIntToEnumEval(3);31 try testIntToEnumEval(3);
33}32}
...@@ -576,8 +575,6 @@ test "enum literal equality" {...@@ -576,8 +575,6 @@ test "enum literal equality" {
576}575}
577576
578test "enum literal cast to enum" {577test "enum literal cast to enum" {
579 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
580
581 const Color = enum { Auto, Off, On };578 const Color = enum { Auto, Off, On };
582579
583 var color1: Color = .Auto;580 var color1: Color = .Auto;
...@@ -874,8 +871,6 @@ test "switch on enum with one member is comptime-known" {...@@ -874,8 +871,6 @@ test "switch on enum with one member is comptime-known" {
874}871}
875872
876test "method call on an enum" {873test "method call on an enum" {
877 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
878
879 const S = struct {874 const S = struct {
880 const E = enum {875 const E = enum {
881 one,876 one,
test/behavior/error.zig+1
...@@ -916,6 +916,7 @@ test "optional error set return type" {...@@ -916,6 +916,7 @@ test "optional error set return type" {
916test "try used in recursive function with inferred error set" {916test "try used in recursive function with inferred error set" {
917 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO917 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
918 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO918 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
919 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
919920
920 const Value = union(enum) {921 const Value = union(enum) {
921 values: []const @This(),922 values: []const @This(),
test/behavior/maximum_minimum.zig+1
...@@ -106,6 +106,7 @@ test "@min/max for floats" {...@@ -106,6 +106,7 @@ test "@min/max for floats" {
106 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO106 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
107 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO107 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
108 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO108 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
109 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
109110
110 const S = struct {111 const S = struct {
111 fn doTheTest(comptime T: type) !void {112 fn doTheTest(comptime T: type) !void {
test/behavior/slice.zig+2
...@@ -186,6 +186,8 @@ test "slicing zero length array" {...@@ -186,6 +186,8 @@ test "slicing zero length array" {
186186
187test "slicing pointer by length" {187test "slicing pointer by length" {
188 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;188 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
189 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
190
189 const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };191 const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
190 const ptr: [*]const u8 = @ptrCast([*]const u8, &array);192 const ptr: [*]const u8 = @ptrCast([*]const u8, &array);
191 const slice = ptr[1..][0..5];193 const slice = ptr[1..][0..5];
test/behavior/union.zig-1
...@@ -365,7 +365,6 @@ test "simple union(enum(u32))" {...@@ -365,7 +365,6 @@ test "simple union(enum(u32))" {
365 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;365 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
366 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;366 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
367 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO367 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
368 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
369368
370 var x = MultipleChoice.C;369 var x = MultipleChoice.C;
371 try expect(x == MultipleChoice.C);370 try expect(x == MultipleChoice.C);