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

--- Comment #2 from Oleksandr Kulkov <adamant.pwn at gmail dot com> ---
Created attachment 66112
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=66112&action=edit
Regression tests only (AI-generated, offered under the test-case exception)

This adds detail on where the duplicate AND in comment 1 comes from.

The split happens in try_combine, in the branch for "a PARALLEL of two
independent SETs" (gcc/combine.cc line 3990 at 7d652a985309). Combine
substitutes insn 10 into insn 11 and simplifies the zero_extend of the QImode
AND into an SImode AND of the same register. r132 is still used later as the
shift and rotate count. So combine keeps its set and builds the two-SET
PARALLEL shown in comment 1. That PARALLEL fails to match on x86. Neither
original insn is a simple move, so this branch emits each SET as its own insn.

Both SETs keep their original sources, and each still reads r129 directly. Both
ANDs therefore survive. The cost check accepts the result because the cost
stays at 4 + 4. After combine, nothing records that r132 equals the low part of
r122. Register allocation then keeps two masked copies of the offset (r10d and
ecx in the original report).

If r132 were set from the low part of r122, as comment 1 suggests, the testcase
would need only one "andl $63".

The attached regression tests were generated with OpenAI Codex and are offered
under the test-case exception of the AI policy. The assembly test checks for
exactly one "andl $63" and fails on trunk at 7d652a985309. The execution test
also covers masks that differ (31 and 63), where both ANDs are needed. I also
used Codex for the analysis above and checked it against the combine dumps.

Assisted-by: OpenAI Codex

Reply via email to