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

            Bug ID: 109052
           Summary: Unnecessary reload with -mfpmath=both
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ubizjak at gmail dot com
  Target Milestone: ---

Following testcase:

--cut here--
double foo (double a)
{
  double tmp = a;
  asm ("" : "+t" (tmp));
  return a * tmp;
}
--cut here--

compiles with -O2 -mfpmath=both -msse2 to:

foo:
        movsd   %xmm0, -8(%rsp)
        fldl    -8(%rsp)
        fstpl   -8(%rsp)
-->     movsd   -8(%rsp), %xmm1
        mulsd   %xmm1, %xmm0
        ret

There is no need to reload from -8(%rsp) to %xmm1, mulsd accepts memory
operands. Optimal code would be:

foo:
        movsd   %xmm0, -8(%rsp)
        fldl    -8(%rsp)
        fstpl   -8(%rsp)
        mulsd   -8(%rsp), %xmm0
        ret

Please note that with -mfpmath=sse, expected code is generated.

The insns pattern is defined in i386.md:

(define_insn "*fop_<mode>_comm"
  [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
        (match_operator:MODEF 3 "binary_fp_operator"
          [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
           (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
  "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
    || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
   && COMMUTATIVE_ARITH_P (operands[3])
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
  "* return output_387_binary_op (insn, operands);"
  [(set (attr "type")
        (if_then_else (eq_attr "alternative" "1,2")
           (if_then_else (match_operand:MODEF 3 "mult_operator")
              (const_string "ssemul")
              (const_string "sseadd"))
           (if_then_else (match_operand:MODEF 3 "mult_operator")
              (const_string "fmul")
              (const_string "fop"))))
   (set_attr "isa" "*,noavx,avx")
   (set_attr "prefix" "orig,orig,vex")
   (set_attr "mode" "<MODE>")
   (set (attr "enabled")
     (if_then_else
       (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
       (if_then_else
         (eq_attr "alternative" "0")
         (symbol_ref "TARGET_MIX_SSE_I387
                      && X87_ENABLE_ARITH (<MODE>mode)")
         (const_string "*"))
       (if_then_else
         (eq_attr "alternative" "0")
         (symbol_ref "true")
         (symbol_ref "false"))))])

The difference between -mfpmath=both and -mfpmath=sse is in alternative 0,
which is enabled with -mfpmath=both and disabled with -mpmath=sse. Using -mavx
instead of -msse2 with -mfpmath=both does not solve the problem.

Reply via email to