How do I propose an optimization for x86 SSE2?

I never contributed to LLVM or interacted with the community here, so I would like to ask how I can propose an optimization in the code gen for x86 with SSE2. Also, I’m not sure whether the LLVM project would even accept that optimization, so is this forum the right place to discuss it with relevant experts first?


To give some detail on the optimization: On x86, ISD::FTRUNC compiles to a single instruction with SSE4.1 (or AVX, etc.) but a library call to truncf on SSE2. The soft-float implementation of the library plus the call overhead makes this very slow. This is a problem in Rust, where generic x86 binaries can typically only assume SSE2.

So I would like to propose a custom lowering for ISD::FTRUNC and ISD::FROUND for x86 SSE2. Here’s a Rust version of the scalar algorithm for trunc. (SSE2 SIMD instructions for all used operations exist.)

fn trunc_sse2_scalar(x: f32) -> f32 {
    // Clear the sign bit
    let abs = x.abs();

    // Determine which values to return unchanged
    const INT_THRESHOLD: i32 = f32::to_bits(2147483648_u32 as f32) as i32;
    let return_unchanged = abs.to_bits() as i32 >= INT_THRESHOLD;

    // Truncate using the native SSE2 f32 <-> i32 conversions
    let abs_trunc = (abs as i32) as f32;
    let trunc = abs_trunc.copysign(x);

    if return_unchanged { x } else { trunc }
}

This is bit-exact to the library truncf and around 10x faster on my machine when used in a loop.

The algorithm for ISD::FROUND is almost identical. The only difference is that next_down(0.5) is added to the absolute value before truncation via integer cast.

I’d propose starting with creating RFC (request for comment) post where you’d describe what you want to add. You can see many RFC posts around.

This doesn’t need an RFC; it’s just extending the existing mechanism for custom lowering of ftrunc to work in more cases. The RFC process is intended for controversial or large changes.

Feel free to just post a patch (Contributing to LLVM - LLVM).

Or if you don’t want to try to implement this yourself, you can open an issue at Issues · llvm/llvm-project · GitHub ; you might find someone else interested in tackling it.

(I haven’t tried to work through whether the proposed lowering is actually correct.)

Thank you for the quick responses!

Then I’ll try my hand at a patch tonight. If people deem it necessary, I’ll make an RFC after that.