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

            Bug ID: 91739
           Summary: Missed optimization for arithmetic operations of
                    integers and floating point constants
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: antoshkka at gmail dot com
  Target Milestone: ---

Consider the example:

double foo(unsigned i, unsigned j) {
  return i * 4.0 + j * 7.0;
}

Right now GCC emits code that converts integers to a floating points and does
the multiplications:

foo(unsigned int, unsigned int): # @foo(unsigned int, unsigned int)
  mov eax, edi
  cvtsi2sd xmm1, rax
  mulsd xmm1, qword ptr [rip + .LCPI0_0]
  mov eax, esi
  cvtsi2sd xmm0, rax
  mulsd xmm0, qword ptr [rip + .LCPI0_1]
  addsd xmm0, xmm1
  ret

However it is possible to do better. If the max value of integer multiplied by
the floating point constant fits into the mantissa and there is an integral
type that could also hold the value then do the multiplication using integers:

double foo2(unsigned i, unsigned j) {
  return i * 4ull + j * 7ull;
}

This results in a much better code:

foo2(unsigned int, unsigned int): # @foo2(unsigned int, unsigned int)
  mov eax, edi
  mov ecx, esi
  lea rdx, [8*rcx]
  sub rdx, rcx
  lea rax, [rdx + 4*rax]
  cvtsi2sd xmm0, rax
  ret

Reply via email to