authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-04-10 18:34:30+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-05-11 20:31:50+02:00
logdfecf89d06dc2caad41ff54b05240506ea2c47e8
tree46cb08a073d4e346188fc2c323d7b3dede446144
parent5d896a6cc6b7127dd4db0bd386ebe33da82d7824
signaturelock-open Commit is signed but in an unrecognized format.

spirv: fix OpFunctionCall parameters interleaving with insts

resolve() is now able to emit instructions. If usage of this function is interleaved with calls to emitRaw() and writeOperand(), then an instruction may get inserted between operands, causing an invalid module. The solution here is to just perform a temporary allocation.

1 files changed, 15 insertions(+), 5 deletions(-)

src/codegen/spirv.zig+15-5
......@@ -2717,19 +2717,29 @@ pub const DeclGen = struct {
27172717 const result_id = self.spv.allocId();
27182718 const callee_id = try self.resolve(pl_op.operand);
27192719
2720 try self.func.body.emitRaw(self.spv.gpa, .OpFunctionCall, 3 + args.len);
2721 self.func.body.writeOperand(spec.IdResultType, result_type_id);
2722 self.func.body.writeOperand(spec.IdResult, result_id);
2723 self.func.body.writeOperand(spec.IdRef, callee_id);
2720 const params = try self.gpa.alloc(spec.IdRef, args.len);
2721 defer self.gpa.free(params);
27242722
2723 var n_params: usize = 0;
27252724 for (args) |arg| {
2725 // Note: resolve() might emit instructions, so we need to call it
2726 // before starting to emit OpFunctionCall instructions. Hence the
2727 // temporary params buffer.
27262728 const arg_id = try self.resolve(arg);
27272729 const arg_ty = self.air.typeOf(arg);
27282730 if (!arg_ty.hasRuntimeBitsIgnoreComptime()) continue;
27292731
2730 self.func.body.writeOperand(spec.IdRef, arg_id);
2732 params[n_params] = arg_id;
2733 n_params += 1;
27312734 }
27322735
2736 try self.func.body.emit(self.spv.gpa, .OpFunctionCall, .{
2737 .id_result_type = result_type_id,
2738 .id_result = result_id,
2739 .function = callee_id,
2740 .id_ref_3 = params[0..n_params],
2741 });
2742
27332743 if (return_type.isNoReturn()) {
27342744 try self.func.body.emit(self.spv.gpa, .OpUnreachable, {});
27352745 }