diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 28309279b79362d5a1464d070624404135cc60b1..e5706fb97bea3dd565413bf105a8c0df24d68c0b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2008-03-18  Jakub Jelinek  <jakub@redhat.com>
+
+	PR middle-end/35611
+	* gimplify.c (gimplify_expr): Gimplify second operand of
+	OMP_ATOMIC_LOAD.
+
 2008-03-17  Richard Guenther  <rguenther@suse.de>
 
 	PR tree-optimization/19637
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index a75c711384fbc2bea874d4719e93972c2545a7f8..102ce3e7354cb34e3d1516d52d00528dbd3c5d0c 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -6022,12 +6022,18 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
 
 	case OMP_RETURN:
 	case OMP_CONTINUE:
-        case OMP_ATOMIC_LOAD:
-        case OMP_ATOMIC_STORE:
-
+	case OMP_ATOMIC_STORE:
 	  ret = GS_ALL_DONE;
 	  break;
 
+	case OMP_ATOMIC_LOAD:
+	  if (gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, NULL,
+	      is_gimple_val, fb_rvalue) != GS_ALL_DONE)
+	    ret = GS_ERROR;
+	  else
+	    ret = GS_ALL_DONE;
+	  break;
+
 	case POINTER_PLUS_EXPR:
           /* Convert ((type *)A)+offset into &A->field_of_type_and_offset.
 	     The second is gimple immediate saving a need for extra statement.
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 5c548844a7a1bc99432567265e905e65e92401d0..c456e7d8ef3e87b8d6e6387a272ab668c61f1e21 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,5 +1,8 @@
 2008-03-18  Jakub Jelinek  <jakub@redhat.com>
 
+	PR middle-end/35611
+	* testsuite/libgomp.c/atomic-4.c: New test.
+
 	PR libgomp/35625
 	* iter.c (gomp_iter_guided_next_locked): If q > n, set end to ws->end.
 	(gomp_iter_guided_next): Likewise.
diff --git a/libgomp/testsuite/libgomp.c/atomic-4.c b/libgomp/testsuite/libgomp.c/atomic-4.c
new file mode 100644
index 0000000000000000000000000000000000000000..10f8197b0b61d9c8cc81af299a6c4be77836b621
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/atomic-4.c
@@ -0,0 +1,18 @@
+/* PR middle-end/35611 */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+
+int
+main (void)
+{
+  long double d = .0L;
+  int i;
+  #pragma omp parallel for shared (d)
+    for (i = 0; i < 1000; i++)
+      #pragma omp atomic
+	d += 1.0L;
+  if (d != 1000.0L)
+    abort ();
+  return 0;
+}