https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120963
Bug ID: 120963 Summary: Missed optimization of (a > b ? a - b : 0) pattern Product: gcc Version: 15.1.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 could be multiple missed optimization issues in one same test code. I just don't know how to reduce the issues to even simpler test cases. ```c #include <stdint.h> int32_t func1a(int32_t a, int32_t b) { if (b - a < 0) a = b; return b - a; } int32_t func1b(int32_t a, int32_t b) { if (b < a) a = b; return b - a; } int32_t func1c(int32_t a, int32_t b) { if (b < a) return 0; return b - a; } ``` x86-64 gcc 15.1 with `-Os -fno-wrapv` options produces the following assembly: ```x86asm func1a: subl %edi, %esi movl $0, %eax cmovns %esi, %eax ret func1b: cmpl %edi, %esi movl %esi, %eax cmovle %esi, %edi subl %edi, %eax ret func1c: movl %esi, %eax xorl %edx, %edx subl %edi, %eax cmpl %edi, %esi cmovl %edx, %eax ret ``` Note that the three functions are equivalent, and yet the generated assembly codes are different, and none of them are optimal. The optimal code, AFAIK, is this: ```x86asm func1: xorl %eax, %eax subl %edi, %esi cmovg %esi, %eax ret ``` When compared with the assembly of three functions above: * func1a missed the part that the `movl $0, %eax` can be simplified to `xorl %eax, %eax` if the instruction is performed _before_ the `sub` instruction, the condition code of which is checked later. * As signed integer overflow is undefined behavior in C, the `cmovns` in func1a could as well be transformed to `cmovg`. (This optimization should be disabled for `-fwrapv`.) * func1c missed that the `sub` and `cmp` could be merged to one operation. This can also save the `mov` instruction at the beginning. (I have reported Bug 113680 as similar to this issue.)