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.

Reply via email to