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;
   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;
           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;
   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);
 
--- /dev/null
+/* PR target/96793 */
+/* { dg-do run { target sse2_runtime } } */
+/* { dg-require-effective-target fenv } */
+/* { dg-options "-O2 -frounding-math -msse2 -mno-sse4 -mfpmath=sse" } */
+
+#include <fenv.h>
+
+double
+__attribute__((noinline))
+test (double value)
+{
+  return __builtin_floor (value);
+}
+
+int
+main ()
+{
+  double result;
+
+  fesetround (FE_DOWNWARD);
+
+  result = test (0.25);
+
+  if (__builtin_signbit (result) != 0)
+    __builtin_abort ();
+
+  return 0;
+}