diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e8c85944ef69eab5fc7fc8e325b73a147b77a03a..7cf73cded46c815bb36565c943fe1990b5336961 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2005-08-15  Sebastian Pop  <pop@cri.ensmp.fr>
+
+	PR 23391
+	* Makefile.in (tree-chrec.o): Depends on real.h.
+	* tree-chrec.c: Include real.h.
+	(chrec_fold_plus_poly_poly, chrec_fold_multiply_poly_poly,
+	chrec_fold_plus_1): Use build_real for SCALAR_FLOAT_TYPE_P.
+	* tree-scalar-evolution.c (add_to_evolution_1,
+	interpret_rhs_modify_expr): Ditto.
+
 2005-08-15  Sebastian Pop  <pop@cri.ensmp.fr>
 
 	PR 23386
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 9234698a4764ae2ab2e7a987e59f1aa42864bb4a..d56e666a1be68108ea659b04f39732164a792f45 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1942,7 +1942,7 @@ tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
    $(TREE_H) tree-inline.h $(DIAGNOSTIC_H) $(HASHTAB_H) \
    $(TM_H) coretypes.h
 tree-chrec.o: tree-chrec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
-   $(GGC_H) $(TREE_H) tree-chrec.h tree-pass.h $(PARAMS_H) \
+   $(GGC_H) $(TREE_H) real.h tree-chrec.h tree-pass.h $(PARAMS_H) \
    $(DIAGNOSTIC_H) $(VARRAY_H) $(CFGLOOP_H) $(TREE_FLOW_H)
 tree-scalar-evolution.o: tree-scalar-evolution.c $(CONFIG_H) $(SYSTEM_H) \
    coretypes.h $(TM_H) $(GGC_H) $(TREE_H) real.h $(RTL_H) \
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23391.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23391.c
new file mode 100644
index 0000000000000000000000000000000000000000..8d2c3023d4f92e18ab650dbc75742d38a2108dac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23391.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+
+void 
+foo (int N) 
+{ 
+  int C; 
+  double R; 
+ 
+  R = 0.0; 
+  do 
+    { 
+      R += 0.001; 
+      C = (int) (R * N); 
+      if (-R * N <= R * N) 
+        { 
+          C++; 
+        } 
+    } 
+  while (C < 0); 
+ 
+  return; 
+} 
diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c
index 1a229225f80a0be40d91d64144a566e37eeec33b..87cc148c1a71dad4d20cf8325577b8e4a606b13a 100644
--- a/gcc/tree-chrec.c
+++ b/gcc/tree-chrec.c
@@ -30,6 +30,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "tm.h"
 #include "ggc.h"
 #include "tree.h"
+#include "real.h"
 #include "diagnostic.h"
 #include "varray.h"
 #include "cfgloop.h"
@@ -119,7 +120,9 @@ chrec_fold_plus_poly_poly (enum tree_code code,
 	  (CHREC_VARIABLE (poly1), 
 	   chrec_fold_minus (type, poly0, CHREC_LEFT (poly1)),
 	   chrec_fold_multiply (type, CHREC_RIGHT (poly1), 
-				build_int_cst_type (type, -1)));
+				SCALAR_FLOAT_TYPE_P (type)
+				? build_real (type, dconstm1)
+				: build_int_cst_type (type, -1)));
     }
   
   if (CHREC_VARIABLE (poly0) > CHREC_VARIABLE (poly1))
@@ -208,7 +211,9 @@ chrec_fold_multiply_poly_poly (tree type,
 						       CHREC_RIGHT (poly1)));
   /* "2*b*d".  */
   t2 = chrec_fold_multiply (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1));
-  t2 = chrec_fold_multiply (type, build_int_cst_type (type, 2), t2);
+  t2 = chrec_fold_multiply (type, SCALAR_FLOAT_TYPE_P (type)
+			    ? build_real (type, dconst2)
+			    : build_int_cst_type (type, 2), t2);
 
   var = CHREC_VARIABLE (poly0);
   return build_polynomial_chrec (var, t0,
@@ -284,8 +289,10 @@ chrec_fold_plus_1 (enum tree_code code,
 	    return build_polynomial_chrec 
 	      (CHREC_VARIABLE (op1), 
 	       chrec_fold_minus (type, op0, CHREC_LEFT (op1)),
-	       chrec_fold_multiply (type, CHREC_RIGHT (op1),
-				    build_int_cst_type (type, -1)));
+	       chrec_fold_multiply (type, CHREC_RIGHT (op1), 
+				    SCALAR_FLOAT_TYPE_P (type)
+				    ? build_real (type, dconstm1)
+				    : build_int_cst_type (type, -1)));
 
 	default:
 	  {
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index db798c025e2b094096ef4a29d83ebaaafa1ed00d..e74904797778578fc90d519250cc551fc4633c8a 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -676,7 +676,9 @@ add_to_evolution_1 (unsigned loop_nb,
 	    {
 	      var = loop_nb;
 	      left = chrec_before;
-	      right = build_int_cst (type, 0);
+	      right = SCALAR_FLOAT_TYPE_P (type)
+		? build_real (type, dconst0)
+		: build_int_cst (type, 0);
 	    }
 	  else
 	    {
@@ -1680,7 +1682,9 @@ interpret_rhs_modify_expr (struct loop *loop, tree at_stmt,
       opnd10 = TREE_OPERAND (opnd1, 0);
       chrec10 = analyze_scalar_evolution (loop, opnd10);
       chrec10 = chrec_convert (type, chrec10, at_stmt);
-      res = chrec_fold_minus (type, build_int_cst (type, 0), chrec10);
+      res = chrec_fold_multiply (type, chrec10, SCALAR_FLOAT_TYPE_P (type)
+				  ? build_real (type, dconstm1)
+				  : build_int_cst_type (type, -1));
       break;
 
     case MULT_EXPR: