Jakub Jelinek via Gcc <[email protected]> writes:
> On Thu, Sep 11, 2025 at 11:02:26AM +0200, Richard Biener via Gcc wrote:
>> > 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.
>
> For SHIFT_COUNT_TRUNCATED targets, the shift count is certainly
> modulo the bitsize, though it is fuzzy what happens when the bitsize is not
> a power of two and the count is negative (whether it is treated as unsigned
> modulo or something else (eventhough -27 % 24 is -3 and not 21 (24 - 3)
> or 13 (-27U % 24)).
> For !SHIFT_COUNT_TRUNCATED, I think we generally consider it UB even on RTL,
> although it doesn't mean we can ICE on it etc., we can just punt on trying
> to optimize it, but it still needs to be assembled one way or another,
> the code might invoke UB but can't be proven to be always executed.

FWIW, I thought that for !SHIFT_COUNT_TRUNCATED, we treated out-of-range
shifts as target-specific.  E.g. it's possible for a !SHIFT_COUNT_TRUNCATED
target to use lshift in the expansion of another operation (such as a
doubleword shift) and rely on target-specific behaviour for shifts
greater than the bit count.  That applies to negative shifts as well.

That's why, for example, simplify-rtx.cc is careful to punt when trying
to fold shifts to constants if !SHIFT_COUNT_TRUNCATED and the shift
is out of range.  If the shift was UB, we could instead fold all shifts
according to SHIFT_COUNT_TRUNCATED semantics.

But the fact that there are varying opinions does prove the point that
this is underdocumented...

Richard

Reply via email to