https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114547
Uroš Bizjak <ubizjak at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 CC| |ubizjak at gmail dot com Last reconfirmed| |2024-04-02 Status|UNCONFIRMED |NEW --- Comment #3 from Uroš Bizjak <ubizjak at gmail dot com> --- The similar testcase with comparison to zero: int z(int *v, int n) { *v -= n; return *v == 0; } int nz(int *v, int n) { *v -= n; return *v != 0; } generates expected code: z: xorl %eax, %eax subl %esi, (%rdi) sete %al ret nz: xorl %eax, %eax subl %esi, (%rdi) setne %al ret The middle end expands via standard sequence: (insn 10 9 11 (set (reg:CCZ 17 flags) (compare:CCZ (reg:SI 83 [ _2 ]) (const_int 0 [0]))) "s.c":3:12 -1 (nil)) (insn 11 10 12 (set (reg:QI 91) (eq:QI (reg:CCZ 17 flags) (const_int 0 [0]))) "s.c":3:12 -1 (nil)) (insn 12 11 13 (set (reg:SI 90) (zero_extend:SI (reg:QI 91))) "s.c":3:12 -1 (nil)) (insn 13 12 14 (set (reg:SI 85 [ <retval> ]) (reg:SI 90)) "s.c":3:12 -1 (nil)) OTOH, the sign compare is expanded via: (insn 12 9 13 (parallel [ (set (reg:SI 90) (lshiftrt:SI (reg:SI 83 [ _2 ]) (const_int 31 [0x1f]))) (clobber (reg:CC 17 flags)) ]) "pr114547.c":4:12 -1 (nil)) (insn 13 12 14 (set (reg:SI 85 [ <retval> ]) (reg:SI 90)) "pr114547.c":4:12 -1 (nil)) (The above shift also interferes with RMW creation, resulting in unoptimal asm sequence with two extra moves, and additional NEG insn in "ns" case.) Middle-end expansion should avoid premature optimization in this case, at least for targets that can merge sign comparison with the arith instruction.