On Thu, 2 Apr 2026 at 03:52, Hans-Peter Nilsson <[email protected]> wrote: > > On Fri, 13 Mar 2026, Philipp Tomsich wrote: > > > Add a new SSA pass (pass_widen_accum) that widens narrow integer > > loop accumulators (e.g. short, char) to int-width, eliminating > > per-iteration sign-/zero-extension truncations. > > I see you really mean int-width, like > tree wide_type = unsigned_type_node
The widening to int is intentional; it's the minimum width that eliminates the per-iteration truncations, and going wider would hurt vectorization. The pass already trades vector throughput for truncation elimination: a short accumulator vectorizes at e16 (VLEN/16 elements on RVV, 8 elements in a NEON 128-bit register), and widening to int halves that to e32. Widening further to register width (64-bit) would halve it again to e64 — a 4x reduction from the original. > So, those sign-/zero-extension truncations will still typically > happen for LP64-targets, where "int" is 32 bits and registers > are 64 bits. So, shouldn't that "int-width" better be > "register-width", typically (u)intptr_t? On the targets where 32-bit operations still produce implicit extensions: - AArch64 and x86-64: 32-bit register operations implicitly zero-extend to 64 bits. Widening to int already eliminates all truncation overhead — no 32-to-64 extensions remain. - RISC-V 64: addw/subw sign-extend their 32-bit result to 64 bits. Any explicit sext.w after them is redundant and is cleaned up by REE, combine, and ext-dce at the RTL level. The residual cases (unsigned accumulator needing zero-extension in a 64-bit context) should be rare and will (hopefully) be handled by ext-dce's bit-level liveness analysis. Register-width widening would sacrifice vector throughput on every target for a cleanup that RTL passes should already handle. Best, Philipp.
