Index: gcc/postreload.c
===================================================================
--- gcc/postreload.c	2017-07-13 09:18:35.050126461 +0100
+++ gcc/postreload.c	2017-07-13 09:18:37.226935948 +0100
@@ -1692,7 +1692,7 @@ move2add_record_sym_value (rtx reg, rtx
 /* Check if REGNO contains a valid value in MODE.  */
 
 static bool
-move2add_valid_value_p (int regno, machine_mode mode)
+move2add_valid_value_p (int regno, scalar_int_mode mode)
 {
   if (reg_set_luid[regno] <= move2add_last_label_luid)
     return false;
@@ -1723,21 +1723,21 @@ move2add_valid_value_p (int regno, machi
   return true;
 }
 
-/* This function is called with INSN that sets REG to (SYM + OFF),
-   while REG is known to already have value (SYM + offset).
+/* This function is called with INSN that sets REG (of mode MODE)
+   to (SYM + OFF), while REG is known to already have value (SYM + offset).
    This function tries to change INSN into an add instruction
    (set (REG) (plus (REG) (OFF - offset))) using the known value.
    It also updates the information about REG's known value.
    Return true if we made a change.  */
 
 static bool
-move2add_use_add2_insn (rtx reg, rtx sym, rtx off, rtx_insn *insn)
+move2add_use_add2_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
+			rtx_insn *insn)
 {
   rtx pat = PATTERN (insn);
   rtx src = SET_SRC (pat);
   int regno = REGNO (reg);
-  rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[regno],
-			      GET_MODE (reg));
+  rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[regno], mode);
   bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
   bool changed = false;
 
