On 6/11/25 9:53 AM, Richard Sandiford wrote:
+ into B | (1 << A). */
+ if (GET_CODE (op0) == AND
+ && GET_CODE (XEXP (op0, 0)) == ROTATE
+ && CONST_INT_P (XEXP (XEXP (op0, 0), 0))
+ && INTVAL (XEXP (XEXP (op0, 0), 0)) == -2
+ && GET_CODE (op1) == ASHIFT
+ && CONST_INT_P (XEXP (op1, 0))
+ && INTVAL (XEXP (op1, 0)) == 1
+ && rtx_equal_p (XEXP (XEXP (op0, 0), 1), XEXP (op1, 1))
I think you also need to check !side_effects_p on XEXP (op1, 1),
since we'll be dropping one instance of the expression.
Yes. Thanks for catching this. I likely would have missed it.
+ && rtx_equal_p (XEXP (op0, 1), XEXP (op0, 1)))
Is this last line a typo? It should always be true.
Certainly looks weird. The prior test is checking the shift/rotate
counts are the same. It's not obvious that any other objects need to be
equal in this transformation.
I suppose the main question is whether we can safely apply this for
!SHIFT_COUNT_TRUNCATED targets.
It's probably best to be safe, though it'd be a real surprise to see the
shift count being truncated on a shift, but not on a rotate or vice-versa
Jaiwei, can you also see if (ior (and (rotate ...)) gets simplified in
the combine dump? During the recent logical op rework I saw multiple
cases where we doing redundant bitmanip operations. It's worth double
checking.
Thanks!
jeff