summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/i386/i386-expand.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index 7c31cc7daac..f838112783c 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -16352,12 +16352,14 @@ ix86_expand_floorceil (rtx operand0, rtx operand1, bool do_floor)
if (!isless (xa, TWO52))
return x;
x2 = (double)(long)x;
+
Compensate. Floor:
if (x2 > x)
x2 -= 1;
Compensate. Ceil:
if (x2 < x)
x2 += 1;
+
if (HONOR_SIGNED_ZEROS (mode))
return copysign (x2, x);
return x2;
@@ -16392,10 +16394,15 @@ ix86_expand_floorceil (rtx operand0, rtx operand1, bool do_floor)
emit_insn (gen_rtx_SET (tmp, gen_rtx_AND (mode, one, tmp)));
tmp = expand_simple_binop (mode, do_floor ? MINUS : PLUS,
xa, tmp, NULL_RTX, 0, OPTAB_DIRECT);
- emit_move_insn (res, tmp);
-
if (HONOR_SIGNED_ZEROS (mode))
- ix86_sse_copysign_to_positive (res, res, force_reg (mode, operand1), mask);
+ {
+ /* Remove the sign with FE_DOWNWARD, where x - x = -0.0. */
+ if (do_floor && flag_rounding_math)
+ tmp = ix86_expand_sse_fabs (tmp, NULL);
+
+ ix86_sse_copysign_to_positive (tmp, tmp, res, mask);
+ }
+ emit_move_insn (res, tmp);
emit_label (label);
LABEL_NUSES (label) = 1;
@@ -16415,12 +16422,14 @@ ix86_expand_floorceildf_32 (rtx operand0, rtx operand1, bool do_floor)
return x;
xa = xa + TWO52 - TWO52;
x2 = copysign (xa, x);
+
Compensate. Floor:
if (x2 > x)
x2 -= 1;
Compensate. Ceil:
if (x2 < x)
x2 += 1;
+
if (HONOR_SIGNED_ZEROS (mode))
x2 = copysign (x2, x);
return x2;
@@ -16457,8 +16466,14 @@ ix86_expand_floorceildf_32 (rtx operand0, rtx operand1, bool do_floor)
emit_insn (gen_rtx_SET (tmp, gen_rtx_AND (mode, one, tmp)));
tmp = expand_simple_binop (mode, do_floor ? MINUS : PLUS,
xa, tmp, NULL_RTX, 0, OPTAB_DIRECT);
- if (!do_floor && HONOR_SIGNED_ZEROS (mode))
- ix86_sse_copysign_to_positive (tmp, tmp, res, mask);
+ if (HONOR_SIGNED_ZEROS (mode))
+ {
+ /* Remove the sign with FE_DOWNWARD, where x - x = -0.0. */
+ if (do_floor && flag_rounding_math)
+ tmp = ix86_expand_sse_fabs (tmp, NULL);
+
+ ix86_sse_copysign_to_positive (tmp, tmp, res, mask);
+ }
emit_move_insn (res, tmp);
emit_label (label);