https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118682
--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I was thinking about
--- gcc/combine.cc.jj 2025-01-28 10:13:59.158871918 +0100
+++ gcc/combine.cc 2025-01-28 10:37:32.160477873 +0100
@@ -7637,6 +7637,15 @@ make_extraction (machine_mode mode, rtx
if (new_rtx)
return gen_rtx_MULT (mode, new_rtx, XEXP (inner, 1));
}
+ /* We're extracting the least significant bits of an rtx
+ (mult X (const_int Y<<Z + 1)), where Z >= LEN. Multiplication
+ by Y<<Z will guarantee all LEN least significant bits zero,
+ and so the LEN least significant bits of (mult X (const_int Y<<Z + 1))
+ will be equal to LEN least significant bits of X. */
+ else if ((INTVAL (XEXP (inner, 1)) & 1) != 0
+ && (unsigned) ctz_hwi (INTVAL (XEXP (inner, 1)) - 1) >= len)
+ return make_extraction (mode, XEXP (inner, 0), 0, 0, len,
+ unsignedp, in_dest, in_compare);
}
else if (GET_CODE (inner) == TRUNCATE
/* If trying or potentionally trying to extract
but maybe this isn't needed. make_extraction later calls
force_to_mode which calls force_int_to_mode which for MULT will do the binop
stuff,
use force_to_mode on the MULT operands. On the X it doesn't really do anything
when extracting 1 bit, but on (const_int 3) it returns const1_rtx and so it
will try
MULT by const1_rtx instead of 3 and simplify_gen_binary simplifies that to just
the other operand.