https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101617
--- Comment #9 from CVS Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Roger Sayle <sa...@gcc.gnu.org>: https://gcc.gnu.org/g:f1652e3343b1ec47035370801d9b9aca1f8b613f commit r13-857-gf1652e3343b1ec47035370801d9b9aca1f8b613f Author: Roger Sayle <ro...@nextmovesoftware.com> Date: Mon May 30 21:26:37 2022 +0100 PR rtl-optimization/101617: Use neg/sbb in ix86_expand_int_movcc. This patch resolves PR rtl-optimization/101617 where we should generate the exact same code for (X ? -1 : 1) as we do for ((X ? -1 : 0) | 1). The cause of the current difference on x86_64 is actually in ix86_expand_int_movcc that doesn't know that negl;sbbl can be used to create a -1/0 result depending on whether the input is zero/nonzero. So for Andrew Pinski's test case: int f1(int i) { return i ? -1 : 1; } GCC currently generates: f1: cmpl $1, %edi sbbl %eax, %eax // x ? 0 : -1 andl $2, %eax // x ? 0 : 2 subl $1, %eax // x ? -1 : 1 ret but with the attached patch, now generates: f1: negl %edi sbbl %eax, %eax // x ? -1 : 0 orl $1, %eax // x ? -1 : 1 ret To implement this I needed to add two expanders to i386.md to generate the required instructions (in both SImode and DImode) matching the pre-existing define_insns of the same name. 2022-05-30 Roger Sayle <ro...@nextmovesoftware.com> gcc/ChangeLog PR rtl-optimization/101617 * config/i386/i386-expand.cc (ix86_expand_int_movcc): Add a special case (indicated by negate_cc_compare_p) to generate a -1/0 mask using neg;sbb. * config/i386/i386.md (x86_neg<mode>_ccc): New define_expand to generate an *x86_neg<mode>_ccc instruction. (x86_mov<mode>cc_0_m1_neg): Likewise, a new define_expand to generate a *x86_mov<mode>cc_0_m1_neg instruction. gcc/testsuite/ChangeLog PR rtl-optimization/101617 * gcc.target/i386/pr101617.c: New test case.