Skip to content

Conversation

LilithHafner
Copy link
Member

Seems like 1 instruction to 4 (branchless) instructions for these two cases:

julia> function sat_mul(x::UInt, y::UInt)
           w = widemul(x,y)
           w2 = w % UInt
           w2 == w ? w2 : typemax(UInt)
       end
sat_mul (generic function with 2 methods)

julia> function sat_plus(x::Int, y::Int)
           z, o = Base.Checked.add_with_overflow(x, y)
           o ? x < 0 ? typemin(Int) : typemax(Int) : z
       end
sat_plus (generic function with 1 method)

julia> @code_native sat_mul(UInt(2), UInt(2))
	.text
	.file	"sat_mul"
	.globl	julia_sat_mul_3459              // -- Begin function julia_sat_mul_3459
	.p2align	2
	.type	julia_sat_mul_3459,@function
julia_sat_mul_3459:                     // @julia_sat_mul_3459
; Function Signature: sat_mul(UInt64, UInt64)
; ┌ @ REPL[57]:1 within `sat_mul`
// %bb.0:                               // %top
; │ @ REPL[57] within `sat_mul`
	//DEBUG_VALUE: sat_mul:x <- $x0
	//DEBUG_VALUE: sat_mul:x <- $x0
	//DEBUG_VALUE: sat_mul:y <- $x1
	//DEBUG_VALUE: sat_mul:y <- $x1
	stp	x29, x30, [sp, #-16]!           // 16-byte Folded Spill
	mov	x29, sp
; │ @ REPL[57]:2 within `sat_mul`
; │┌ @ number.jl:277 within `widemul`
; ││┌ @ int.jl:998 within `*`
	mul	x8, x0, x1
	umulh	x9, x0, x1
	cmp	xzr, x9
	csinv	x0, x8, xzr, eq
; │└└
; │ @ REPL[57]:4 within `sat_mul`
	ldp	x29, x30, [sp], #16             // 16-byte Folded Reload
	ret
.Lfunc_end0:
	.size	julia_sat_mul_3459, .Lfunc_end0-julia_sat_mul_3459
; └
                                        // -- End function
	.section	".note.GNU-stack","",@progbits

julia> @code_native *(UInt(2), UInt(2))
	.text
	.file	"*"
	.globl	"julia_*_3466"                  // -- Begin function julia_*_3466
	.p2align	2
	.type	"julia_*_3466",@function
"julia_*_3466":                         // @"julia_*_3466"
; Function Signature: *(UInt64, UInt64)
; ┌ @ int.jl:88 within `*`
// %bb.0:                               // %top
; │ @ int.jl within `*`
	//DEBUG_VALUE: *:x <- $x0
	//DEBUG_VALUE: *:x <- $x0
	//DEBUG_VALUE: *:y <- $x1
	//DEBUG_VALUE: *:y <- $x1
	stp	x29, x30, [sp, #-16]!           // 16-byte Folded Spill
	mov	x29, sp
; │ @ int.jl:88 within `*`
	mul	x0, x1, x0
	ldp	x29, x30, [sp], #16             // 16-byte Folded Reload
	ret
.Lfunc_end0:
	.size	"julia_*_3466", .Lfunc_end0-"julia_*_3466"
; └
                                        // -- End function
	.section	".note.GNU-stack","",@progbits

julia> @code_native sat_plus(1,1)
	.text
	.file	"sat_plus"
	.globl	julia_sat_plus_3469             // -- Begin function julia_sat_plus_3469
	.p2align	2
	.type	julia_sat_plus_3469,@function
julia_sat_plus_3469:                    // @julia_sat_plus_3469
; Function Signature: sat_plus(Int64, Int64)
; ┌ @ REPL[58]:1 within `sat_plus`
// %bb.0:                               // %top
; │ @ REPL[58] within `sat_plus`
	//DEBUG_VALUE: sat_plus:x <- $x0
	//DEBUG_VALUE: sat_plus:x <- $x0
	//DEBUG_VALUE: sat_plus:y <- $x1
	//DEBUG_VALUE: sat_plus:y <- $x1
	stp	x29, x30, [sp, #-16]!           // 16-byte Folded Spill
	mov	x29, sp
; │ @ REPL[58]:3 within `sat_plus`
	adds	x8, x0, x1
	asr	x9, x8, #63
	eor	x9, x9, #0x8000000000000000
	csel	x0, x9, x8, vs
	ldp	x29, x30, [sp], #16             // 16-byte Folded Reload
	ret
.Lfunc_end0:
	.size	julia_sat_plus_3469, .Lfunc_end0-julia_sat_plus_3469
; └
                                        // -- End function
	.section	".note.GNU-stack","",@progbits

julia> @code_native +(1,1)
	.text
	.file	"+"
	.globl	"julia_+_3474"                  // -- Begin function julia_+_3474
	.p2align	2
	.type	"julia_+_3474",@function
"julia_+_3474":                         // @"julia_+_3474"
; Function Signature: +(Int64, Int64)
; ┌ @ int.jl:87 within `+`
// %bb.0:                               // %top
; │ @ int.jl within `+`
	//DEBUG_VALUE: +:x <- $x0
	//DEBUG_VALUE: +:x <- $x0
	//DEBUG_VALUE: +:y <- $x1
	//DEBUG_VALUE: +:y <- $x1
	stp	x29, x30, [sp, #-16]!           // 16-byte Folded Spill
	mov	x29, sp
; │ @ int.jl:87 within `+`
	add	x0, x1, x0
	ldp	x29, x30, [sp], #16             // 16-byte Folded Reload
	ret
.Lfunc_end0:
	.size	"julia_+_3474", .Lfunc_end0-"julia_+_3474"
; └
                                        // -- End function
	.section	".note.GNU-stack","",@progbits

@LilithHafner LilithHafner added docs This change adds or pertains to documentation performance Must go faster maths Mathematical functions labels Sep 19, 2025
@LilithHafner
Copy link
Member Author

Test failures look unrelated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs This change adds or pertains to documentation maths Mathematical functions performance Must go faster
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant