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

Reply via email to