diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 71cdd934b69b06fbb934d8a1bf0ca779b396daa5..1c56ebe37b8e0232f9859f0f8b9be81956b1586c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2012-02-08  Andrew MacLeod  <amacleod@redhat.com>
+
+	* optabs.c (expand_atomic_load): Do not assume compare_and_swap will
+	always succeed for integers larger than a native word.
+
 2012-02-08  Richard Guenther  <rguenther@suse.de>
 
 	PR rtl-optimization/52170
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 87cce8ef4b0430a0f1b2dd929d2c1b3af1817a76..b0ecdf0513eef86514f07b3f9df14e2d9de05d96 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -7665,9 +7665,12 @@ expand_atomic_load (rtx target, rtx mem, enum memmodel model)
       /* Issue val = compare_and_swap (mem, 0, 0).
 	 This may cause the occasional harmless store of 0 when the value is
 	 already 0, but it seems to be OK according to the standards guys.  */
-      expand_atomic_compare_and_swap (NULL, &target, mem, const0_rtx,
-				      const0_rtx, false, model, model);
-      return target;
+      if (expand_atomic_compare_and_swap (NULL, &target, mem, const0_rtx,
+					  const0_rtx, false, model, model))
+	return target;
+      else
+      /* Otherwise there is no atomic load, leave the library call.  */
+        return NULL_RTX;
     }
 
   /* Otherwise assume loads are atomic, and emit the proper barriers.  */