Sema: avoid ptr_add/ptr_sub instructions void elem type

This commit is contained in:
Andrew Kelley 2025-09-08 18:44:50 -07:00
parent aacff8c800
commit c0bbddb007
2 changed files with 23 additions and 13 deletions

View File

@ -166,19 +166,25 @@ pub const Inst = struct {
mod, mod,
/// Same as `mod` with optimized float mode. /// Same as `mod` with optimized float mode.
mod_optimized, mod_optimized,
/// Add an offset to a pointer, returning a new pointer. /// Add an offset, in element type units, to a pointer, returning a new
/// The offset is in element type units, not bytes. /// pointer. Element type may not be zero bits.
/// Wrapping is illegal behavior. ///
/// The lhs is the pointer, rhs is the offset. Result type is the same as lhs. /// Wrapping is illegal behavior. If the newly computed address is
/// The pointer may be a slice. /// outside the provenance of the operand, the result is undefined.
/// Uses the `ty_pl` field. Payload is `Bin`. ///
/// Uses the `ty_pl` field. Payload is `Bin`. The lhs is the pointer,
/// rhs is the offset. Result type is the same as lhs. The operand may
/// be a slice.
ptr_add, ptr_add,
/// Subtract an offset from a pointer, returning a new pointer. /// Subtract an offset, in element type units, from a pointer,
/// The offset is in element type units, not bytes. /// returning a new pointer. Element type may not be zero bits.
/// Wrapping is illegal behavior. ///
/// The lhs is the pointer, rhs is the offset. Result type is the same as lhs. /// Wrapping is illegal behavior. If the newly computed address is
/// The pointer may be a slice. /// outside the provenance of the operand, the result is undefined.
/// Uses the `ty_pl` field. Payload is `Bin`. ///
/// Uses the `ty_pl` field. Payload is `Bin`. The lhs is the pointer,
/// rhs is the offset. Result type is the same as lhs. The operand may
/// be a slice.
ptr_sub, ptr_sub,
/// Given two operands which can be floats, integers, or vectors, returns the /// Given two operands which can be floats, integers, or vectors, returns the
/// greater of the operands. For vectors it operates element-wise. /// greater of the operands. For vectors it operates element-wise.

View File

@ -16002,7 +16002,6 @@ fn splat(sema: *Sema, ty: Type, val: Value) !Value {
fn analyzeArithmetic( fn analyzeArithmetic(
sema: *Sema, sema: *Sema,
block: *Block, block: *Block,
/// TODO performance investigation: make this comptime?
zir_tag: Zir.Inst.Tag, zir_tag: Zir.Inst.Tag,
lhs: Air.Inst.Ref, lhs: Air.Inst.Ref,
rhs: Air.Inst.Ref, rhs: Air.Inst.Ref,
@ -16201,6 +16200,11 @@ fn analyzePtrArithmetic(
const ptr_info = ptr_ty.ptrInfo(zcu); const ptr_info = ptr_ty.ptrInfo(zcu);
assert(ptr_info.flags.size == .many or ptr_info.flags.size == .c); assert(ptr_info.flags.size == .many or ptr_info.flags.size == .c);
if ((try sema.typeHasOnePossibleValue(.fromInterned(ptr_info.child))) != null) {
// Offset will be multiplied by zero, so result is the same as the base pointer.
return ptr;
}
const new_ptr_ty = t: { const new_ptr_ty = t: {
// Calculate the new pointer alignment. // Calculate the new pointer alignment.
// This code is duplicated in `Type.elemPtrType`. // This code is duplicated in `Type.elemPtrType`.