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.
