| author | |
| committer | |
| log | 2bbac862018599c121281f2ca5658f3879c0c0a3 |
| tree | e623382ca7e637dce46749617853a30e9173f1a7 |
| parent | 0a01fe2bc6748b5fa2b03cebdcaae0e655501ad4 |
17 files changed, 163 insertions(+), 191 deletions(-)
src/Sema.zig+17-42| ... | @@ -8695,19 +8695,17 @@ fn checkParamType( | ... | @@ -8695,19 +8695,17 @@ fn checkParamType( |
| 8695 | if (param_is_noalias and !param_ty.isGenericPoison() and !param_ty.isPtrAtRuntime(zcu) and !param_ty.isSliceAtRuntime(zcu)) { | 8695 | if (param_is_noalias and !param_ty.isGenericPoison() and !param_ty.isPtrAtRuntime(zcu) and !param_ty.isSliceAtRuntime(zcu)) { |
| 8696 | return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{}); | 8696 | return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{}); |
| 8697 | } | 8697 | } |
| 8698 | switch (target.os.tag) { | 8698 | if (cc != .@"inline" and param_ty.isPtrAtRuntime(zcu)) { |
| 8699 | .vulkan, .opengl => if (cc != .@"inline" and param_ty.isPtrAtRuntime(zcu)) { | 8699 | const as = param_ty.ptrAddressSpace(zcu); |
| 8700 | switch (param_ty.ptrAddressSpace(zcu)) { | 8700 | if (target_util.addrSpaceIsLogical(target, as)) switch (as) { |
| 8701 | .input, .output => |as| return sema.failWithOwnedErrorMsg(block, msg: { | 8701 | .input, .output => return sema.failWithOwnedErrorMsg(block, msg: { |
| 8702 | const msg = try sema.errMsg(param_src, "function parameter cannot be a pointer in '{s}' address space", .{@tagName(as)}); | 8702 | const msg = try sema.errMsg(param_src, "function parameter cannot be a pointer in '{s}' address space", .{@tagName(as)}); |
| 8703 | errdefer msg.destroy(sema.gpa); | 8703 | errdefer msg.destroy(sema.gpa); |
| 8704 | try sema.errNote(param_src, msg, "mark the function as 'inline' so the parameter is substituted at call sites", .{}); | 8704 | try sema.errNote(param_src, msg, "mark the function as 'inline' so the parameter is substituted at call sites", .{}); |
| 8705 | break :msg msg; | 8705 | break :msg msg; |
| 8706 | }), | 8706 | }), |
| 8707 | else => {}, | 8707 | else => {}, |
| 8708 | } | 8708 | }; |
| 8709 | }, | ||
| 8710 | else => {}, | ||
| 8711 | } | 8709 | } |
| 8712 | } | 8710 | } |
| 8713 | 8711 | ||
| ... | @@ -8944,9 +8942,7 @@ fn checkMergeAllowed(sema: *Sema, block: *Block, src: LazySrcLoc, peer_ty: Type) | ... | @@ -8944,9 +8942,7 @@ fn checkMergeAllowed(sema: *Sema, block: *Block, src: LazySrcLoc, peer_ty: Type) |
| 8944 | } | 8942 | } |
| 8945 | 8943 | ||
| 8946 | const as = peer_ty.ptrAddressSpace(zcu); | 8944 | const as = peer_ty.ptrAddressSpace(zcu); |
| 8947 | if (!target_util.shouldBlockPointerOps(target, as)) { | 8945 | if (!target_util.addrSpaceIsLogical(target, as)) return; |
| 8948 | return; | ||
| 8949 | } | ||
| 8950 | 8946 | ||
| 8951 | return sema.failWithOwnedErrorMsg(block, msg: { | 8947 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 8952 | const msg = try sema.errMsg(src, "value with non-mergable pointer type '{f}' depends on runtime control flow", .{peer_ty.fmt(zcu)}); | 8948 | const msg = try sema.errMsg(src, "value with non-mergable pointer type '{f}' depends on runtime control flow", .{peer_ty.fmt(zcu)}); |
| ... | @@ -22245,7 +22241,7 @@ fn ptrCastFull( | ... | @@ -22245,7 +22241,7 @@ fn ptrCastFull( |
| 22245 | try sema.validateRuntimeValue(block, operand_src, operand); | 22241 | try sema.validateRuntimeValue(block, operand_src, operand); |
| 22246 | try sema.checkLogicalPtrCast(block, src, operand_ty, dest_ty); | 22242 | try sema.checkLogicalPtrCast(block, src, operand_ty, dest_ty); |
| 22247 | 22243 | ||
| 22248 | const can_cast_to_int = !target_util.shouldBlockPointerOps(zcu.getTarget(), operand_ty.ptrAddressSpace(zcu)); | 22244 | const can_cast_to_int = !target_util.addrSpaceIsLogical(zcu.getTarget(), operand_ty.ptrAddressSpace(zcu)); |
| 22249 | const need_null_check = can_cast_to_int and block.wantSafety() and operand_ty.ptrAllowsZero(zcu) and !dest_ty.ptrAllowsZero(zcu); | 22245 | const need_null_check = can_cast_to_int and block.wantSafety() and operand_ty.ptrAllowsZero(zcu) and !dest_ty.ptrAllowsZero(zcu); |
| 22250 | const need_align_check = can_cast_to_int and block.wantSafety() and dest_align.compare(.gt, src_align); | 22246 | const need_align_check = can_cast_to_int and block.wantSafety() and dest_align.compare(.gt, src_align); |
| 22251 | 22247 | ||
| ... | @@ -22791,7 +22787,7 @@ fn checkLogicalPtrOperation(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ | ... | @@ -22791,7 +22787,7 @@ fn checkLogicalPtrOperation(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ |
| 22791 | if (zcu.intern_pool.indexToKey(ty.toIntern()) == .ptr_type) { | 22787 | if (zcu.intern_pool.indexToKey(ty.toIntern()) == .ptr_type) { |
| 22792 | const target = zcu.getTarget(); | 22788 | const target = zcu.getTarget(); |
| 22793 | const as = ty.ptrAddressSpace(zcu); | 22789 | const as = ty.ptrAddressSpace(zcu); |
| 22794 | if (target_util.shouldBlockPointerOps(target, as)) { | 22790 | if (target_util.addrSpaceIsLogical(target, as)) { |
| 22795 | return sema.failWithOwnedErrorMsg(block, msg: { | 22791 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 22796 | const msg = try sema.errMsg(src, "illegal operation on logical pointer of type '{f}'", .{ty.fmt(zcu)}); | 22792 | const msg = try sema.errMsg(src, "illegal operation on logical pointer of type '{f}'", .{ty.fmt(zcu)}); |
| 22797 | errdefer msg.destroy(sema.gpa); | 22793 | errdefer msg.destroy(sema.gpa); |
| ... | @@ -22822,11 +22818,7 @@ fn checkLogicalPtrCast( | ... | @@ -22822,11 +22818,7 @@ fn checkLogicalPtrCast( |
| 22822 | const dest_child: Type = .fromInterned(dest_info.child); | 22818 | const dest_child: Type = .fromInterned(dest_info.child); |
| 22823 | 22819 | ||
| 22824 | if (block.isComptime() or block.is_typeof) return; | 22820 | if (block.isComptime() or block.is_typeof) return; |
| 22825 | switch (zcu.getTarget().os.tag) { | 22821 | if (!target_util.addrSpaceIsLogical(zcu.getTarget(), src_info.flags.address_space)) return; |
| 22826 | .vulkan, .opengl => {}, | ||
| 22827 | else => return, | ||
| 22828 | } | ||
| 22829 | if (src_info.flags.address_space == .physical_storage_buffer) return; | ||
| 22830 | if (!dest_child.hasRuntimeBits(zcu)) return; | 22822 | if (!dest_child.hasRuntimeBits(zcu)) return; |
| 22831 | 22823 | ||
| 22832 | var cur = src_child; | 22824 | var cur = src_child; |
| ... | @@ -30297,25 +30289,8 @@ fn checkSpirvSliceAllowed( | ... | @@ -30297,25 +30289,8 @@ fn checkSpirvSliceAllowed( |
| 30297 | if (!target.cpu.arch.isSpirV()) return; | 30289 | if (!target.cpu.arch.isSpirV()) return; |
| 30298 | if (block.isComptime()) return; | 30290 | if (block.isComptime()) return; |
| 30299 | 30291 | ||
| 30300 | // This probably lets some invalid OpPtrAccessChains slip through, but it's better than nothing | 30292 | if (!target_util.addrSpaceIsLogical(target, address_space)) return; |
| 30301 | if (!target.cpu.has(.spirv, .variable_pointers) and !target.cpu.has(.spirv, .variable_pointers_storage_buffer)) { | 30293 | return sema.fail(block, src, "cannot construct slice from logical address space '{t}'", .{address_space}); |
| 30302 | return sema.failWithOwnedErrorMsg( | ||
| 30303 | block, | ||
| 30304 | try sema.errMsg(src, "cannot construct slices without the 'variable_pointers' or 'variable_pointers_storage_buffer' features", .{}), | ||
| 30305 | ); | ||
| 30306 | } | ||
| 30307 | |||
| 30308 | switch (address_space) { | ||
| 30309 | .shared, .storage_buffer => {}, | ||
| 30310 | else => { | ||
| 30311 | return sema.failWithOwnedErrorMsg(block, msg: { | ||
| 30312 | const msg = try sema.errMsg(src, "cannot construct slice from address space '{t}'", .{address_space}); | ||
| 30313 | errdefer msg.destroy(sema.gpa); | ||
| 30314 | try sema.errNote(src, msg, "only 'shared' and 'storage_buffer' address spaces support slicing on SPIR-V", .{}); | ||
| 30315 | break :msg msg; | ||
| 30316 | }); | ||
| 30317 | }, | ||
| 30318 | } | ||
| 30319 | } | 30294 | } |
| 30320 | 30295 | ||
| 30321 | fn coerceArrayPtrToSlice( | 30296 | fn coerceArrayPtrToSlice( |
src/codegen/spirv/CodeGen.zig+84-109| ... | @@ -816,21 +816,20 @@ pub fn memberDebugName(cg: *CodeGen, target: Id, member: u32, name: []const u8) | ... | @@ -816,21 +816,20 @@ pub fn memberDebugName(cg: *CodeGen, target: Id, member: u32, name: []const u8) |
| 816 | pub fn storageClass(cg: *const CodeGen, as: std.lang.AddressSpace) spec.StorageClass { | 816 | pub fn storageClass(cg: *const CodeGen, as: std.lang.AddressSpace) spec.StorageClass { |
| 817 | const target = cg.zcu.getTarget(); | 817 | const target = cg.zcu.getTarget(); |
| 818 | return switch (as) { | 818 | return switch (as) { |
| 819 | .generic => .function, | ||
| 820 | .global => switch (target.os.tag) { | 819 | .global => switch (target.os.tag) { |
| 821 | .opencl, .amdhsa => .cross_workgroup, | 820 | .opencl, .amdhsa => .cross_workgroup, |
| 822 | else => .storage_buffer, | 821 | else => unreachable, |
| 823 | }, | 822 | }, |
| 823 | .local, .generic => .function, | ||
| 824 | .push_constant => .push_constant, | 824 | .push_constant => .push_constant, |
| 825 | .output => .output, | ||
| 826 | .uniform => .uniform, | 825 | .uniform => .uniform, |
| 827 | .storage_buffer => .storage_buffer, | 826 | .storage_buffer => .storage_buffer, |
| 828 | .physical_storage_buffer => .physical_storage_buffer, | 827 | .physical_storage_buffer => .physical_storage_buffer, |
| 829 | .constant => .uniform_constant, | 828 | .constant => .uniform_constant, |
| 830 | .shared => .workgroup, | 829 | .shared => .workgroup, |
| 831 | .local => .function, | ||
| 832 | .private => .private, | 830 | .private => .private, |
| 833 | .input => .input, | 831 | .input => .input, |
| 832 | .output => .output, | ||
| 834 | .gs, | 833 | .gs, |
| 835 | .fs, | 834 | .fs, |
| 836 | .ss, | 835 | .ss, |
| ... | @@ -1689,14 +1688,14 @@ fn constantPtr(cg: *CodeGen, ptr_val: Value) !Id { | ... | @@ -1689,14 +1688,14 @@ fn constantPtr(cg: *CodeGen, ptr_val: Value) !Id { |
| 1689 | /// This function emits instructions on every call, and they stay in the module whether or not they | 1688 | /// This function emits instructions on every call, and they stay in the module whether or not they |
| 1690 | /// are read, so it should only be called where the resulting type is used: a buffer struct emitted | 1689 | /// are read, so it should only be called where the resulting type is used: a buffer struct emitted |
| 1691 | /// without `Block` fails validation even when nothing refers to it. | 1690 | /// without `Block` fails validation even when nothing refers to it. |
| 1692 | fn derivedPtrType(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Value.PointerDerivation) !Id { | 1691 | fn derivedPtrType(cg: *CodeGen, as: std.lang.AddressSpace, derivation: Value.PointerDerivation) !Id { |
| 1693 | return cg.ptrType( | 1692 | return cg.ptrType( |
| 1694 | try cg.pointeeType(@"addrspace", derivation.elem_ty, false), | 1693 | try cg.pointeeType(as, derivation.elem_ty, false), |
| 1695 | cg.storageClass(@"addrspace"), | 1694 | cg.storageClass(as), |
| 1696 | ); | 1695 | ); |
| 1697 | } | 1696 | } |
| 1698 | 1697 | ||
| 1699 | fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Value.PointerDerivation) !Id { | 1698 | fn derivePtr(cg: *CodeGen, as: std.lang.AddressSpace, derivation: Value.PointerDerivation) !Id { |
| 1700 | const gpa = cg.gpa; | 1699 | const gpa = cg.gpa; |
| 1701 | const zcu = cg.zcu; | 1700 | const zcu = cg.zcu; |
| 1702 | const target = zcu.getTarget(); | 1701 | const target = zcu.getTarget(); |
| ... | @@ -1704,18 +1703,16 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu | ... | @@ -1704,18 +1703,16 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1704 | switch (derivation.addr) { | 1703 | switch (derivation.addr) { |
| 1705 | .comptime_alloc, .comptime_field => unreachable, | 1704 | .comptime_alloc, .comptime_field => unreachable, |
| 1706 | .int => |int| { | 1705 | .int => |int| { |
| 1707 | if (target.os.tag != .opencl) { | 1706 | if (target_util.addrSpaceIsLogical(target, as)) { |
| 1708 | if (@"addrspace" != .physical_storage_buffer) { | 1707 | return cg.fail( |
| 1709 | return cg.fail( | 1708 | "cannot cast integer to pointer with address space '{s}'", |
| 1710 | "cannot cast integer to pointer with address space '{s}'", | 1709 | .{@tagName(as)}, |
| 1711 | .{@tagName(@"addrspace")}, | 1710 | ); |
| 1712 | ); | ||
| 1713 | } | ||
| 1714 | } | 1711 | } |
| 1715 | // TODO: This can probably be an OpSpecConstantOp Bitcast, but | 1712 | // TODO: This can probably be an OpSpecConstantOp Bitcast, but |
| 1716 | // that is not implemented by Mesa yet. Therefore, just generate it | 1713 | // that is not implemented by Mesa yet. Therefore, just generate it |
| 1717 | // as a runtime operation. | 1714 | // as a runtime operation. |
| 1718 | const result_ty_id = try cg.derivedPtrType(@"addrspace", derivation); | 1715 | const result_ty_id = try cg.derivedPtrType(as, derivation); |
| 1719 | const result_ptr_id = cg.allocId(); | 1716 | const result_ptr_id = cg.allocId(); |
| 1720 | const value_id = try cg.constInt(.usize, int); | 1717 | const value_id = try cg.constInt(.usize, int); |
| 1721 | try cg.body.emit(gpa, .OpConvertUToPtr, .{ | 1718 | try cg.body.emit(gpa, .OpConvertUToPtr, .{ |
| ... | @@ -1735,30 +1732,26 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu | ... | @@ -1735,30 +1732,26 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1735 | 1732 | ||
| 1736 | if (ip.isFunctionType(nav_ty.toIntern())) { | 1733 | if (ip.isFunctionType(nav_ty.toIntern())) { |
| 1737 | if (is_extern) return try cg.resolveExternFn(nav_index); | 1734 | if (is_extern) return try cg.resolveExternFn(nav_index); |
| 1738 | return try cg.constUndef(try cg.derivedPtrType(@"addrspace", derivation)); | 1735 | return try cg.constUndef(try cg.derivedPtrType(as, derivation)); |
| 1739 | } | 1736 | } |
| 1740 | if (!nav_ty.hasRuntimeBits(zcu) and nav_ty.zigTypeTag(zcu) != .spirv) { | 1737 | if (!nav_ty.hasRuntimeBits(zcu) and nav_ty.zigTypeTag(zcu) != .spirv) { |
| 1741 | return cg.constUndef(try cg.derivedPtrType(@"addrspace", derivation)); | 1738 | return cg.constUndef(try cg.derivedPtrType(as, derivation)); |
| 1742 | } | 1739 | } |
| 1743 | if (!is_extern) { | 1740 | if (!is_extern) { |
| 1744 | return cg.todo("pointer to constant '{f}'", .{nav.fqn.fmt(ip)}); | 1741 | return cg.todo("pointer to constant '{f}'", .{nav.fqn.fmt(ip)}); |
| 1745 | } | 1742 | } |
| 1746 | 1743 | ||
| 1747 | const as = nav.resolved.?.@"addrspace"; | 1744 | assert(nav.resolved.?.@"addrspace" != .generic); |
| 1748 | assert(as != .generic); | ||
| 1749 | 1745 | ||
| 1750 | const var_id = try cg.resolveNav(nav_index); | 1746 | const var_id = try cg.resolveNav(nav_index); |
| 1751 | if (cg.needsLayout(as, nav_ty)) { | 1747 | if (cg.needsLayout(as, nav_ty)) { |
| 1752 | try cg.block_var_ids.put(gpa, var_id, {}); | 1748 | try cg.block_var_ids.put(gpa, var_id, {}); |
| 1753 | } | 1749 | } |
| 1754 | switch (target.os.tag) { | 1750 | if (target_util.addrSpaceIsLogical(target, as)) return var_id; |
| 1755 | .vulkan, .opengl => return var_id, | ||
| 1756 | else => {}, | ||
| 1757 | } | ||
| 1758 | 1751 | ||
| 1759 | const nav_ty_id = try cg.resolveType(nav_ty, .indirect); | 1752 | const nav_ty_id = try cg.resolveType(nav_ty, .indirect); |
| 1760 | const decl_ptr_ty_id = try cg.ptrType(nav_ty_id, cg.storageClass(as)); | 1753 | const decl_ptr_ty_id = try cg.ptrType(nav_ty_id, cg.storageClass(as)); |
| 1761 | const result_ty_id = try cg.derivedPtrType(@"addrspace", derivation); | 1754 | const result_ty_id = try cg.derivedPtrType(as, derivation); |
| 1762 | if (decl_ptr_ty_id == result_ty_id) return var_id; | 1755 | if (decl_ptr_ty_id == result_ty_id) return var_id; |
| 1763 | 1756 | ||
| 1764 | const casted_ptr_id = cg.allocId(); | 1757 | const casted_ptr_id = cg.allocId(); |
| ... | @@ -1780,10 +1773,10 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu | ... | @@ -1780,10 +1773,10 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1780 | } | 1773 | } |
| 1781 | 1774 | ||
| 1782 | if (!uav_ty.hasRuntimeBits(zcu) and uav_ty.zigTypeTag(zcu) != .spirv) { | 1775 | if (!uav_ty.hasRuntimeBits(zcu) and uav_ty.zigTypeTag(zcu) != .spirv) { |
| 1783 | return cg.constUndef(try cg.derivedPtrType(@"addrspace", derivation)); | 1776 | return cg.constUndef(try cg.derivedPtrType(as, derivation)); |
| 1784 | } | 1777 | } |
| 1785 | 1778 | ||
| 1786 | if (cg.storageClass(@"addrspace") != .function) { | 1779 | if (cg.storageClass(as) != .function) { |
| 1787 | return cg.todo("pointer to an anonymous constant of type '{f}'", .{uav_ty.fmt(zcu)}); | 1780 | return cg.todo("pointer to an anonymous constant of type '{f}'", .{uav_ty.fmt(zcu)}); |
| 1788 | } | 1781 | } |
| 1789 | 1782 | ||
| ... | @@ -1796,11 +1789,11 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu | ... | @@ -1796,11 +1789,11 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1796 | .eu_payload => @panic("TODO"), | 1789 | .eu_payload => @panic("TODO"), |
| 1797 | .opt_payload => @panic("TODO"), | 1790 | .opt_payload => @panic("TODO"), |
| 1798 | .field => |derived| return cg.structFieldPtr( | 1791 | .field => |derived| return cg.structFieldPtr( |
| 1799 | @"addrspace", | 1792 | as, |
| 1800 | try cg.derivedPtrType(@"addrspace", derivation), | 1793 | try cg.derivedPtrType(as, derivation), |
| 1801 | derivation.elem_ty, | 1794 | derivation.elem_ty, |
| 1802 | derived.parent.elem_ty, | 1795 | derived.parent.elem_ty, |
| 1803 | try cg.derivePtr(@"addrspace", derived.parent.*), | 1796 | try cg.derivePtr(as, derived.parent.*), |
| 1804 | derived.field_index, | 1797 | derived.field_index, |
| 1805 | ), | 1798 | ), |
| 1806 | .elem => |derived| return cg.ptrElemPtr( | 1799 | .elem => |derived| return cg.ptrElemPtr( |
| ... | @@ -1808,13 +1801,13 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu | ... | @@ -1808,13 +1801,13 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1808 | .one => .single_array_ptr, | 1801 | .one => .single_array_ptr, |
| 1809 | .many => .many_ptr, | 1802 | .many => .many_ptr, |
| 1810 | }, | 1803 | }, |
| 1811 | @"addrspace", | 1804 | as, |
| 1812 | derivation.elem_ty, | 1805 | derivation.elem_ty, |
| 1813 | try cg.derivePtr(@"addrspace", derived.parent.*), | 1806 | try cg.derivePtr(as, derived.parent.*), |
| 1814 | try cg.constInt(.usize, derived.elem_index), | 1807 | try cg.constInt(.usize, derived.elem_index), |
| 1815 | ), | 1808 | ), |
| 1816 | .offset_and_cast => |derived| { | 1809 | .offset_and_cast => |derived| { |
| 1817 | const parent_ptr_id = try cg.derivePtr(@"addrspace", derived.parent.*); | 1810 | const parent_ptr_id = try cg.derivePtr(as, derived.parent.*); |
| 1818 | 1811 | ||
| 1819 | if (derived.byte_offset == 0) { | 1812 | if (derived.byte_offset == 0) { |
| 1820 | var depth: u32 = 0; | 1813 | var depth: u32 = 0; |
| ... | @@ -1849,13 +1842,13 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu | ... | @@ -1849,13 +1842,13 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1849 | const zero = try cg.constInt(.u32, 0); | 1842 | const zero = try cg.constInt(.u32, 0); |
| 1850 | const ids = try cg.id_scratch.addManyAsSlice(gpa, depth); | 1843 | const ids = try cg.id_scratch.addManyAsSlice(gpa, depth); |
| 1851 | @memset(ids, zero); | 1844 | @memset(ids, zero); |
| 1852 | return cg.accessChainId(try cg.derivedPtrType(@"addrspace", derivation), parent_ptr_id, ids); | 1845 | return cg.accessChainId(try cg.derivedPtrType(as, derivation), parent_ptr_id, ids); |
| 1853 | } else { | 1846 | } else { |
| 1854 | return parent_ptr_id; | 1847 | return parent_ptr_id; |
| 1855 | } | 1848 | } |
| 1856 | } | 1849 | } |
| 1857 | if (target.os.tag == .opencl) { | 1850 | if (!target_util.addrSpaceIsLogical(target, as)) { |
| 1858 | const result_ty_id = try cg.derivedPtrType(@"addrspace", derivation); | 1851 | const result_ty_id = try cg.derivedPtrType(as, derivation); |
| 1859 | const result_ptr_id = cg.allocId(); | 1852 | const result_ptr_id = cg.allocId(); |
| 1860 | try cg.body.emit(gpa, .OpBitcast, .{ | 1853 | try cg.body.emit(gpa, .OpBitcast, .{ |
| 1861 | .id_result_type = result_ty_id, | 1854 | .id_result_type = result_ty_id, |
| ... | @@ -3820,7 +3813,7 @@ fn generateTestEntryPoint( | ... | @@ -3820,7 +3813,7 @@ fn generateTestEntryPoint( |
| 3820 | const anyerror_ty_id = try cg.resolveType(.anyerror, .direct); | 3813 | const anyerror_ty_id = try cg.resolveType(.anyerror, .direct); |
| 3821 | const ptr_anyerror_ty = try cg.pt.ptrType(.{ | 3814 | const ptr_anyerror_ty = try cg.pt.ptrType(.{ |
| 3822 | .child = .anyerror_type, | 3815 | .child = .anyerror_type, |
| 3823 | .flags = .{ .address_space = .global }, | 3816 | .flags = .{ .address_space = .storage_buffer }, |
| 3824 | }); | 3817 | }); |
| 3825 | const ptr_anyerror_ty_id = try cg.resolveType(ptr_anyerror_ty, .direct); | 3818 | const ptr_anyerror_ty_id = try cg.resolveType(ptr_anyerror_ty, .direct); |
| 3826 | 3819 | ||
| ... | @@ -3863,7 +3856,7 @@ fn generateTestEntryPoint( | ... | @@ -3863,7 +3856,7 @@ fn generateTestEntryPoint( |
| 3863 | const ptr_buffer_struct_ty_id = cg.allocId(); | 3856 | const ptr_buffer_struct_ty_id = cg.allocId(); |
| 3864 | try cg.module.emit(gpa, .OpTypePointer, .{ | 3857 | try cg.module.emit(gpa, .OpTypePointer, .{ |
| 3865 | .id_result = ptr_buffer_struct_ty_id, | 3858 | .id_result = ptr_buffer_struct_ty_id, |
| 3866 | .storage_class = cg.storageClass(.global), | 3859 | .storage_class = cg.storageClass(.storage_buffer), |
| 3867 | .type = buffer_struct_ty_id, | 3860 | .type = buffer_struct_ty_id, |
| 3868 | }); | 3861 | }); |
| 3869 | 3862 | ||
| ... | @@ -3872,7 +3865,7 @@ fn generateTestEntryPoint( | ... | @@ -3872,7 +3865,7 @@ fn generateTestEntryPoint( |
| 3872 | try cg.module.emit(gpa, .OpVariable, .{ | 3865 | try cg.module.emit(gpa, .OpVariable, .{ |
| 3873 | .id_result_type = ptr_buffer_struct_ty_id, | 3866 | .id_result_type = ptr_buffer_struct_ty_id, |
| 3874 | .id_result = error_buffer_id, | 3867 | .id_result = error_buffer_id, |
| 3875 | .storage_class = cg.storageClass(.global), | 3868 | .storage_class = cg.storageClass(.storage_buffer), |
| 3876 | }); | 3869 | }); |
| 3877 | try cg.decorate(error_buffer_id, .{ .descriptor_set = .{ .descriptor_set = 0 } }); | 3870 | try cg.decorate(error_buffer_id, .{ .descriptor_set = .{ .descriptor_set = 0 } }); |
| 3878 | try cg.decorate(error_buffer_id, .{ .binding = .{ .binding_point = 0 } }); | 3871 | try cg.decorate(error_buffer_id, .{ .binding = .{ .binding_point = 0 } }); |
| ... | @@ -5464,6 +5457,7 @@ fn accessChain( | ... | @@ -5464,6 +5457,7 @@ fn accessChain( |
| 5464 | 5457 | ||
| 5465 | fn ptrAccessChain( | 5458 | fn ptrAccessChain( |
| 5466 | cg: *CodeGen, | 5459 | cg: *CodeGen, |
| 5460 | as: std.lang.AddressSpace, | ||
| 5467 | result_ty_id: Id, | 5461 | result_ty_id: Id, |
| 5468 | base: Id, | 5462 | base: Id, |
| 5469 | element: Id, | 5463 | element: Id, |
| ... | @@ -5491,8 +5485,7 @@ fn ptrAccessChain( | ... | @@ -5491,8 +5485,7 @@ fn ptrAccessChain( |
| 5491 | }); | 5485 | }); |
| 5492 | }, | 5486 | }, |
| 5493 | .vulkan, .opengl => { | 5487 | .vulkan, .opengl => { |
| 5494 | assert(target.cpu.has(.spirv, .variable_pointers) or | 5488 | assert(!target_util.addrSpaceIsLogical(target, as)); |
| 5495 | target.cpu.has(.spirv, .variable_pointers_storage_buffer)); | ||
| 5496 | try cg.body.emit(gpa, .OpPtrAccessChain, .{ | 5489 | try cg.body.emit(gpa, .OpPtrAccessChain, .{ |
| 5497 | .id_result_type = result_ty_id, | 5490 | .id_result_type = result_ty_id, |
| 5498 | .id_result = result_id, | 5491 | .id_result = result_id, |
| ... | @@ -5513,11 +5506,11 @@ fn ptrAdd(cg: *CodeGen, result_ty: Type, ptr_ty: Type, ptr_id: Id, offset_id: Id | ... | @@ -5513,11 +5506,11 @@ fn ptrAdd(cg: *CodeGen, result_ty: Type, ptr_ty: Type, ptr_id: Id, offset_id: Id |
| 5513 | const result_ty_id = try cg.ptrType(child_ty_id, cg.storageClass(as)); | 5506 | const result_ty_id = try cg.ptrType(child_ty_id, cg.storageClass(as)); |
| 5514 | return switch (ptr_ty.ptrSize(zcu)) { | 5507 | return switch (ptr_ty.ptrSize(zcu)) { |
| 5515 | .one => cg.accessChainId(result_ty_id, ptr_id, &.{offset_id}), | 5508 | .one => cg.accessChainId(result_ty_id, ptr_id, &.{offset_id}), |
| 5516 | .c, .many => cg.ptrAccessChain(result_ty_id, ptr_id, offset_id, &.{}), | 5509 | .c, .many => cg.ptrAccessChain(as, result_ty_id, ptr_id, offset_id, &.{}), |
| 5517 | .slice => blk: { | 5510 | .slice => blk: { |
| 5518 | // TODO: This is probably incorrect. A slice should be returned here, though this is what llvm does. | 5511 | // TODO: This is probably incorrect. A slice should be returned here, though this is what llvm does. |
| 5519 | const slice_ptr_id = try cg.extractField(result_ty, ptr_id, 0); | 5512 | const slice_ptr_id = try cg.extractField(result_ty, ptr_id, 0); |
| 5520 | break :blk cg.ptrAccessChain(result_ty_id, slice_ptr_id, offset_id, &.{}); | 5513 | break :blk cg.ptrAccessChain(as, result_ty_id, slice_ptr_id, offset_id, &.{}); |
| 5521 | }, | 5514 | }, |
| 5522 | }; | 5515 | }; |
| 5523 | } | 5516 | } |
| ... | @@ -5770,8 +5763,8 @@ fn bitCast( | ... | @@ -5770,8 +5763,8 @@ fn bitCast( |
| 5770 | const target = zcu.getTarget(); | 5763 | const target = zcu.getTarget(); |
| 5771 | 5764 | ||
| 5772 | if (src_ty.toIntern() == dst_ty.toIntern()) return src_id; | 5765 | if (src_ty.toIntern() == dst_ty.toIntern()) return src_id; |
| 5773 | if (src_ty.isPtrAtRuntime(zcu) and dst_ty.isPtrAtRuntime(zcu)) switch (target.os.tag) { | 5766 | if (src_ty.isPtrAtRuntime(zcu) and dst_ty.isPtrAtRuntime(zcu)) { |
| 5774 | .vulkan, .opengl => if (src_ty.ptrAddressSpace(zcu) != .physical_storage_buffer) { | 5767 | if (target_util.addrSpaceIsLogical(target, src_ty.ptrAddressSpace(zcu))) { |
| 5775 | const src_child = src_ty.childType(zcu); | 5768 | const src_child = src_ty.childType(zcu); |
| 5776 | const dst_child = dst_ty.childType(zcu); | 5769 | const dst_child = dst_ty.childType(zcu); |
| 5777 | if (!dst_child.hasRuntimeBits(zcu)) return src_id; | 5770 | if (!dst_child.hasRuntimeBits(zcu)) return src_id; |
| ... | @@ -5797,9 +5790,8 @@ fn bitCast( | ... | @@ -5797,9 +5790,8 @@ fn bitCast( |
| 5797 | } | 5790 | } |
| 5798 | const dst_ty_id = try cg.resolveType(dst_ty, .direct); | 5791 | const dst_ty_id = try cg.resolveType(dst_ty, .direct); |
| 5799 | return try cg.accessChain(dst_ty_id, src_id, indices.items); | 5792 | return try cg.accessChain(dst_ty_id, src_id, indices.items); |
| 5800 | }, | 5793 | } |
| 5801 | else => {}, | 5794 | } |
| 5802 | }; | ||
| 5803 | 5795 | ||
| 5804 | const dst_ty_id = try cg.resolveType(dst_ty, .direct); | 5796 | const dst_ty_id = try cg.resolveType(dst_ty, .direct); |
| 5805 | const result_id = blk: { | 5797 | const result_id = blk: { |
| ... | @@ -5836,13 +5828,11 @@ fn bitCast( | ... | @@ -5836,13 +5828,11 @@ fn bitCast( |
| 5836 | } | 5828 | } |
| 5837 | 5829 | ||
| 5838 | if (src_ty.zigTypeTag(zcu) == .int and dst_ty.isPtrAtRuntime(zcu)) { | 5830 | if (src_ty.zigTypeTag(zcu) == .int and dst_ty.isPtrAtRuntime(zcu)) { |
| 5839 | if (target.os.tag != .opencl) { | 5831 | if (target_util.addrSpaceIsLogical(target, dst_ty.ptrAddressSpace(zcu))) { |
| 5840 | if (dst_ty.ptrAddressSpace(zcu) != .physical_storage_buffer) { | 5832 | return cg.fail( |
| 5841 | return cg.fail( | 5833 | "cannot cast integer to pointer with address space '{s}'", |
| 5842 | "cannot cast integer to pointer with address space '{s}'", | 5834 | .{@tagName(dst_ty.ptrAddressSpace(zcu))}, |
| 5843 | .{@tagName(dst_ty.ptrAddressSpace(zcu))}, | 5835 | ); |
| 5844 | ); | ||
| 5845 | } | ||
| 5846 | } | 5836 | } |
| 5847 | 5837 | ||
| 5848 | const result_id = cg.allocId(); | 5838 | const result_id = cg.allocId(); |
| ... | @@ -5869,16 +5859,13 @@ fn bitCast( | ... | @@ -5869,16 +5859,13 @@ fn bitCast( |
| 5869 | break :blk result_id; | 5859 | break :blk result_id; |
| 5870 | } | 5860 | } |
| 5871 | 5861 | ||
| 5872 | switch (target.os.tag) { | 5862 | if (target_util.addrSpaceIsLogical(target, .local)) { |
| 5873 | .vulkan, .opengl => { | 5863 | // Logical addressing forbids OpBitcast on pointers. Allocate |
| 5874 | // Logical addressing forbids OpBitcast on pointers. Allocate | 5864 | // the temp with dst_ty so the load reads through a slot of the right type. |
| 5875 | // the temp with dst_ty so the load reads through a slot of the right type. | 5865 | const dst_ty_indirect_id = try cg.resolveType(dst_ty, .indirect); |
| 5876 | const dst_ty_indirect_id = try cg.resolveType(dst_ty, .indirect); | 5866 | const tmp_id = try cg.alloc(dst_ty_indirect_id, null); |
| 5877 | const tmp_id = try cg.alloc(dst_ty_indirect_id, null); | 5867 | try cg.store(dst_ty, tmp_id, src_id, .{}); |
| 5878 | try cg.store(dst_ty, tmp_id, src_id, .{}); | 5868 | break :blk try cg.load(dst_ty, tmp_id, .{}); |
| 5879 | break :blk try cg.load(dst_ty, tmp_id, .{}); | ||
| 5880 | }, | ||
| 5881 | else => {}, | ||
| 5882 | } | 5869 | } |
| 5883 | 5870 | ||
| 5884 | const dst_ptr_ty_id = try cg.ptrType(dst_ty_id, .function); | 5871 | const dst_ptr_ty_id = try cg.ptrType(dst_ty_id, .function); |
| ... | @@ -6463,7 +6450,7 @@ fn airSliceElemPtr(cg: *CodeGen, inst: Air.Inst.Index) !?Id { | ... | @@ -6463,7 +6450,7 @@ fn airSliceElemPtr(cg: *CodeGen, inst: Air.Inst.Index) !?Id { |
| 6463 | const ptr_ty_id = try cg.resolveType(ptr_ty, .direct); | 6450 | const ptr_ty_id = try cg.resolveType(ptr_ty, .direct); |
| 6464 | 6451 | ||
| 6465 | const slice_ptr = try cg.extractField(ptr_ty, slice_id, 0); | 6452 | const slice_ptr = try cg.extractField(ptr_ty, slice_id, 0); |
| 6466 | return try cg.ptrAccessChain(ptr_ty_id, slice_ptr, index_id, &.{}); | 6453 | return try cg.ptrAccessChain(ptr_ty.ptrAddressSpace(zcu), ptr_ty_id, slice_ptr, index_id, &.{}); |
| 6467 | } | 6454 | } |
| 6468 | 6455 | ||
| 6469 | fn airSliceElemVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id { | 6456 | fn airSliceElemVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id { |
| ... | @@ -6479,22 +6466,22 @@ fn airSliceElemVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id { | ... | @@ -6479,22 +6466,22 @@ fn airSliceElemVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id { |
| 6479 | const ptr_ty_id = try cg.resolveType(ptr_ty, .direct); | 6466 | const ptr_ty_id = try cg.resolveType(ptr_ty, .direct); |
| 6480 | 6467 | ||
| 6481 | const slice_ptr = try cg.extractField(ptr_ty, slice_id, 0); | 6468 | const slice_ptr = try cg.extractField(ptr_ty, slice_id, 0); |
| 6482 | const elem_ptr = try cg.ptrAccessChain(ptr_ty_id, slice_ptr, index_id, &.{}); | 6469 | const elem_ptr = try cg.ptrAccessChain(ptr_ty.ptrAddressSpace(zcu), ptr_ty_id, slice_ptr, index_id, &.{}); |
| 6483 | return try cg.load(slice_ty.childType(zcu), elem_ptr, .{ .is_volatile = slice_ty.isVolatilePtr(zcu) }); | 6470 | return try cg.load(slice_ty.childType(zcu), elem_ptr, .{ .is_volatile = slice_ty.isVolatilePtr(zcu) }); |
| 6484 | } | 6471 | } |
| 6485 | 6472 | ||
| 6486 | fn ptrElemPtr( | 6473 | fn ptrElemPtr( |
| 6487 | cg: *CodeGen, | 6474 | cg: *CodeGen, |
| 6488 | mode: enum { single_array_ptr, many_ptr }, | 6475 | mode: enum { single_array_ptr, many_ptr }, |
| 6489 | @"addrspace": std.lang.AddressSpace, | 6476 | as: std.lang.AddressSpace, |
| 6490 | elem_ty: Type, | 6477 | elem_ty: Type, |
| 6491 | ptr_id: Id, | 6478 | ptr_id: Id, |
| 6492 | index_id: Id, | 6479 | index_id: Id, |
| 6493 | ) !Id { | 6480 | ) !Id { |
| 6494 | // Construct new pointer type for the resulting pointer | 6481 | // Construct new pointer type for the resulting pointer |
| 6495 | const elem_is_block = cg.block_var_ids.contains(ptr_id); | 6482 | const elem_is_block = cg.block_var_ids.contains(ptr_id); |
| 6496 | const elem_ty_id = try cg.pointeeType(@"addrspace", elem_ty, elem_is_block); | 6483 | const elem_ty_id = try cg.pointeeType(as, elem_ty, elem_is_block); |
| 6497 | const elem_ptr_ty_id = try cg.ptrType(elem_ty_id, cg.storageClass(@"addrspace")); | 6484 | const elem_ptr_ty_id = try cg.ptrType(elem_ty_id, cg.storageClass(as)); |
| 6498 | switch (mode) { | 6485 | switch (mode) { |
| 6499 | .single_array_ptr => { | 6486 | .single_array_ptr => { |
| 6500 | // Pointer-to-array. In this case, the resulting pointer is not of the same type | 6487 | // Pointer-to-array. In this case, the resulting pointer is not of the same type |
| ... | @@ -6503,7 +6490,7 @@ fn ptrElemPtr( | ... | @@ -6503,7 +6490,7 @@ fn ptrElemPtr( |
| 6503 | }, | 6490 | }, |
| 6504 | .many_ptr => { | 6491 | .many_ptr => { |
| 6505 | // Resulting pointer type is the same as the ptr_ty, so use ptrAccessChain | 6492 | // Resulting pointer type is the same as the ptr_ty, so use ptrAccessChain |
| 6506 | return cg.ptrAccessChain(elem_ptr_ty_id, ptr_id, index_id, &.{}); | 6493 | return cg.ptrAccessChain(as, elem_ptr_ty_id, ptr_id, index_id, &.{}); |
| 6507 | }, | 6494 | }, |
| 6508 | } | 6495 | } |
| 6509 | } | 6496 | } |
| ... | @@ -6821,14 +6808,11 @@ fn airAggFieldVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id { | ... | @@ -6821,14 +6808,11 @@ fn airAggFieldVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id { |
| 6821 | return try cg.load(field_ty, pl_ptr_id, .{}); | 6808 | return try cg.load(field_ty, pl_ptr_id, .{}); |
| 6822 | } | 6809 | } |
| 6823 | 6810 | ||
| 6824 | switch (zcu.getTarget().os.tag) { | 6811 | if (target_util.addrSpaceIsLogical(zcu.getTarget(), .local)) { |
| 6825 | .vulkan, .opengl => { | 6812 | // Logical addressing forbids OpBitcast on pointers. Load the |
| 6826 | // Logical addressing forbids OpBitcast on pointers. Load the | 6813 | // payload as its type and bitcast the value instead. |
| 6827 | // payload as its type and bitcast the value instead. | 6814 | const payload_id = try cg.load(layout.payload_ty, pl_ptr_id, .{}); |
| 6828 | const payload_id = try cg.load(layout.payload_ty, pl_ptr_id, .{}); | 6815 | return try cg.bitCast(field_ty, layout.payload_ty, payload_id); |
| 6829 | return try cg.bitCast(field_ty, layout.payload_ty, payload_id); | ||
| 6830 | }, | ||
| 6831 | else => {}, | ||
| 6832 | } | 6816 | } |
| 6833 | 6817 | ||
| 6834 | const field_ty_id = try cg.resolveType(field_ty, .indirect); | 6818 | const field_ty_id = try cg.resolveType(field_ty, .indirect); |
| ... | @@ -6871,13 +6855,11 @@ fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) !?Id { | ... | @@ -6871,13 +6855,11 @@ fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) !?Id { |
| 6871 | break :base_ptr_int try result.materialize(cg); | 6855 | break :base_ptr_int try result.materialize(cg); |
| 6872 | }; | 6856 | }; |
| 6873 | 6857 | ||
| 6874 | if (target.os.tag != .opencl) { | 6858 | if (target_util.addrSpaceIsLogical(target, field_ptr_ty.ptrAddressSpace(zcu))) { |
| 6875 | if (field_ptr_ty.ptrAddressSpace(zcu) != .physical_storage_buffer) { | 6859 | return cg.fail( |
| 6876 | return cg.fail( | 6860 | "cannot cast integer to pointer with address space '{s}'", |
| 6877 | "cannot cast integer to pointer with address space '{s}'", | 6861 | .{@tagName(field_ptr_ty.ptrAddressSpace(zcu))}, |
| 6878 | .{@tagName(field_ptr_ty.ptrAddressSpace(zcu))}, | 6862 | ); |
| 6879 | ); | ||
| 6880 | } | ||
| 6881 | } | 6863 | } |
| 6882 | 6864 | ||
| 6883 | const base_ptr = cg.allocId(); | 6865 | const base_ptr = cg.allocId(); |
| ... | @@ -6892,7 +6874,7 @@ fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) !?Id { | ... | @@ -6892,7 +6874,7 @@ fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) !?Id { |
| 6892 | 6874 | ||
| 6893 | fn structFieldPtr( | 6875 | fn structFieldPtr( |
| 6894 | cg: *CodeGen, | 6876 | cg: *CodeGen, |
| 6895 | @"addrspace": std.lang.AddressSpace, | 6877 | as: std.lang.AddressSpace, |
| 6896 | result_ptr_ty_id: Id, | 6878 | result_ptr_ty_id: Id, |
| 6897 | field_ty: Type, | 6879 | field_ty: Type, |
| 6898 | object_ty: Type, | 6880 | object_ty: Type, |
| ... | @@ -6926,21 +6908,18 @@ fn structFieldPtr( | ... | @@ -6926,21 +6908,18 @@ fn structFieldPtr( |
| 6926 | return try cg.constUndef(result_ptr_ty_id); | 6908 | return try cg.constUndef(result_ptr_ty_id); |
| 6927 | } | 6909 | } |
| 6928 | 6910 | ||
| 6929 | const storage_class = cg.storageClass(@"addrspace"); | 6911 | const storage_class = cg.storageClass(as); |
| 6930 | if (field_ty.toIntern() == layout.payload_ty.toIntern()) { | 6912 | if (field_ty.toIntern() == layout.payload_ty.toIntern()) { |
| 6931 | if (object_ty.containerLayout(zcu) == .@"packed") return object_ptr; | 6913 | if (object_ty.containerLayout(zcu) == .@"packed") return object_ptr; |
| 6932 | return try cg.accessChain(result_ptr_ty_id, object_ptr, &.{layout.payload_index}); | 6914 | return try cg.accessChain(result_ptr_ty_id, object_ptr, &.{layout.payload_index}); |
| 6933 | } | 6915 | } |
| 6934 | 6916 | ||
| 6935 | switch (zcu.getTarget().os.tag) { | 6917 | if (target_util.addrSpaceIsLogical(zcu.getTarget(), as)) { |
| 6936 | .vulkan, .opengl => { | 6918 | // Logical addressing forbids OpBitcast on pointers. If the field |
| 6937 | // Logical addressing forbids OpBitcast on pointers. If the field | 6919 | // type is structurally identical to the payload type (dedup will |
| 6938 | // type is structurally identical to the payload type (dedup will | 6920 | // unify them) the access chain typed as the field type is valid. |
| 6939 | // unify them) the access chain typed as the field type is valid. | 6921 | if (object_ty.containerLayout(zcu) == .@"packed") return object_ptr; |
| 6940 | if (object_ty.containerLayout(zcu) == .@"packed") return object_ptr; | 6922 | return try cg.accessChain(result_ptr_ty_id, object_ptr, &.{layout.payload_index}); |
| 6941 | return try cg.accessChain(result_ptr_ty_id, object_ptr, &.{layout.payload_index}); | ||
| 6942 | }, | ||
| 6943 | else => {}, | ||
| 6944 | } | 6923 | } |
| 6945 | 6924 | ||
| 6946 | const layout_payload_ty_id = try cg.resolveType(layout.payload_ty, .indirect); | 6925 | const layout_payload_ty_id = try cg.resolveType(layout.payload_ty, .indirect); |
| ... | @@ -7039,18 +7018,13 @@ fn airAlloc(cg: *CodeGen, inst: Air.Inst.Index) !?Id { | ... | @@ -7039,18 +7018,13 @@ fn airAlloc(cg: *CodeGen, inst: Air.Inst.Index) !?Id { |
| 7039 | const ptr_ty = cg.typeOfIndex(inst); | 7018 | const ptr_ty = cg.typeOfIndex(inst); |
| 7040 | const child_ty = ptr_ty.childType(zcu); | 7019 | const child_ty = ptr_ty.childType(zcu); |
| 7041 | 7020 | ||
| 7042 | switch (target.os.tag) { | 7021 | if (child_ty.zigTypeTag(zcu) == .pointer and !child_ty.isSlice(zcu)) { |
| 7043 | .vulkan, .opengl => { | 7022 | const as = child_ty.ptrAddressSpace(zcu); |
| 7044 | if (child_ty.zigTypeTag(zcu) == .pointer and !child_ty.isSlice(zcu)) { | 7023 | if (target_util.addrSpaceIsLogical(target, as) and cg.storageClass(as) == .function) { |
| 7045 | const as = child_ty.ptrAddressSpace(zcu); | 7024 | const result_id = cg.allocId(); |
| 7046 | if (cg.storageClass(as) == .function) { | 7025 | try cg.tracked_allocas.put(cg.gpa, result_id, null); |
| 7047 | const result_id = cg.allocId(); | 7026 | return result_id; |
| 7048 | try cg.tracked_allocas.put(cg.gpa, result_id, null); | 7027 | } |
| 7049 | return result_id; | ||
| 7050 | } | ||
| 7051 | } | ||
| 7052 | }, | ||
| 7053 | else => {}, | ||
| 7054 | } | 7028 | } |
| 7055 | 7029 | ||
| 7056 | const child_ty_id = try cg.resolveType(child_ty, .indirect); | 7030 | const child_ty_id = try cg.resolveType(child_ty, .indirect); |
| ... | @@ -8790,6 +8764,7 @@ const log = std.log.scoped(.codegen); | ... | @@ -8790,6 +8764,7 @@ const log = std.log.scoped(.codegen); |
| 8790 | const builtin = @import("builtin"); | 8764 | const builtin = @import("builtin"); |
| 8791 | const link = @import("../../link.zig"); | 8765 | const link = @import("../../link.zig"); |
| 8792 | const codegen = @import("../../codegen.zig"); | 8766 | const codegen = @import("../../codegen.zig"); |
| 8767 | const target_util = @import("../../target.zig"); | ||
| 8793 | const Zcu = @import("../../Zcu.zig"); | 8768 | const Zcu = @import("../../Zcu.zig"); |
| 8794 | const Type = @import("../../Type.zig"); | 8769 | const Type = @import("../../Type.zig"); |
| 8795 | const Value = @import("../../Value.zig"); | 8770 | const Value = @import("../../Value.zig"); |
src/target.zig+22-32| ... | @@ -635,38 +635,28 @@ pub fn addrSpaceCastIsValid( | ... | @@ -635,38 +635,28 @@ pub fn addrSpaceCastIsValid( |
| 635 | } | 635 | } |
| 636 | } | 636 | } |
| 637 | 637 | ||
| 638 | /// Returns whether pointer operations (arithmetic, indexing, etc.) should be blocked | 638 | /// Returns true if the given address space memory model is logical (i.e. arithmetic pointer |
| 639 | /// for the given address space on the target architecture. | 639 | /// operations are illegal). |
| 640 | /// | 640 | pub fn addrSpaceIsLogical(target: *const std.Target, as: AddressSpace) bool { |
| 641 | /// Under SPIR-V with Vulkan | 641 | const features = &target.cpu.features; |
| 642 | /// (a) all physical pointers (.physical_storage_buffer, .global) always support pointer operations, | 642 | return switch (target.os.tag) { |
| 643 | /// (b) by default logical pointers (.constant, .input, .output, etc.) never support operations | 643 | .vulkan, .opengl => switch (as) { |
| 644 | /// (c) some logical pointers (.storage_buffer, .shared) do support operations when | 644 | .generic, |
| 645 | /// the VariablePointers capability is enabled (which enables OpPtrAccessChain). | 645 | .constant, |
| 646 | pub fn shouldBlockPointerOps(target: *const std.Target, as: AddressSpace) bool { | 646 | .local, |
| 647 | if (target.os.tag != .vulkan and target.os.tag != .opengl) return false; | 647 | .private, |
| 648 | 648 | .input, | |
| 649 | return switch (as) { | 649 | .output, |
| 650 | // TODO: Vulkan doesn't support pointers in the generic address space, we | 650 | .uniform, |
| 651 | // should remove this case but this requires a change in defaultAddressSpace(). | 651 | .push_constant, |
| 652 | .generic => true, | 652 | => true, |
| 653 | // For now, all global pointers are represented using StorageBuffer or CrossWorkgroup, | 653 | .shared => !features.isEnabled(@backingInt(std.Target.spirv.Feature.variable_pointers)), |
| 654 | // so these are real pointers. | 654 | .storage_buffer => !features.isEnabled(@backingInt(std.Target.spirv.Feature.variable_pointers)) and |
| 655 | // Physical pointers always support operations | 655 | !features.isEnabled(@backingInt(std.Target.spirv.Feature.variable_pointers_storage_buffer)), |
| 656 | .global, .physical_storage_buffer => false, | 656 | .physical_storage_buffer => false, |
| 657 | // Logical pointers that support operations with VariablePointers capability | 657 | else => unreachable, |
| 658 | .shared => !target.cpu.features.isEnabled(@backingInt(std.Target.spirv.Feature.variable_pointers)), | 658 | }, |
| 659 | .storage_buffer => !target.cpu.features.isEnabled(@backingInt(std.Target.spirv.Feature.variable_pointers)), | 659 | else => false, |
| 660 | // Logical pointers that never support operations | ||
| 661 | .constant, | ||
| 662 | .local, | ||
| 663 | .private, | ||
| 664 | .input, | ||
| 665 | .output, | ||
| 666 | .uniform, | ||
| 667 | .push_constant, | ||
| 668 | => true, | ||
| 669 | else => unreachable, | ||
| 670 | }; | 660 | }; |
| 671 | } | 661 | } |
| 672 | 662 |
test/behavior/abs.zig+1| ... | @@ -203,6 +203,7 @@ fn testAbsUnsignedBigInt() !void { | ... | @@ -203,6 +203,7 @@ fn testAbsUnsignedBigInt() !void { |
| 203 | test "@abs floats" { | 203 | test "@abs floats" { |
| 204 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 204 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 205 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 205 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 206 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // Fails on lavapipe | ||
| 206 | 207 | ||
| 207 | try comptime testAbsFloats(f16); | 208 | try comptime testAbsFloats(f16); |
| 208 | if (builtin.zig_backend != .stage2_riscv64) try testAbsFloats(f16); | 209 | if (builtin.zig_backend != .stage2_riscv64) try testAbsFloats(f16); |
test/behavior/bitcast.zig+2| ... | @@ -107,6 +107,7 @@ test "bitcast generates a temporary value" { | ... | @@ -107,6 +107,7 @@ test "bitcast generates a temporary value" { |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | test "@bitCast packed structs at runtime and comptime" { | 109 | test "@bitCast packed structs at runtime and comptime" { |
| 110 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 110 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 111 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 111 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 112 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 112 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 113 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -134,6 +135,7 @@ test "@bitCast packed structs at runtime and comptime" { | ... | @@ -134,6 +135,7 @@ test "@bitCast packed structs at runtime and comptime" { |
| 134 | } | 135 | } |
| 135 | 136 | ||
| 136 | test "bitcast packed struct to integer and back" { | 137 | test "bitcast packed struct to integer and back" { |
| 138 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 137 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 139 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 138 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 140 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 139 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 141 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/cast.zig+3-1| ... | @@ -273,6 +273,7 @@ test "type coercion from int to float" { | ... | @@ -273,6 +273,7 @@ test "type coercion from int to float" { |
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | test "@intFromFloat" { | 275 | test "@intFromFloat" { |
| 276 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 276 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 277 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 277 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 278 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 278 | 279 | ||
| ... | @@ -299,7 +300,6 @@ fn testIntFromFloats() !void { | ... | @@ -299,7 +300,6 @@ fn testIntFromFloats() !void { |
| 299 | 300 | ||
| 300 | try expectRoundCast(f32, -128.2, i8, -128); | 301 | try expectRoundCast(f32, -128.2, i8, -128); |
| 301 | try expectCeilCast(f32, -128.2, i8, -128); | 302 | try expectCeilCast(f32, -128.2, i8, -128); |
| 302 | try expectTruncCast(f32, -128.2, i8, -128); | ||
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | test "rounding builtins with anytype and context propagation" { | 305 | test "rounding builtins with anytype and context propagation" { |
| ... | @@ -3077,6 +3077,7 @@ test "peer type resolution: slice of sentinel-terminated array" { | ... | @@ -3077,6 +3077,7 @@ test "peer type resolution: slice of sentinel-terminated array" { |
| 3077 | 3077 | ||
| 3078 | test "@intFromFloat boundary cases" { | 3078 | test "@intFromFloat boundary cases" { |
| 3079 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 3079 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 3080 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 3080 | 3081 | ||
| 3081 | const S = struct { | 3082 | const S = struct { |
| 3082 | fn case(comptime I: type, x: f32, bump: enum { up, down }, expected: I) !void { | 3083 | fn case(comptime I: type, x: f32, bump: enum { up, down }, expected: I) !void { |
| ... | @@ -3107,6 +3108,7 @@ test "@intFromFloat boundary cases" { | ... | @@ -3107,6 +3108,7 @@ test "@intFromFloat boundary cases" { |
| 3107 | } | 3108 | } |
| 3108 | 3109 | ||
| 3109 | test "@intFromFloat vector boundary cases" { | 3110 | test "@intFromFloat vector boundary cases" { |
| 3111 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 3110 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 3112 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 3111 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 3113 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 3112 | 3114 |
test/behavior/enum.zig+1| ... | @@ -1217,6 +1217,7 @@ const bit_field_1 = BitFieldOfEnums{ | ... | @@ -1217,6 +1217,7 @@ const bit_field_1 = BitFieldOfEnums{ |
| 1217 | }; | 1217 | }; |
| 1218 | 1218 | ||
| 1219 | test "bit field access with enum fields" { | 1219 | test "bit field access with enum fields" { |
| 1220 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 1220 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1221 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1221 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 1222 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 1222 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1223 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/floatop.zig+4| ... | @@ -137,6 +137,7 @@ test "cmp f64" { | ... | @@ -137,6 +137,7 @@ test "cmp f64" { |
| 137 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 137 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 138 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isAarch64() and builtin.os.tag == .netbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/36765 | 138 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isAarch64() and builtin.os.tag == .netbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/36765 |
| 139 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isAarch64() and builtin.os.tag == .netbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/36765 | 139 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isAarch64() and builtin.os.tag == .netbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/36765 |
| 140 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // Fails on lavapipe | ||
| 140 | 141 | ||
| 141 | try testCmp(f64); | 142 | try testCmp(f64); |
| 142 | try comptime testCmp(f64); | 143 | try comptime testCmp(f64); |
| ... | @@ -247,6 +248,7 @@ test "vector cmp f64" { | ... | @@ -247,6 +248,7 @@ test "vector cmp f64" { |
| 247 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isAarch64() and builtin.os.tag == .netbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/36765 | 248 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isAarch64() and builtin.os.tag == .netbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/36765 |
| 248 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isAarch64() and builtin.os.tag == .netbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/36765 | 249 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isAarch64() and builtin.os.tag == .netbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/36765 |
| 249 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 250 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 251 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // Fails on lavapipe | ||
| 250 | 252 | ||
| 251 | try testCmpVector(f64); | 253 | try testCmpVector(f64); |
| 252 | try comptime testCmpVector(f64); | 254 | try comptime testCmpVector(f64); |
| ... | @@ -1024,6 +1026,7 @@ test "@abs f16" { | ... | @@ -1024,6 +1026,7 @@ test "@abs f16" { |
| 1024 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1026 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1025 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1027 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1026 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1028 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1029 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // Fails on lavapipe | ||
| 1027 | 1030 | ||
| 1028 | try testFabs(f16); | 1031 | try testFabs(f16); |
| 1029 | try comptime testFabs(f16); | 1032 | try comptime testFabs(f16); |
| ... | @@ -1032,6 +1035,7 @@ test "@abs f16" { | ... | @@ -1032,6 +1035,7 @@ test "@abs f16" { |
| 1032 | test "@abs f32/f64" { | 1035 | test "@abs f32/f64" { |
| 1033 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1036 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1034 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1037 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1038 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // Fails on lavapipe | ||
| 1035 | 1039 | ||
| 1036 | try testFabs(f32); | 1040 | try testFabs(f32); |
| 1037 | try comptime testFabs(f32); | 1041 | try comptime testFabs(f32); |
test/behavior/math.zig+1| ... | @@ -2613,6 +2613,7 @@ test "float vector multiplication of comptime zero by runtime nan is nan" { | ... | @@ -2613,6 +2613,7 @@ test "float vector multiplication of comptime zero by runtime nan is nan" { |
| 2613 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2613 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2614 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2614 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2615 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 2615 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 2616 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // Fails on lavapipe | ||
| 2616 | 2617 | ||
| 2617 | const ct_zero: @Vector(1, f32) = .{0}; | 2618 | const ct_zero: @Vector(1, f32) = .{0}; |
| 2618 | var rt_nan: @Vector(1, f32) = .{math.nan(f32)}; | 2619 | var rt_nan: @Vector(1, f32) = .{math.nan(f32)}; |
test/behavior/maximum_minimum.zig+1| ... | @@ -62,6 +62,7 @@ test "@min" { | ... | @@ -62,6 +62,7 @@ test "@min" { |
| 62 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 62 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 63 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 63 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 64 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 64 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 65 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // Fails on lavapipe | ||
| 65 | 66 | ||
| 66 | const S = struct { | 67 | const S = struct { |
| 67 | fn doTheTest() !void { | 68 | fn doTheTest() !void { |
test/behavior/memcpy.zig+2| ... | @@ -182,6 +182,8 @@ test "@memcpy no sentinel source into sentinel destination" { | ... | @@ -182,6 +182,8 @@ test "@memcpy no sentinel source into sentinel destination" { |
| 182 | } | 182 | } |
| 183 | 183 | ||
| 184 | test "@memcpy a global array" { | 184 | test "@memcpy a global array" { |
| 185 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 186 | |||
| 185 | const S = struct { | 187 | const S = struct { |
| 186 | var array_u8: [1]u8 = .{1}; | 188 | var array_u8: [1]u8 = .{1}; |
| 187 | const slice_u8: []u8 = &array_u8; | 189 | const slice_u8: []u8 = &array_u8; |
test/behavior/memmove.zig+2| ... | @@ -172,6 +172,8 @@ comptime { | ... | @@ -172,6 +172,8 @@ comptime { |
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | test "@memmove a global array" { | 174 | test "@memmove a global array" { |
| 175 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 176 | |||
| 175 | const S = struct { | 177 | const S = struct { |
| 176 | var array_u8: [1]u8 = .{1}; | 178 | var array_u8: [1]u8 = .{1}; |
| 177 | const slice_u8: []u8 = &array_u8; | 179 | const slice_u8: []u8 = &array_u8; |
test/behavior/packed-struct.zig+10| ... | @@ -225,6 +225,7 @@ test "nested packed structs" { | ... | @@ -225,6 +225,7 @@ test "nested packed structs" { |
| 225 | } | 225 | } |
| 226 | 226 | ||
| 227 | test "regular in irregular packed struct" { | 227 | test "regular in irregular packed struct" { |
| 228 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 228 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 229 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 229 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 230 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 230 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 231 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| ... | @@ -792,6 +793,7 @@ test "nested packed struct at non-zero offset 2" { | ... | @@ -792,6 +793,7 @@ test "nested packed struct at non-zero offset 2" { |
| 792 | } | 793 | } |
| 793 | 794 | ||
| 794 | test "runtime init of unnamed packed struct type" { | 795 | test "runtime init of unnamed packed struct type" { |
| 796 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 795 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 797 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 796 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 798 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 797 | 799 | ||
| ... | @@ -885,6 +887,7 @@ test "pointer to container level packed struct field" { | ... | @@ -885,6 +887,7 @@ test "pointer to container level packed struct field" { |
| 885 | } | 887 | } |
| 886 | 888 | ||
| 887 | test "store undefined to packed result location" { | 889 | test "store undefined to packed result location" { |
| 890 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 888 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 891 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 889 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 892 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 890 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 893 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| ... | @@ -907,6 +910,7 @@ test "bitcast back and forth" { | ... | @@ -907,6 +910,7 @@ test "bitcast back and forth" { |
| 907 | 910 | ||
| 908 | // Originally reported at https://github.com/ziglang/zig/issues/14200 | 911 | // Originally reported at https://github.com/ziglang/zig/issues/14200 |
| 909 | test "field access of packed struct smaller than its abi size inside struct initialized with rls" { | 912 | test "field access of packed struct smaller than its abi size inside struct initialized with rls" { |
| 913 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 910 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 914 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 911 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO | 915 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 912 | 916 | ||
| ... | @@ -1001,6 +1005,7 @@ test "packed struct acts as a namespace" { | ... | @@ -1001,6 +1005,7 @@ test "packed struct acts as a namespace" { |
| 1001 | } | 1005 | } |
| 1002 | 1006 | ||
| 1003 | test "assignment to non-byte-aligned field in packed struct" { | 1007 | test "assignment to non-byte-aligned field in packed struct" { |
| 1008 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 1004 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1009 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1005 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1010 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1006 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO | 1011 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| ... | @@ -1039,6 +1044,7 @@ test "packed struct field pointer aligned properly" { | ... | @@ -1039,6 +1044,7 @@ test "packed struct field pointer aligned properly" { |
| 1039 | } | 1044 | } |
| 1040 | 1045 | ||
| 1041 | test "load flag from packed struct in union" { | 1046 | test "load flag from packed struct in union" { |
| 1047 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 1042 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1048 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1043 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1049 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1044 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1050 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -1162,6 +1168,7 @@ test "packed struct equality" { | ... | @@ -1162,6 +1168,7 @@ test "packed struct equality" { |
| 1162 | } | 1168 | } |
| 1163 | 1169 | ||
| 1164 | test "packed struct equality ignores padding bits" { | 1170 | test "packed struct equality ignores padding bits" { |
| 1171 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 1165 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1172 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1166 | 1173 | ||
| 1167 | const S = packed struct { b: bool }; | 1174 | const S = packed struct { b: bool }; |
| ... | @@ -1172,6 +1179,7 @@ test "packed struct equality ignores padding bits" { | ... | @@ -1172,6 +1179,7 @@ test "packed struct equality ignores padding bits" { |
| 1172 | } | 1179 | } |
| 1173 | 1180 | ||
| 1174 | test "packed struct with signed field" { | 1181 | test "packed struct with signed field" { |
| 1182 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 1175 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1183 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1176 | 1184 | ||
| 1177 | var s: packed struct { | 1185 | var s: packed struct { |
| ... | @@ -1184,6 +1192,7 @@ test "packed struct with signed field" { | ... | @@ -1184,6 +1192,7 @@ test "packed struct with signed field" { |
| 1184 | } | 1192 | } |
| 1185 | 1193 | ||
| 1186 | test "assign packed struct initialized with RLS to packed struct literal field" { | 1194 | test "assign packed struct initialized with RLS to packed struct literal field" { |
| 1195 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 1187 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1196 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1188 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1197 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1189 | 1198 | ||
| ... | @@ -1200,6 +1209,7 @@ test "assign packed struct initialized with RLS to packed struct literal field" | ... | @@ -1200,6 +1209,7 @@ test "assign packed struct initialized with RLS to packed struct literal field" |
| 1200 | } | 1209 | } |
| 1201 | 1210 | ||
| 1202 | test "packed struct store of comparison result" { | 1211 | test "packed struct store of comparison result" { |
| 1212 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 1203 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1213 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1204 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO | 1214 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 1205 | 1215 |
test/behavior/struct.zig+6| ... | @@ -376,6 +376,7 @@ const APackedStruct = packed struct { | ... | @@ -376,6 +376,7 @@ const APackedStruct = packed struct { |
| 376 | }; | 376 | }; |
| 377 | 377 | ||
| 378 | test "packed struct" { | 378 | test "packed struct" { |
| 379 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 379 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 380 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 380 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 381 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 381 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 382 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| ... | @@ -502,6 +503,7 @@ test "packed struct fields are ordered from LSB to MSB" { | ... | @@ -502,6 +503,7 @@ test "packed struct fields are ordered from LSB to MSB" { |
| 502 | } | 503 | } |
| 503 | 504 | ||
| 504 | test "implicit cast packed struct field to const ptr" { | 505 | test "implicit cast packed struct field to const ptr" { |
| 506 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 505 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 507 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 506 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 508 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 507 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 509 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -564,6 +566,7 @@ const bit_field_1 = BitField1{ | ... | @@ -564,6 +566,7 @@ const bit_field_1 = BitField1{ |
| 564 | }; | 566 | }; |
| 565 | 567 | ||
| 566 | test "bit field access" { | 568 | test "bit field access" { |
| 569 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 567 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 570 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 568 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 571 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 569 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 572 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -686,6 +689,7 @@ const FooArrayOfAligned = packed struct { | ... | @@ -686,6 +689,7 @@ const FooArrayOfAligned = packed struct { |
| 686 | }; | 689 | }; |
| 687 | 690 | ||
| 688 | test "pointer to packed struct member in a stack variable" { | 691 | test "pointer to packed struct member in a stack variable" { |
| 692 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 689 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 693 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 690 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 694 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 691 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 695 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -815,6 +819,7 @@ test "non-packed struct with u128 entry in union" { | ... | @@ -815,6 +819,7 @@ test "non-packed struct with u128 entry in union" { |
| 815 | } | 819 | } |
| 816 | 820 | ||
| 817 | test "packed struct field passed to generic function" { | 821 | test "packed struct field passed to generic function" { |
| 822 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 818 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 823 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 819 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 824 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 820 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 825 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1197,6 +1202,7 @@ test "packed struct aggregate init" { | ... | @@ -1197,6 +1202,7 @@ test "packed struct aggregate init" { |
| 1197 | } | 1202 | } |
| 1198 | 1203 | ||
| 1199 | test "packed struct field access via pointer" { | 1204 | test "packed struct field access via pointer" { |
| 1205 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 1200 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1206 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1201 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1207 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1202 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1208 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/switch.zig+2| ... | @@ -1671,6 +1671,8 @@ test "union field pointer capture preserves alignment in inline prong" { | ... | @@ -1671,6 +1671,8 @@ test "union field pointer capture preserves alignment in inline prong" { |
| 1671 | } | 1671 | } |
| 1672 | 1672 | ||
| 1673 | test "switch on expression" { | 1673 | test "switch on expression" { |
| 1674 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 1675 | |||
| 1674 | var a: []const []const u8 = &.{ "b", "b", "A", "A", "b" }; | 1676 | var a: []const []const u8 = &.{ "b", "b", "A", "A", "b" }; |
| 1675 | _ = &a; | 1677 | _ = &a; |
| 1676 | var c: isize = 0; | 1678 | var c: isize = 0; |
test/cases/compile_errors/spirv_slices.zig+2-4| ... | @@ -19,7 +19,5 @@ export fn b() void { | ... | @@ -19,7 +19,5 @@ export fn b() void { |
| 19 | // target=spirv32-opengl,spirv32-vulkan | 19 | // target=spirv32-opengl,spirv32-vulkan |
| 20 | // cpu_features=baseline+variable_pointers | 20 | // cpu_features=baseline+variable_pointers |
| 21 | // | 21 | // |
| 22 | // :3:16: error: cannot construct slice from address space 'generic' | 22 | // :3:16: error: cannot construct slice from logical address space 'generic' |
| 23 | // :3:16: note: only 'shared' and 'storage_buffer' address spaces support slicing on SPIR-V | 23 | // :14:11: error: cannot construct slice from logical address space 'generic' |
| 24 | // :14:11: error: cannot construct slice from address space 'generic' | ||
| 25 | // :14:11: note: only 'shared' and 'storage_buffer' address spaces support slicing on SPIR-V |
test/cases/spirv_mergable_pointers.zig+3-3| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | export fn a() void { | 1 | export fn a() void { |
| 2 | var x: *addrspace(.global) i32 = undefined; | 2 | var x: *addrspace(.physical_storage_buffer) i32 = undefined; |
| 3 | _ = &x; | 3 | _ = &x; |
| 4 | var y: *addrspace(.global) i32 = undefined; | 4 | var y: *addrspace(.physical_storage_buffer) i32 = undefined; |
| 5 | _ = &y; | 5 | _ = &y; |
| 6 | var rt_cond = false; | 6 | var rt_cond = false; |
| 7 | _ = &rt_cond; | 7 | _ = &rt_cond; |
| ... | @@ -13,5 +13,5 @@ export fn a() void { | ... | @@ -13,5 +13,5 @@ export fn a() void { |
| 13 | // compile | 13 | // compile |
| 14 | // output_mode=Obj | 14 | // output_mode=Obj |
| 15 | // backend=selfhosted | 15 | // backend=selfhosted |
| 16 | // target=spirv32-vulkan | 16 | // target=spirv64-vulkan |
| 17 | // emit_bin=true | 17 | // emit_bin=true |