@@ -1759,7 +1759,7 @@ move2add_use_add2_insn (rtx reg, rtx sym
   else
     {
       struct full_rtx_costs oldcst, newcst;
-      rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src);
+      rtx tem = gen_rtx_PLUS (mode, reg, new_src);
 
       get_full_set_rtx_cost (pat, &oldcst);
       SET_SRC (pat) = tem;
@@ -1769,10 +1769,10 @@ move2add_use_add2_insn (rtx reg, rtx sym
       if (costs_lt_p (&newcst, &oldcst, speed)
 	  && have_add2_insn (reg, new_src))
 	changed = validate_change (insn, &SET_SRC (pat), tem, 0);	
-      else if (sym == NULL_RTX && GET_MODE (reg) != BImode)
+      else if (sym == NULL_RTX && mode != BImode)
 	{
-	  machine_mode narrow_mode;
-	  FOR_EACH_MODE_UNTIL (narrow_mode, GET_MODE (reg))
+	  scalar_int_mode narrow_mode;
+	  FOR_EACH_MODE_UNTIL (narrow_mode, mode)
 	    {
 	      if (have_insn_for (STRICT_LOW_PART, narrow_mode)
 		  && ((reg_offset[regno] & ~GET_MODE_MASK (narrow_mode))
@@ -1802,9 +1802,9 @@ move2add_use_add2_insn (rtx reg, rtx sym
 }
 
 
-/* This function is called with INSN that sets REG to (SYM + OFF),
-   but REG doesn't have known value (SYM + offset).  This function
-   tries to find another register which is known to already have
+/* This function is called with INSN that sets REG (of mode MODE) to
+   (SYM + OFF), but REG doesn't have known value (SYM + offset).  This
+   function tries to find another register which is known to already have
    value (SYM + offset) and change INSN into an add instruction
    (set (REG) (plus (the found register) (OFF - offset))) if such
    a register is found.  It also updates the information about
@@ -1812,7 +1812,8 @@ move2add_use_add2_insn (rtx reg, rtx sym
    Return true iff we made a change.  */
 
 static bool
-move2add_use_add3_insn (rtx reg, rtx sym, rtx off, rtx_insn *insn)
+move2add_use_add3_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
+			rtx_insn *insn)
 {
   rtx pat = PATTERN (insn);
   rtx src = SET_SRC (pat);
@@ -1831,7 +1832,7 @@ move2add_use_add3_insn (rtx reg, rtx sym
   SET_SRC (pat) = plus_expr;
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    if (move2add_valid_value_p (i, GET_MODE (reg))
+    if (move2add_valid_value_p (i, mode)
 	&& reg_base_reg[i] < 0
 	&& reg_symbol_ref[i] != NULL_RTX
 	&& rtx_equal_p (sym, reg_symbol_ref[i]))
@@ -1921,8 +1922,10 @@ reload_cse_move2add (rtx_insn *first)
       pat = PATTERN (insn);
       /* For simplicity, we only perform this optimization on
 	 straightforward SETs.  */
+      scalar_int_mode mode;
       if (GET_CODE (pat) == SET
-	  && REG_P (SET_DEST (pat)))
+	  && REG_P (SET_DEST (pat))
+	  && is_a <scalar_int_mode> (GET_MODE (SET_DEST (pat)), &mode))
 	{
 	  rtx reg = SET_DEST (pat);
 	  int regno = REGNO (reg);
@@ -1930,7 +1933,7 @@ reload_cse_move2add (rtx_insn *first)
 
 	  /* Check if we have valid information on the contents of this
 	     register in the mode of REG.  */
-	  if (move2add_valid_value_p (regno, GET_MODE (reg))
+	  if (move2add_valid_value_p (regno, mode)
               && dbg_cnt (cse2_move2add))
 	    {
 	      /* Try to transform (set (REGX) (CONST_INT A))
@@ -1950,7 +1953,8 @@ reload_cse_move2add (rtx_insn *first)
 		  && reg_base_reg[regno] < 0
 		  && reg_symbol_ref[regno] == NULL_RTX)
 		{
-		  changed |= move2add_use_add2_insn (reg, NULL_RTX, src, insn);
+		  changed |= move2add_use_add2_insn (mode, reg, NULL_RTX,
+						     src, insn);
 		  continue;
 		}
 
@@ -1967,7 +1971,7 @@ reload_cse_move2add (rtx_insn *first)
 	      else if (REG_P (src)
 		       && reg_set_luid[regno] == reg_set_luid[REGNO (src)]
 		       && reg_base_reg[regno] == reg_base_reg[REGNO (src)]
-		       && move2add_valid_value_p (REGNO (src), GET_MODE (reg)))
+		       && move2add_valid_value_p (REGNO (src), mode))
 		{
 		  rtx_insn *next = next_nonnote_nondebug_insn (insn);
 		  rtx set = NULL_RTX;
@@ -1987,7 +1991,7 @@ reload_cse_move2add (rtx_insn *first)
 			gen_int_mode (added_offset
 				      + base_offset
 				      - regno_offset,
-				      GET_MODE (reg));
+				      mode);
 		      bool success = false;
 		      bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
 
@@ -1999,11 +2003,11 @@ reload_cse_move2add (rtx_insn *first)
 			{
 			  rtx old_src = SET_SRC (set);
 			  struct full_rtx_costs oldcst, newcst;
-			  rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src);
+			  rtx tem = gen_rtx_PLUS (mode, reg, new_src);
 
 			  get_full_set_rtx_cost (set, &oldcst);
 			  SET_SRC (set) = tem;
-			  get_full_set_src_cost (tem, GET_MODE (reg), &newcst);
+			  get_full_set_src_cost (tem, mode, &newcst);
 			  SET_SRC (set) = old_src;
 			  costs_add_n_insns (&oldcst, 1);
 
@@ -2023,7 +2027,7 @@ reload_cse_move2add (rtx_insn *first)
 		      move2add_record_mode (reg);
 		      reg_offset[regno]
 			= trunc_int_for_mode (added_offset + base_offset,
-					      GET_MODE (reg));
+					      mode);
 		      continue;
 		    }
 		}
@@ -2059,16 +2063,16 @@ reload_cse_move2add (rtx_insn *first)
 
 	      /* If the reg already contains the value which is sum of
 		 sym and some constant value, we can use an add2 insn.  */
-	      if (move2add_valid_value_p (regno, GET_MODE (reg))
+	      if (move2add_valid_value_p (regno, mode)
 		  && reg_base_reg[regno] < 0
 		  && reg_symbol_ref[regno] != NULL_RTX
 		  && rtx_equal_p (sym, reg_symbol_ref[regno]))
-		changed |= move2add_use_add2_insn (reg, sym, off, insn);
+		changed |= move2add_use_add2_insn (mode, reg, sym, off, insn);
 
 	      /* Otherwise, we have to find a register whose value is sum
 		 of sym and some constant value.  */
 	      else
-		changed |= move2add_use_add3_insn (reg, sym, off, insn);
+		changed |= move2add_use_add3_insn (mode, reg, sym, off, insn);
 
 	      continue;
 	    }
