https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121959
--- Comment #8 from rguenther at suse dot de <rguenther at suse dot de> --- On Thu, 23 Oct 2025, rdapp at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121959 > > --- Comment #7 from Robin Dapp <rdapp at gcc dot gnu.org> --- > > So what do we want? RVV can do a widen subtract-and-shift? If not, > > we're stuck with signed short subtract (possibly a widening uchar subtract > > if that exists?) and a widen left shift. > > > > I can't see how one could argue that a[0] == 0, b[0] == 5, aka -5 << 16 > > would be invalid. In particular in C++ this is well-defined. > > Ah, I wasn't aware that C++20 defined it. > > We have a widening shift and a widening subtract but the widening shift is > only > unsigned. > > Having looked at the patterns and possible options for a while now, I don't > think it's feasible or reasonable to change pattern handling without > complicating things a lot. I guess that leaves us with option (2), > converting > (int)((signed short)bla << 16) > into > (int)((unsigned short)bla << 16) > if shift count >= TYPE_PRECISION (TREE_TYPE (bla)). > > Is that desirable, generally? The point would be turning a sign extension > into a zero extension. Zero extensions can be slightly less expensive in > hardware but I'm not sure if that's a sufficient justification. > LLVM seems to do this, but I haven't checked whether just for RISC-V or > generally. If you have a widening unsigned shift then we can pattern match that to (int)((signed short)bla << 16) or any shift count >= TYPE_PRECISION (TREE_TYPE (bla)) given your argument above? That said, I'd try to handle this within the widen-shift pattern recognition code?
