https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93505
--- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
As for the expand_binop bug, if I fix it like:
--- gcc/optabs.c.jj 2020-01-12 11:54:36.690409230 +0100
+++ gcc/optabs.c 2020-01-30 16:05:43.520649234 +0100
@@ -1226,16 +1226,22 @@ expand_binop (machine_mode mode, optab b
unsigned int bits = GET_MODE_PRECISION (int_mode);
if (CONST_INT_P (op1))
- newop1 = gen_int_shift_amount (int_mode, bits - INTVAL (op1));
+ newop1
+ = gen_int_shift_amount (int_mode, (bits - UINTVAL (op1)) % bits);
else if (targetm.shift_truncation_mask (int_mode) == bits - 1)
newop1 = negate_rtx (GET_MODE (op1), op1);
- else
- newop1 = expand_binop (GET_MODE (op1), sub_optab,
- gen_int_mode (bits, GET_MODE (op1)), op1,
+ else if (pow2p_hwi (bits))
+ newop1 = expand_binop (GET_MODE (op1), and_optab,
+ negate_rtx (GET_MODE (op1), op1),
+ gen_int_mode (bits - 1, GET_MODE (op1)),
NULL_RTX, unsignedp, OPTAB_DIRECT);
+ else
+ newop1 = NULL_RTX;
- temp = expand_binop_directly (icode, int_mode, otheroptab, op0, newop1,
- target, unsignedp, methods, last);
+ temp = NULL_RTX;
+ if (newop1)
+ temp = expand_binop_directly (icode, int_mode, otheroptab, op0, newop1,
+ target, unsignedp, methods, last);
if (temp)
return temp;
}
then unfortunately given -O2 on
unsigned int
bar (unsigned int x, int y)
{
return x >> y | x << (-y & 31);
}
powerpc64le-linux emitted assembly changes like:
bar:
.LFB1:
.cfi_startproc
- subfic 4,4,32
+ neg 4,4
+ rlwinm 4,4,0,27,31
rotlw 3,3,4
blr
Given
unsigned int
baz (unsigned int x, int y)
{
y &= 31;
return x >> y | x << (-y & 31);
}
the change is:
bar:
.LFB1:
.cfi_startproc
+ neg 4,4
rlwinm 4,4,0,27,31
- subfic 4,4,32
rotlw 3,3,4
blr
and so I'd say even if we just don't fix expand_binop, this shows an
optimization opportunity for the rs6000 backend
if the rotlw instruction only uses bottom 5 bits from the last operand.