authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-09-08 18:44:50-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-09-20 18:33:00-07:00
logc0bbddb0071830eb9a6afd96124a24176f263b6a
tree8e6e0becec62a8ab058db2b6cd3f9515f16750e2
parentaacff8c80091c0187057e65d96108f46962f98a3

Sema: avoid ptr_add/ptr_sub instructions void elem type


2 files changed, 23 insertions(+), 13 deletions(-)

src/Air.zig+18-12
......@@ -166,19 +166,25 @@ pub const Inst = struct {
166166 mod,
167167 /// Same as `mod` with optimized float mode.
168168 mod_optimized,
169 /// Add an offset to a pointer, returning a new pointer.
170 /// The offset is in element type units, not bytes.
171 /// Wrapping is illegal behavior.
172 /// The lhs is the pointer, rhs is the offset. Result type is the same as lhs.
173 /// The pointer may be a slice.
174 /// Uses the `ty_pl` field. Payload is `Bin`.
169 /// Add an offset, in element type units, to a pointer, returning a new
170 /// pointer. Element type may not be zero bits.
171 ///
172 /// Wrapping is illegal behavior. If the newly computed address is
173 /// outside the provenance of the operand, the result is undefined.
174 ///
175 /// Uses the `ty_pl` field. Payload is `Bin`. The lhs is the pointer,
176 /// rhs is the offset. Result type is the same as lhs. The operand may
177 /// be a slice.
175178 ptr_add,
176 /// Subtract an offset from a pointer, returning a new pointer.
177 /// The offset is in element type units, not bytes.
178 /// Wrapping is illegal behavior.
179 /// The lhs is the pointer, rhs is the offset. Result type is the same as lhs.
180 /// The pointer may be a slice.
181 /// Uses the `ty_pl` field. Payload is `Bin`.
179 /// Subtract an offset, in element type units, from a pointer,
180 /// returning a new pointer. Element type may not be zero bits.
181 ///
182 /// Wrapping is illegal behavior. If the newly computed address is
183 /// outside the provenance of the operand, the result is undefined.
184 ///
185 /// Uses the `ty_pl` field. Payload is `Bin`. The lhs is the pointer,
186 /// rhs is the offset. Result type is the same as lhs. The operand may
187 /// be a slice.
182188 ptr_sub,
183189 /// Given two operands which can be floats, integers, or vectors, returns the
184190 /// greater of the operands. For vectors it operates element-wise.
src/Sema.zig+5-1
......@@ -16002,7 +16002,6 @@ fn splat(sema: *Sema, ty: Type, val: Value) !Value {
1600216002fn analyzeArithmetic(
1600316003 sema: *Sema,
1600416004 block: *Block,
16005 /// TODO performance investigation: make this comptime?
1600616005 zir_tag: Zir.Inst.Tag,
1600716006 lhs: Air.Inst.Ref,
1600816007 rhs: Air.Inst.Ref,
......@@ -16201,6 +16200,11 @@ fn analyzePtrArithmetic(
1620116200 const ptr_info = ptr_ty.ptrInfo(zcu);
1620216201 assert(ptr_info.flags.size == .many or ptr_info.flags.size == .c);
1620316202
16203 if ((try sema.typeHasOnePossibleValue(.fromInterned(ptr_info.child))) != null) {
16204 // Offset will be multiplied by zero, so result is the same as the base pointer.
16205 return ptr;
16206 }
16207
1620416208 const new_ptr_ty = t: {
1620516209 // Calculate the new pointer alignment.
1620616210 // This code is duplicated in `Type.elemPtrType`.