What is `slt_int`

What is Core.Intrinsics.slt_int? As seen in base/sort.jl, added 2013.

Also, how can I find out the answer to this sort of question in general? I tried @edit, ?, web searches, and even git blame (a much less ideal solution), but none came up with anything.

Emperically:

using Test

values = Float64[
    0.0, -0.0, 1.0, -1.0, pi, 1/pi, Inf, -Inf, NaN, -NaN, 
    rand(), 1/rand(), -rand(), -1/rand(), 
    reinterpret(Float64, reinterpret(UInt64, NaN) | 78782),
    -reinterpret(Float64, reinterpret(UInt64, NaN) | 78782)]

@testset "slt_int == isless(reinterpret(Int, ⋅))" begin
    for a in values
        for b in values
            @test Core.Intrinsics.slt_int(a, b) == 
                  isless(reinterpret(Int64, a), reinterpret(Int64, b))
        end
    end
end
Test Summary:                          | Pass  Total
slt_int == isless(reinterpret(Int, ⋅)) |  256    256
1 Like

It is an intrinsic that implements signed less than for integers. That particular line is a bit tricky since it applies integer intrinsics directly to floating-point values. Normally, I’d express that by reinterpreting to an integer type with the same size and then doing the normal isless comparison, but this tricky way to do it leverages the fact that intrinsics generate the right sized instructions based on the storage size of the arguments they get. That test you referenced verifies that slt_int has the same effect as that reinterpretation and isless comparison for floating-point values.

Intrinsics are an internal language implementation detail, not part of the official surface API, so they’re not documented. Code generation for slt_int is defined in this line:

You can see that it calls the LLVM method, CreateICmpSLT, which is documented here the meanings of which are documented here.

5 Likes

Thanks! It’s nice to know for sure what is going on.

1 Like

Is there any reason we define

struct Right <: Ordering end
right(::DirectOrdering) = Right()
lt(::Right, x::T, y::T) where {T<:Floats} = slt_int(x, y)

In julia/sort.jl at b2d15f05698ba78ac2493ec2624a0ee1c9a042a3 · JuliaLang/julia · GitHub
instead of

right(::DirectOrdering) = Reverse(Left())

?

Not sure, I didn’t write that code.

You didn’t?

That code is 9 years old, I think it’s fine to not quite remember why it was written this exact way :slight_smile: If it wasn’t specially documented, there probably was not a specific reason (though that’s a very fuzzy indicator, so if it there was a reason and it can be documented now, that’d be good too - and even more amazing if future additions have a nice comment/git log trail).

2 Likes

That doesn’t include anything called Right so I can’t speak to why that is the way it is.

@Sukera is right, and the way it’s written isn’t posing a problem, so I’m happy to move on. This is the history, though:

Rename from FpRev to Rev

Rename from Rev to Right

In digging through the history, I answered my own question. When Right was originally written, Reverse wasn’t parametric. You only added that here

And nobody got around to using Reverse in the Sort.Float module. This raises the question: should we change it now? I could make a PR if appropriate.