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.

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?

Thanks,

Christophe

Reply via email to