https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124956
--- Comment #2 from Dusan Stojkovic <[email protected]> --- Created attachment 64842 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=64842&action=edit A minimal patch to handle consts in noce_try_cond_arith As a recap, per our discussions on the patchwork sync the general optimization can be split into two parts: 1. Handling const_int operands in noce_try_cond_arith better 2. Peeling the sign/zero extend part of the RTX expression and trying to emit cmove in the wider mode before reapplying the extension peeled. The patch attached addresses 1. in the narrowest sense. The general change which regressed the detection of const_int can be traced back to: https://gcc.gnu.org/cgit/gcc/commit/?id=9e61a171244110a45a87bb010704f2f9d4030181 In the mode variable we had GET_MODE (if_info->x) which is in the wider mode. The patch attached uses this mode for emitting cmove in the case when the GET_MODE(XEXP(a, 1) is VOIDmode (i.e. const_int). Additionally, it allows a_op1 to be a const_int in this case because the `if (a_op1 == NULL_RTX)` will deny any CONST_INT_P related optimizations. Instead of adding get_base_reg_or_constant as Jeff mentioned here: https://www.mail-archive.com/[email protected]/msg405649.html the patch attached only allows a_op1 to be a const_int which seems like the minimal prerequisite. Note this hasn't been tested thoroughly enough, but a nice consequence of this change is that on the trunk a test like: long test_long_Mul_pow2_eqz (long cond, long val) { if (cond) val *= 64; return val; } produces: test_long_Mul_pow2_eqz: beq a0,zero,.L11 slli a1,a1,6 .L11: mv a0,a1 ret And with the attached patch the result is: test_long_Mul_pow2_eqz: li a5,6 czero.eqz a0,a5,a0 sll a0,a1,a0 ret
