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.