Middle-end: Optimize MUL_HIGHPART RTL
Adds new RTL simplifications for signed and unsigned high-part multiplication operations.
This patch introduces new RTL simplifications for SMUL_HIGHPART and UMUL_HIGHPART. The compiler can now recognize that multiplying the high part of a product by zero or one results in zero. Additionally, it optimizes multiplication by powers of two by transforming them into logical or arithmetic right shifts, depending on whether the operation is signed or unsigned. These optimizations improve the efficiency of intermediate representations for multiplication operations.
In Details
This commit enhances simplify_binary_operation_1 in simplify-rtx.cc by adding new machine-independent RTL simplifications for SMUL_HIGHPART and UMUL_HIGHPART. The existing logic already handled multiplication by zero. This patch adds cases for multiplication by one, reducing SMUL_HIGHPART(x, 1) to (x >> (PRECISION-1)) (sign-extending) and UMUL_HIGHPART(x, 1) to 0. Furthermore, multiplications by powers of two are now transformed into shifts: UMUL_HIGHPART(x, 1 << n) becomes (x >> n) and SMUL_HIGHPART(x, 1 << n) becomes (x >> n) (arithmetic shift). A new test case `mul-…
- RTL
- Register Transfer Language. An intermediate representation used by GCC to represent code during optimization passes. It's a low-level, machine-independent language.
- MUL_HIGHPART
- An RTL operation representing the multiplication of the high-order part of a product. For example, in a 64-bit multiplication, this would be the upper 32 bits of the 64-bit result.
- SMUL_HIGHPART
- Signed MUL_HIGHPART. Represents the high part of a signed multiplication.
- UMUL_HIGHPART
- Unsigned MUL_HIGHPART. Represents the high part of an unsigned multiplication.
- simplification
- An optimization pass that transforms RTL code into an equivalent but simpler form, making it easier for later passes to optimize further or generate efficient machine code.
- arithmetic right shift
- A bitwise right shift operation that preserves the sign bit of the number. If the number is negative, the most significant bit is filled with 1s; otherwise, it's filled with 0s.
- logical right shift
- A bitwise right shift operation that fills the most significant bit with 0s, regardless of the sign of the number.