From ae8532e95c36d8257245759659b40e1e0878ff05 Mon Sep 17 00:00:00 2001 From: Gabriel Sa Date: Wed, 23 Sep 2026 21:22:58 +0200 Subject: [PATCH] Legalize: add `expand_array_to_slice` legalization (#36818) see #36719 tried to follow the style of the existing legalizations tested with `stage4/bin/zig build test -Dskip-release -Dskip-non-native` Reviewed-on: https://codeberg.org/ziglang/zig/pulls/36818 Reviewed-by: Justus Klausecker --- src/Air/Legalize.zig | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/Air/Legalize.zig b/src/Air/Legalize.zig index 838e0fe989fa984e0cff4981cb69f9fe9fd6fb27..99dc64577b09583bcdf4f8a51b8efe9ff42c749c 100644 --- a/src/Air/Legalize.zig +++ b/src/Air/Legalize.zig @@ -206,6 +206,8 @@ pub const Feature = enum { expand_array_to_vector, /// Replace `ptr_elem_val` with an `ptr_elem_ptr` followed by a `load`. expand_ptr_elem_val, + /// Replace `array_to_slice` with a `ptr_cast` followed by a `slice`. + expand_array_to_slice, /// 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` @@ -866,7 +868,6 @@ fn legalizeBody(l: *Legalize, body_start: usize, body_len: usize) Error!void { .slice_elem_val, .slice_elem_ptr, .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)); @@ -874,6 +875,9 @@ fn legalizeBody(l: *Legalize, body_start: usize, body_len: usize) Error!void { .array_to_vector => if (l.features.has(.expand_array_to_vector)) { continue :inst l.replaceInst(inst, .block, try l.arrayToVectorBlockPayload(inst)); }, + .array_to_slice => if (l.features.has(.expand_array_to_slice)) { + continue :inst l.replaceInst(inst, .block, try l.arrayToSliceBlockPayload(inst)); + }, inline .reduce, .reduce_optimized => |air_tag| { const reduce = l.air_instructions.items(.data)[@backingInt(inst)].reduce; const vector_ty = l.typeOf(reduce.operand); @@ -3059,6 +3063,42 @@ fn arrayToVectorBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Error!Air. } }; } +fn arrayToSliceBlockPayload(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_ty_op = l.air_instructions.items(.data)[@backingInt(orig_inst)].ty_op; + + const slice_ty = orig_ty_op.ty; + const ptr_ty = slice_ty.slicePtrFieldType(zcu); + + const array_ptr_ty = l.typeOf(orig_ty_op.operand); + const len = array_ptr_ty.childType(zcu).arrayLen(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.addPtrCast(l, ptr_ty, orig_ty_op.operand); + const result = main_block.add(l, .{ + .tag = .slice, + .data = .{ .ty_pl = .{ + .ty = slice_ty, + .payload = try l.addExtra(Air.Bin, .{ + .lhs = ptr, + .rhs = try pt.intRef(.usize, len), + }), + } }, + }).toRef(); + + main_block.addBr(l, orig_inst, result); + return .{ .ty_pl = .{ + .ty = slice_ty, + .payload = try l.addBlockBody(main_block.body()), + } }; +} + /// Given a `std.math.big.int.Const`, converts it to a `Value` which is a float of type `float_ty` /// representing the same numeric value. If the integer cannot be exactly represented, `round` /// decides whether the value should be rounded up or down. If `is_vector`, then `float_ty` is -- 2.54.0