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
> >

Reply via email to