On Wed, Sep 10, 2025 at 5:12 PM Christophe Lyon via Gcc <gcc@gcc.gnu.org> wrote:
>
> Hi!
>
> I am looking for clarification about the permitted shift amount in RTL
> (ashift, lshiftrt, ashiftrt).
>
> The doc in rtl.texi does not mention any constraints on the value of
> 'c'.  In particular, what is supposed to happen if c < 0 ?  Although
> it is UB at the C language level, arm targets have instructions
> (e.g. asrl and lsll) which explicitly support negative shift amounts
> in their "register" variant (if the shift amount is negative, the
> shift direction is reversed).
>
> We recently fixed the asrl and lsll Arm MVE intrinsics implementation
> in GCC to use the builtins instead of:
>
> return (value >> shift);
> return (value << shift);
>
> respectively, because some user code was purposely using a negative
> shift amount in order to shift in the opposite direction. With the
> previous implementation, the compiler detected UB and did not use the
> intended instruction.

I don't think RTL supports this, in the past we turned constant negative
shift amounts to flip the direction early on GENERIC, but I'm not sure
we're still doing this.

I think rtl.texi should mention that the shift amount is interpreted unsigned.

>
> However, we have concerns that given
>
> (set (reg:SI 1) (const_int -5))
> (set (reg:DI 2) (ashift:DI (reg:DI 3) (reg:SI 1)))
>
> simplify_rtx could simplify this into
>
> (set (reg:DI 2) (ashift:DI (reg:DI 3) (const_int -5)))
>
> and consider this as invalid and do whatever it feels like?
>
> I do notice several places in simplify-rtx.cc checking that
> UINTVAL (XEXP (op, 1)) < precision)
> so it seems there is some assumption that the shift amount is within
> the expected range.
>
> Does the doc need clarification on the semantics of RTL shift
> operations when the shift amount is out of range?

The SHIFT_COUNT_TRUNCATED target macro is also relevant in
this context.  On x86 which is a "mixed" ISA in this regard we make
sure to recognize shifts with an (and ...) shift operand which is
what the middle-end will add (the and) when !SHIFT_COUNT_TRUNCATED
IIRC.

Richard.

> Thanks,
>
> Christophe

Reply via email to