On Thu, Apr 2, 2026 at 8:31 PM Hans-Peter Nilsson <[email protected]> wrote: > > On Thu, 2 Apr 2026, Philipp Tomsich wrote: > > 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. > > Confusing argument about a separate optimization, though > pragmatically it might be correct for some targets. But, that > argument isn't found in the patch-set, is it?
In fact I think we need a few versions of this pass through the pipeline. In a few different ways. We need a pass which does this for induction variables and that should be done to the width of the WORD_MODE. Second is we need a pass which does it to the smallest size that is being loaded. Third will be the pass late before expand which corrects up the smallest size case to either word mode or a few modes that is reasonable for the target. And then have the ability to remove some zero/sign extends inside the loop. >From the sound of it, the version we are talking about here is the second one. But I am not sure widening to int is correct either. Even for aarch64, the implicit zero-extend is not free for vectorization at all. So that argument goes out the window. But then I go and read what it does, it actually sounds like the third case. Also there was almost no description of the pass in the original message to the mailing list except in the code itself. Having a wiki page on the pass which describes what it does and why the choices are happening that way would be nice. On a secondary note to this, I think we should start up the RFC process again and start up the release planning process like we had back in early 4.x days (e.g. https://gcc.gnu.org/wiki/GCC_4.3_Release_Planning). Especially if we are going to have these huge pass additions. Also comments on the code here: + /* Already verified on a convergent path -- ok. In-loop merge + PHIs cannot form cycles without going through the header + PHI, so a previously visited node is safe. */ + if (visited.add (name)) + return true; Since name is always a SSA_NAME (you check above), you could just make visited a bitmap that is pre-allocated and mark it that way instead of a hash_map. That would be faster and small and not worry about hash conflicts. + tree *mapped = narrow_to_wide.get (back_arg); + if (mapped) + return *mapped; narrow_to_wide could be a vect since you again have a SSA_NAME. Or better yet use the version as the key rather than tree. Thanks, Andrew Pinski > > > 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. > > I see. > > > > 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. > > No, that's not a complete list. It might be the targets you > know or care about, but it's still incomplete. Hint: > LP64 targets that don't have vectorization. > > > Register-width widening would sacrifice vector throughput on every > > target for a cleanup that RTL passes should already handle. > > Incorrect. I'd suggest a target hook. If it would default to > register-sized type in the absence of vectorization, it'd be > perfect. The current setting with a comment about the > vectorisation reasoning and targets better see to the best > setting themselves, could also be ok. The hook should be > controllable from the target as an implicit effect of a target > option (like, one that selects vectorization for that target), > so from a function call rather than a constant. > > brgds, H-P
