https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94567

--- Comment #12 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Jeffrey A. Law from comment #11)
> Rather than extending that hack, I think just widening the mode when the
> sign bit is being tested (c#5) is simpler and easier to understand.  The
> bits you're changing should be killed rather than extended to handle more
> cases.

That is not a hack.  x86_64 doesn't have an instruction that ands a 64-bit
reg/mem with a 32-bit zero extended immediate (nor 64-bit immediate), so when
we want to use reg against 32-bit zero extended, we need to use 32-bit
instruction and that has different behavior for the SF, so we must ensure we
don't care about that most significant bit.

Now for these other cases, perhaps we could instead user wider mode if
possible, but it isn't possible always.
So, combine my patch with the last condition changed into >= 32 from
== GET_MODE (operands[2]) and then apply what you have in #c5, but with
hardcoded SImode instead of wider mode - we want to avoid introducing HImode
stuff when there wasn't before, it is both larger and slower - and only do it
if GET_MODE (operands[0]) isn't CCZmode.
If pos + len >= 32, such in the pos + len == 64 special case where we turn
testing bits pos (< 32) up to most significant into a testq which has that
sign-extended 32-bit immediate, then the pattern before splitting would have
always SF zero (unless pos is 0) but split pattern would always copy there the
MSB of the 64-bit register.

Reply via email to