Adding libcall support for Rust's new vector math library

We’re writing a vector math library for use with Rust’s Project Portable SIMD, where we would like to have fast architecture-independent implementations of functions like vectorized cos that are available from Rust’s core library, where the requirement is that it can’t depend on system libraries such as libc or libm. In order to have Rust code run as fast as possible, we want to have the Rust compiler generate calls to LLVM intrinsics such as llvm.cos.v4f32 allowing LLVM to optimize those intrinsics and generate native instructions where available, otherwise generating calls to the Rust vector math library functions that implement the appropriate functions.

Tracking issue for vector math library with more details:
https://github.com/rust-lang/stdsimd/issues/109

WIP vector math library:
https://salsa.debian.org/Kazan-team/vector-math/

What all is required to get LLVM to generate libcalls to our vector math library? Does this sound like a good plan?

Also, there are some math functions that don’t currently have generic LLVM intrinsics, that several different architectures support, such as sinpi which is supported by AMDGPU (multiply input by 0.5 then use the sin instruction), OpenCL-flavored SPIR-V, Libre-SOC’s SimpleV (not in LLVM yet), and probably others too.

Jacob Lifshay

Sounds like a good plan to me, but perhaps others know more/better.
Clang option -fveclib=​ can be used to specify a vector library, so I think the infrastructure is there and you’ll just need to plumb in support for yours.

Cheers.

Sounds like a good plan to me, but perhaps others know more/better.

Thanks!

Clang option -fveclib=​ can be used to specify a vector library, so I think the infrastructure is there and you’ll just need to plumb in support for yours.

Yeah, I’m aware the infrastructure already exists, I’m just not sure how I should add the new code – which classes should I subclass/modify?

Jacob

Yeah, I’m aware the infrastructure already exists, I’m just not sure how I should add the new code – which classes should I subclass/modify?

I think you could do this by example. There is a front-end part, e.g. https://reviews.llvm.org/D53928, and there is back-end part, e.g. https://reviews.llvm.org/D53927.

Thanks for the links!

Would we have to add support to clang in order to merge our patches,
or can we get away with just adding support to llvm and rustc for now
since the vector math library is going to be mostly used just through
rustc?

Jacob

Not sure if I fully understand the question - but for our Burst HPC# compiler we just:

  • create our own TargetLibraryInfo
  • use targetLibraryInfo.addVectorizableFunctions(descriptors); to add scalar → vector mappings
  • profit?
    I can say that this has let us teach LLVM how to vectorize calls to math functions that don’t have matching LLVM intrinsics (like acos/asin/etc).

-Neil.

From what I can see in D53927, we’d probably want to modify the existing TargetLibraryInfo rather than create a new one, since we are trying to get support into upstream LLVM rather than having to cram more stuff into rustc’s LLVM glue code (which we’re trying to upstream to LLVM as much as possible) and modifying the existing TargetLibraryInfo looks like what would work best.

Thanks everyone!

Jacob