From 23e69f7c5766c46c2b699762642f7134d916e515 Mon Sep 17 00:00:00 2001 From: David Senoner Date: Thu, 3 Sep 2026 00:45:19 +0200 Subject: [PATCH] compiler: add `expand_ptr_elem_val` legalization creates a block in place of the old ptr_elem_val air instruction and in the block adds ptr_elem_ptr and load air instructions --- src/Air/Legalize.zig | 46 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/Air/Legalize.zig b/src/Air/Legalize.zig index 28fe9faf04c981155dd41c997784f7fba1baa972..838e0fe989fa984e0cff4981cb69f9fe9fd6fb27 100644 --- a/src/Air/Legalize.zig +++ b/src/Air/Legalize.zig @@ -204,6 +204,8 @@ pub const Feature = enum { expand_array_splat, /// Replace `array_to_vector` with an `array_elem_val` per element followed by an `aggregate_init`. expand_array_to_vector, + /// Replace `ptr_elem_val` with an `ptr_elem_ptr` followed by a `load`. + expand_ptr_elem_val, /// Replace all arithmetic operations on 16-bit floating-point types with calls to soft-float /// routines in compiler_rt, including `fptrunc`/`fpext`/`float_from_int`/`int_from_float` @@ -863,10 +865,12 @@ fn legalizeBody(l: *Legalize, body_start: usize, body_len: usize) Error!void { .array_elem_val, .slice_elem_val, .slice_elem_ptr, - .ptr_elem_val, .ptr_elem_ptr, .array_to_slice, => {}, + .ptr_elem_val => if (l.features.has(.expand_ptr_elem_val)) { + continue :inst l.replaceInst(inst, .block, try l.ptrElemValBlockPayload(inst)); + }, .array_to_vector => if (l.features.has(.expand_array_to_vector)) { continue :inst l.replaceInst(inst, .block, try l.arrayToVectorBlockPayload(inst)); }, @@ -2973,6 +2977,46 @@ fn packedAggregateInitBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Erro } }; } +fn ptrElemValBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Error!Air.Inst.Data { + const pt = l.pt; + const zcu = pt.zcu; + const gpa = zcu.gpa; + + const orig_bin_op = l.air_instructions.items(.data)[@backingInt(orig_inst)].bin_op; + + const ptr_val = orig_bin_op.lhs; + const ptr_ty = try l.typeOf(ptr_val).elemPtrType(null, pt); + const val_ty = ptr_ty.childType(zcu); + + var inst_buf: [3]Air.Inst.Index = undefined; + var main_block: Block = .init(&inst_buf); + try l.air_instructions.ensureUnusedCapacity(gpa, inst_buf.len); + + const ptr = main_block.add(l, .{ + .tag = .ptr_elem_ptr, + .data = .{ + .ty_pl = .{ + .ty = ptr_ty, + .payload = try l.addExtra(Air.Bin, .{ + .lhs = ptr_val, + .rhs = orig_bin_op.rhs, + }), + }, + }, + }).toRef(); + + const val = main_block.addTyOp(l, .load, val_ty, ptr).toRef(); + + main_block.addBr(l, orig_inst, val); + + return .{ + .ty_pl = .{ + .ty = val_ty, + .payload = try l.addBlockBody(main_block.body()), + }, + }; +} + fn arrayToVectorBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Error!Air.Inst.Data { const pt = l.pt; const zcu = pt.zcu; -- 2.54.0