i386: Improve x86 Scalar-To-Vector conversion for zero-extended memory loads
Optimizes Scalar-To-Vector (STV) conversion by recognizing that loading a 32-bit value into an SSE register naturally zero-extends it to 64 bits.
This patch enhances the i386 backend’s Scalar-To-Vector (STV) conversion by allowing it to recognize and optimize patterns where a 32-bit memory value is zero-extended to a 64-bit value using SSE registers. Loading a 32-bit value into an SSE register automatically clears the upper bits, effectively performing a zero-extension. This transformation replaces multiple instructions with a single SSE load and manipulation, improving code density and potentially performance.
In Details
The i386 backend's stv2 pass now considers (zero_extend:DI (mem:SI ...)) patterns as candidates for V2DImode STV conversion. Previously, this pattern required explicit instructions to perform the zero-extension and load into SSE registers. By recognizing that movd (or movq with movq_load_si_pseudo) into an XMM register zero-extends the SI source to DI, the backend can directly generate SSE instructions (e.g., movd followed by punpckldq or pxor) to implement this conversion more efficiently, eliminating intermediate XOR or explicit zeroing instructions.
- SSE
- Streaming SIMD Extensions, a set of CPU instructions for parallel processing of data, commonly used for multimedia and floating-point operations. SSE registers (XMM) are 128 bits wide.
- Scalar-To-Vector (STV)
- A compiler optimization pass that converts scalar operations (operating on single values) into vector operations (operating on multiple values in parallel using SIMD instructions).
- DI mode
- Doubleword Integer mode, representing a 64-bit integer value.
- SI mode
- Singleword Integer mode, representing a 32-bit integer value.
- zero-extend
- An operation that converts a smaller integer type to a larger integer type by padding the most significant bits with zeros. This is in contrast to sign-extension, which pads with copies of the sign bit.
- rtl
- Register Transfer Language, an intermediate representation used within GCC to describe operations before they are converted into machine code.