https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86628

            Bug ID: 86628
           Summary: Missed simplification of division
           Product: gcc
           Version: tree-ssa
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: david.bolvansky at gmail dot com
  Target Milestone: ---

Hello,

for code:
int f(int x, int y, int z) {
   return (x * y  * z) / (y * z);
}

GCC 8.1 (x86-64) with -O3 emits:
f(int, int, int):
  mov eax, edi
  imul eax, esi
  imul esi, edx
  imul eax, edx
  cdq
  idiv esi
  ret


but one multiplication can be removed, as Clang does it:
f(int, int, int):
  imul esi, edx
  imul edi, esi
  mov eax, edi
  cdq
  idiv esi
  ret


Also, for:
unsigned f2(unsigned x, unsigned y, unsigned z) {
   return (x*z) / (y*z);
}

f2(unsigned int, unsigned int, unsigned int):
  mov eax, edi
  imul esi, edx
  imul eax, edx
  xor edx, edx
  div esi
  ret

This could be simplified to "x/y". For a signed case it could be possible too,
just z = -1 needs to be checked.

Reply via email to