On Mon, Sep 15, 2025 at 11:55 AM Christophe Lyon <christophe.l...@linaro.org> wrote: > > On Thu, 11 Sept 2025 at 19:44, Jakub Jelinek <ja...@redhat.com> wrote: > > > > On Thu, Sep 11, 2025 at 07:14:51PM +0200, Richard Biener wrote: > > > Yes, RTL expansion inserts an AND operation when !SHIFT_COUNT_TRUNCATED. > > > What I was saying there's no way to get a negative shift count flip shift > > > direction to RTL - it would require a target specific intrinsic that's a > > > builtin > > > call before RTL expansion and an UNSPEC after. > > > > Of course the target can have patterns like: > > (set (match_operand:M 0) > > (if_then_else:M > > (lt:SI (match_operand:SI 2) (const_int 0)) > > (ashiftrt:M (match_operand:M 1) (neg:SI (match_dup 2))) > > (ashift:M (match_dup 1) (match_dup 2)))) > > or so, it doesn't need to use UNSPEC for that. > > > > Hi! > Thanks for all the feedback, that was very useful. > I've implemented the suggestion above, but so far I couldn't make the > 'if' condition match (the shift amount is never seen as negative with > my tests). > Since the constraint is "rPg", where "Pg" means "constant in range 1 > to 32", out-of-range values are always passed in register: can the > above if_then_else work when operand 2 is a register?
I think the above might match during combine when you write C code like if (n < 0) res = x >> -n; else res = x << n; which of course would need to be if-converted (possibly trying to match exactly that insn pattern). A variant with UB, like res1 = x >> -n; res2 = x << n; res = n < 0 ? res1 : res2; might be an easier match. Richard. > Christophe > > > Jakub > >