Commit 64f99f36a6

Robin Voetter <robin@voetter.nl>
2023-05-18 19:25:52
spirv: ptr_add
Implements the ptr_add air tag for spirv. The implementation for slices is probably wrong, but there seems to be no test for this...
1 parent 3c14438
Changed files (2)
src
codegen
test
behavior
src/codegen/spirv.zig
@@ -1738,6 +1738,8 @@ pub const DeclGen = struct {
 
             .shuffle => try self.airShuffle(inst),
 
+            .ptr_add => try self.airPtrAdd(inst),
+
             .bit_and  => try self.airBinOpSimple(inst, .OpBitwiseAnd),
             .bit_or   => try self.airBinOpSimple(inst, .OpBitwiseOr),
             .xor      => try self.airBinOpSimple(inst, .OpBitwiseXor),
@@ -2120,6 +2122,33 @@ pub const DeclGen = struct {
         return result_id;
     }
 
+    fn airPtrAdd(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
+        if (self.liveness.isUnused(inst)) return null;
+        const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
+        const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
+        const ptr_id = try self.resolve(bin_op.lhs);
+        const offset_id = try self.resolve(bin_op.rhs);
+        const ptr_ty = self.air.typeOf(bin_op.lhs);
+        const result_ty = self.air.typeOfIndex(inst);
+        const result_ty_ref = try self.resolveType(result_ty, .direct);
+
+        switch (ptr_ty.ptrSize()) {
+            .One => {
+                // Pointer to array
+                // TODO: Is this correct?
+                return try self.accessChain(result_ty_ref, ptr_id, &.{offset_id});
+            },
+            .C, .Many => {
+                return try self.ptrAccessChain(result_ty_ref, ptr_id, offset_id, &.{});
+            },
+            .Slice => {
+                // TODO: This is probably incorrect. A slice should be returned here, though this is what llvm does.
+                const slice_ptr_id = try self.extractField(result_ty, ptr_id, 0);
+                return try self.ptrAccessChain(result_ty_ref, slice_ptr_id, offset_id, &.{});
+            },
+        }
+    }
+
     fn cmp(
         self: *DeclGen,
         comptime op: std.math.CompareOperator,
test/behavior/basic.zig
@@ -751,7 +751,6 @@ fn maybe(x: bool) anyerror!?u32 {
 test "auto created variables have correct alignment" {
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
-    if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
 
     const S = struct {
         fn foo(str: [*]const u8) u32 {