Skip to content

Commit 3820e74

Browse files
committed
intrinsics: use -one(T) instead of -1 for signed AND identity
Ensures type-consistent encoding for Int8, Int16, etc. intrinsics: use type-dependent identity values for reduce ops - add: zero(T) - max: typemin(T) - mul: one(T) - min: typemax(T) - and: is_signed ? -1 : typemax(T) for proper bit representation - or, xor: zero(T) Fixes encoding error for UInt32 (9223372036854775807 does not fit in 32 bits) Update core.jl fix reduce_min identity to use typemax(T) instead of typemax(Int64) - For UInt32, typemax(UInt32) = 4294967295 fits in 32 bits - typemax(Int64) = 9223372036854775807 does not fit and caused encoding error
1 parent 68db6d2 commit 3820e74

1 file changed

Lines changed: 16 additions & 14 deletions

File tree

src/compiler/intrinsics/core.jl

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -682,39 +682,41 @@ Identity must satisfy: identity ⊕ x = x for the operation.
682682
"""
683683
# Addition identity: 0 + x = x
684684
reduce_identity(::Val{:add}, dtype, ::Type{T}) where T <: AbstractFloat =
685-
FloatIdentityOp(0.0, dtype, T)
685+
FloatIdentityOp(zero(T), dtype, T)
686686
reduce_identity(::Val{:add}, dtype, ::Type{T}) where T <: Integer =
687-
IntegerIdentityOp(0, dtype, T, is_signed(T))
687+
IntegerIdentityOp(zero(T), dtype, T, is_signed(T))
688688

689-
# Maximum identity: max(-Inf, x) = x
689+
# Maximum identity: max(typemin(T), x) = x
690690
reduce_identity(::Val{:max}, dtype, ::Type{T}) where T <: AbstractFloat =
691-
FloatIdentityOp(-Inf, dtype, T)
691+
FloatIdentityOp(typemin(T), dtype, T)
692692
reduce_identity(::Val{:max}, dtype, ::Type{T}) where T <: Integer =
693-
IntegerIdentityOp(0, dtype, T, is_signed(T)) # For integers, use 0 as identity (max(0, x) = x)
693+
IntegerIdentityOp(typemin(T), dtype, T, is_signed(T))
694694

695695
# Multiplication identity: 1 * x = x
696696
reduce_identity(::Val{:mul}, dtype, ::Type{T}) where T <: AbstractFloat =
697-
FloatIdentityOp(1.0, dtype, T)
697+
FloatIdentityOp(one(T), dtype, T)
698698
reduce_identity(::Val{:mul}, dtype, ::Type{T}) where T <: Integer =
699-
IntegerIdentityOp(1, dtype, T, is_signed(T))
699+
IntegerIdentityOp(one(T), dtype, T, is_signed(T))
700700

701-
# Minimum identity: min(+Inf, x) = x
701+
# Minimum identity: min(typemax(T), x) = x
702702
reduce_identity(::Val{:min}, dtype, ::Type{T}) where T <: AbstractFloat =
703-
FloatIdentityOp(+Inf, dtype, T)
703+
FloatIdentityOp(typemax(T), dtype, T)
704704
reduce_identity(::Val{:min}, dtype, ::Type{T}) where T <: Integer =
705-
IntegerIdentityOp(typemax(Int64), dtype, T, is_signed(T)) # Use max int as +Inf proxy
705+
IntegerIdentityOp(typemax(T), dtype, T, is_signed(T))
706706

707-
# AND identity: all bits set (x & -1 == x)
707+
# AND identity: all bits set (x & identity == x)
708+
# For signed: -one(T) has all bits set in two's complement
709+
# For unsigned: typemax(T) has all bits set
708710
reduce_identity(::Val{:and}, dtype, ::Type{T}) where T <: Integer =
709-
IntegerIdentityOp(-1, dtype, T, is_signed(T)) # All bits set
711+
IntegerIdentityOp(is_signed(T) ? -one(T) : typemax(T), dtype, T, is_signed(T))
710712

711713
# OR identity: 0 | x = x
712714
reduce_identity(::Val{:or}, dtype, ::Type{T}) where T <: Integer =
713-
IntegerIdentityOp(0, dtype, T, is_signed(T))
715+
IntegerIdentityOp(zero(T), dtype, T, is_signed(T))
714716

715717
# XOR identity: 0 ⊕ x = x
716718
reduce_identity(::Val{:xor}, dtype, ::Type{T}) where T <: Integer =
717-
IntegerIdentityOp(0, dtype, T, is_signed(T))
719+
IntegerIdentityOp(zero(T), dtype, T, is_signed(T))
718720

719721
#=============================================================================
720722
Reduce Body Operations - dispatch on Val{fn} and elem_type

0 commit comments

Comments
 (0)