On Tue, 19 Nov 2024, Jakub Jelinek wrote:

> Hi!
> 
> Apparently the middle-end/expansion can only handle {L,R}ROTATE_EXPR
> on types with mode precision, or large/huge BITINT_TYPE.
> So, the following patch uses the rotate exprs only in those cases
> where it can be handled, and emits code with shifts/ior otherwise.
> As types without mode precision including small/medium BITINT_TYPE
> have unlikely power of two precision and TRUNC_MOD_EXPR is on many targets
> quite expensive, I chose to expand e.g. __builtin_stdc_rotate_left (arg1,
> arg2) as
> ((tem = arg1, count = arg2 % prec)
>  ? ((tem << count) | (tem >> (prec - count))) : tem)
> rather than
> (((tem = arg1) << (count = arg2 % prec))
>  | (tem >> (-count % prec))
> (where the assignments are really save_exprs, so no UB), because
> I think another TRUNC_MOD_EXPR would be more costly in most cases
> when the shift count is non-constant (and when it is constant,
> it folds to 2 shifts by constant and ior in either case).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK (though if in future any other language wants rotates of non-mode 
precision, we should teach the middle-end to lower / expand them 
appropriately itself rather than duplicating such logic between front 
ends).

-- 
Joseph S. Myers
josmy...@redhat.com

Reply via email to