diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index f44f52ea1bac5c6da34c1e157818a4d5f2dbeca4..0adcc5ac1dba0087704ec74d95392cc84ab177b9 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,8 @@
+2012-03-31  Eric Botcazou  <ebotcazou@adacore.com>
+
+	* config/ia64/unwind-ia64.c (uw_install_context): Manually save LC
+	if it hasn't been previously saved.
+
 2012-03-29  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* config/i386/linux-unwind.h (x86_64_fallback_frame_state): Define
diff --git a/libgcc/config/ia64/unwind-ia64.c b/libgcc/config/ia64/unwind-ia64.c
index 10cf1363b1bd80f57a67f6f9e0167ccac1469089..2bb9100a4995936b1a45e9c7f529fc2a0dc8abff 100644
--- a/libgcc/config/ia64/unwind-ia64.c
+++ b/libgcc/config/ia64/unwind-ia64.c
@@ -2169,8 +2169,20 @@ uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
 		    struct _Unwind_Context *target)
 {
   unw_word ireg_buf[4], ireg_nat = 0, ireg_pr = 0;
+  unw_word saved_lc;
   int i;
 
+  /* ??? LC is a fixed register so the call to __builtin_unwind_init in
+     uw_init_context doesn't cause it to be saved.  In case it isn't in
+     the user frames either, we need to manually do so here, lest it be
+     clobbered by the loop just below.  */
+  if (target->lc_loc == NULL)
+    {
+      register unw_word lc asm ("ar.lc");
+      saved_lc = lc;
+      target->lc_loc = &saved_lc;
+    }
+
   /* Copy integer register data from the target context to a
      temporary buffer.  Do this so that we can frob AR.UNAT
      to get the NaT bits for these registers set properly.  */