Fix .MUL_OVERFLOW expansion for non-mode precision arguments
Correctly expands built-in multiplication overflow checks for arguments with non-standard precision.
This commit fixes an issue in the expansion of the .MUL_OVERFLOW built-in function when arguments do not conform to standard precision modes. Previously, the code assumed uniform precision, leading to incorrect results for types like _BitInt. The fix ensures proper handling of value ranges for these non-standard types, particularly when mixed with signed or unsigned values.
In Details
The expand_mul_overflow function in GCC incorrectly handled cases where operand types had non-mode precision, especially when _BitInt support was introduced. This commit refines the logic for determining the sign and range of operands (get_range_pos_neg) when the operand's precision is less than the target mode's precision. It adjusts the logic to correctly account for virtual zero-extension of unsigned types that are narrower than the operation's mode, preventing incorrect overflow detection in scenarios like s x u -> s overflow.
- .MUL_OVERFLOW
- A GCC internal function that checks for arithmetic overflow during multiplication. It's used to implement compiler intrinsics for safe multiplication.
- _BitInt
- A GCC extension that allows users to specify integer types with arbitrary bit widths, not limited to standard C types like
intorlong. - mode precision
- The bit width or format defined by a GCC internal machine mode, typically corresponding to hardware register sizes or standard integer types.
- gimple opts
- Optimizations performed on the Gimple intermediate representation (IR) of the code. Gimple is a three-address-like representation used within GCC.