https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81346
Bug ID: 81346 Summary: Missed constant propagation into comparison Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: gergo.barany at inria dot fr Target Milestone: --- Created attachment 41694 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41694&action=edit Input C file for triggering the issue The attached C file contains the following function: int fn1(int p1) { int b = (p1 / 12 == 6); return b; } As these are integers, the expression (p1 / 12 == 6) can be optimized to a subtraction and an unsigned compare. GCC can do this (here for ARM): fn1: sub r0, r0, #72 cmp r0, #11 movhi r0, #0 movls r0, #1 bx lr The attached file also contains the following function: int fn2(int p1) { int a = 6; int b = (p1 / 12 == a); return b; } This is equivalent to the above code; the value of a can only ever be 6. Consequently, the output machine code should be equivalent. However, GCC does not recognize the above pattern and generates more complex code: fn2: movw r3, #43691 movt r3, 10922 smull r2, r3, r3, r0 asr r0, r0, #31 rsb r0, r0, r3, asr #1 sub r0, r0, #6 clz r0, r0 lsr r0, r0, #5 bx lr I believe this is a target-independent optimization issue because x86-64 and PowerPC behave analogously, for example (x86-64): fn1: subl $72, %edi xorl %eax, %eax cmpl $11, %edi setbe %al ret fn2: movl %edi, %eax movl $715827883, %edx sarl $31, %edi imull %edx xorl %eax, %eax sarl %edx subl %edi, %edx cmpl $6, %edx sete %al ret Version: gcc version 8.0.0 20170706 (experimental) (GCC) Configured with: --target=armv7a-eabihf --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float-abi=hard --with-float=hard or with: --target=x86_64-pc-linux-gnu or with: --target=ppc-eabi