--- /dev/null
+diff -Naurp gcc/combine.c gcc/combine.c
+--- gcc/combine.c 2011-07-29 14:05:59.000000000 +0530
++++ gcc/combine.c 2012-06-28 15:51:12.000000000 +0530
+@@ -1666,6 +1666,7 @@ can_combine_p (rtx insn, rtx i3, rtx pre
+ rtx link;
+ #endif
+ bool all_adjacent = true;
++ int (*is_volatile_p) (const_rtx);
+
+ if (succ)
+ {
+@@ -1914,11 +1915,17 @@ can_combine_p (rtx insn, rtx i3, rtx pre
+ && REG_P (dest) && REGNO (dest) < FIRST_PSEUDO_REGISTER)
+ return 0;
+
+- /* If there are any volatile insns between INSN and I3, reject, because
+- they might affect machine state. */
+-
++ /* If INSN contains volatile references (specifically volatile MEMs),
++ we cannot combine across any other volatile references.
++ Even if INSN doesn't contain volatile references, any intervening
++ volatile insn might affect machine state. */
++
++ is_volatile_p = volatile_refs_p (PATTERN (insn))
++ ? volatile_refs_p
++ : volatile_insn_p;
++
+ for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p))
+- if (INSN_P (p) && p != succ && p != succ2 && volatile_insn_p (PATTERN (p)))
++ if (INSN_P (p) && p != succ && p != succ2 && is_volatile_p (PATTERN (p)))
+ return 0;
+
+ /* If INSN contains an autoincrement or autodecrement, make sure that
+diff -Naurp gcc/config/avr/avr.c gcc/config/avr/avr.c
+--- gcc/config/avr/avr.c 2012-06-28 15:47:34.000000000 +0530
++++ gcc/config/avr/avr.c 2012-06-28 15:51:12.000000000 +0530
+@@ -6307,6 +6307,7 @@ avr_encode_section_info (tree decl, rtx
+ if (new_decl_p
+ && decl && DECL_P (decl)
+ && NULL_TREE == DECL_INITIAL (decl)
++ && !DECL_EXTERNAL (decl)
+ && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
+ {
+ warning (OPT_Wuninitialized,