https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119178
Bug ID: 119178 Summary: Optimization: (x != C) comparison can utilize (x - C) or (x ^ C) result Product: gcc Version: 14.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: other Assignee: unassigned at gcc dot gnu.org Reporter: Explorer09 at gmail dot com Target Milestone: --- This is an optimization opportunity that can benefit RISC-V, MIPS and other processors that don't use condition codes for their compare-and-branch instructions. ```c #include <stdlib.h> unsigned int func1_a(unsigned int x) { if (x != 0x555) return (x ^ 0x555); abort(); } unsigned int func1_c(unsigned int x) { unsigned int tmp = x ^ 0x555; __asm__ ("" : "+r" (tmp)); if (tmp == 0) abort(); return tmp; } unsigned int func2_a(unsigned int x) { if (x != 0x555) return (x - 0x555); abort(); } unsigned int func2_c(unsigned int x) { unsigned int tmp = x - 0x555; __asm__ ("" : "+r" (tmp)); if (tmp == 0) abort(); return tmp; } ``` The example code above can be tested in Compiler Explorer (godbolt.org). func1_c() and func2_c() are the results I expected for func1_a() and func2_a() to optimize to when using the `-Os` option. * The second operand for `==` or `!=` comparison is a compile-time constant. * The constant is small enough to fit the immediate operands of the "sub" and "xor" instructions. * The compare-and-branch instructions of RISC-V have only register operands (cannot compare with immediate), and for these particular examples it's better to calculate `(x - 0x555)` or `(x ^ 0x555)` first and compare that result with zero.