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