Hello! According to C99, reminder function returns:
If x or y is a NaN, a NaN is returned. If x is an infinity, and y is not a NaN, a domain error occurs, and a NaN is returned. If y is zero, and x is not a NaN, a domain error occurs, and a NaN is returned. and fmod returns: If x or y is a NaN, a NaN is returned. If x is an infinity, a domain error occurs, and a NaN is returned. If y is zero, a domain error occurs, and a NaN is returned. If x is +0 (-0), and y is not zero, +0 (-0) is returned. However, x87 fprem and fprem1 instructions that are used to implement these builtin functions do not return NaN for infinities, but generate invalid-arithmetic-operand exception. Attached patch enables these builtins for finite math only, consistent with gcc documentation: '-ffinite-math-only': Allow optimizations for floating-point arithmetic that assume that arguments and results are not NaNs or +-Infs. This option is not turned on by any '-O' option since it can result in incorrect output for programs that depend on an exact implementation of IEEE or ISO rules/specifications for math functions. It may, however, yield faster code for programs that do not require the guarantees of these specifications. 2014-09-30 Uros Bizjak <ubiz...@gmail.com> * config/i386/i386.md (fmodxf3): Enable for flag_finite_math_only only. (fmod<mode>3): Ditto. (fpremxf4_i387): Ditto. (reminderxf3): Ditto. (reminder<mode>3): Ditto. (fprem1xf4_i387): Ditto. Patch was bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. The patch also fixes ieee_2.f90 testsuite failure with FX's pending IEEE support improvement patch. 2014-09-30 Uros Bizjak <ubiz...@gmail.com> * config/i386/i386.md (fmodxf3): Enable for flag_finite_math_only only. (fmod<mode>3): Ditto. (fpremxf4_i387): Ditto. (reminderxf3): Ditto. (reminder<mode>3): Ditto. (fprem1xf4_i387): Ditto. The patch will be committed to mainline and other release branches. Uros.
Index: config/i386/i386.md =================================================================== --- config/i386/i386.md (revision 215705) +++ config/i386/i386.md (working copy) @@ -13813,7 +13813,8 @@ (set (reg:CCFP FPSR_REG) (unspec:CCFP [(match_dup 2) (match_dup 3)] UNSPEC_C2_FLAG))] - "TARGET_USE_FANCY_MATH_387" + "TARGET_USE_FANCY_MATH_387 + && flag_finite_math_only" "fprem" [(set_attr "type" "fpspc") (set_attr "mode" "XF")]) @@ -13822,7 +13823,8 @@ [(use (match_operand:XF 0 "register_operand")) (use (match_operand:XF 1 "general_operand")) (use (match_operand:XF 2 "general_operand"))] - "TARGET_USE_FANCY_MATH_387" + "TARGET_USE_FANCY_MATH_387 + && flag_finite_math_only" { rtx_code_label *label = gen_label_rtx (); @@ -13845,7 +13847,8 @@ [(use (match_operand:MODEF 0 "register_operand")) (use (match_operand:MODEF 1 "general_operand")) (use (match_operand:MODEF 2 "general_operand"))] - "TARGET_USE_FANCY_MATH_387" + "TARGET_USE_FANCY_MATH_387 + && flag_finite_math_only" { rtx (*gen_truncxf) (rtx, rtx); @@ -13884,7 +13887,8 @@ (set (reg:CCFP FPSR_REG) (unspec:CCFP [(match_dup 2) (match_dup 3)] UNSPEC_C2_FLAG))] - "TARGET_USE_FANCY_MATH_387" + "TARGET_USE_FANCY_MATH_387 + && flag_finite_math_only" "fprem1" [(set_attr "type" "fpspc") (set_attr "mode" "XF")]) @@ -13893,7 +13897,8 @@ [(use (match_operand:XF 0 "register_operand")) (use (match_operand:XF 1 "general_operand")) (use (match_operand:XF 2 "general_operand"))] - "TARGET_USE_FANCY_MATH_387" + "TARGET_USE_FANCY_MATH_387 + && flag_finite_math_only" { rtx_code_label *label = gen_label_rtx (); @@ -13916,7 +13921,8 @@ [(use (match_operand:MODEF 0 "register_operand")) (use (match_operand:MODEF 1 "general_operand")) (use (match_operand:MODEF 2 "general_operand"))] - "TARGET_USE_FANCY_MATH_387" + "TARGET_USE_FANCY_MATH_387 + && flag_finite_math_only" { rtx (*gen_truncxf) (rtx, rtx);