https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121136
Bug ID: 121136 Summary: Missed optimization: (x <= 0xFFFFF) in '-Os' mode can convert to ((x >> 20) == 0) 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: --- Test code ```c #include <stdbool.h> #include <stdint.h> bool func1(uint32_t x) { return x < 0x100000U; } bool func2(uint32_t x) { return ((x >> 20) == 0); } bool func3(uint32_t x) { return ((x / 0x100000U) == 0); } ``` The three functions are equivalent. Specifically the threshold constant to be compared with is a power-of-two. If there is no shortage of temporary registers, then the right shift version (that is, func2) will likely make the smallest code. The actual result I tested in gcc is: gcc can recognize func3 and func1 are equivalent (it optimizes func3 to func1), but missed func2. Also it doesn't realize func2 can make the smallest code (at least in x86-64 and RISC-V targets; it likely misses for ARM too but I didn't test it thoroughly and so can't tell for sure). I assume `-Os` optimization mode here. This is the assembly I expected for x86-64: ``` shrl $20, %edi sete %al ret ``` And for RV64: ``` srliw a0,a0,20 seqz a0,a0 ret ``` (This issue report is related to bug 115529 - maybe I can consider this a sub-issue of it.)