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
