Index: ChangeLog
===================================================================
--- ChangeLog	(revision 268403)
+++ ChangeLog	(working copy)
@@ -1,3 +1,9 @@
+2019-01-30  Vladimir Makarov  <vmakarov@redhat.com>
+
+	PR rtl-optimization/87246
+	* lra-constraints.c (simplify_operand_subreg): Reload memory
+	in subreg if the address became invalid.
+
 2019-01-30  Bill Schmidt  <wschmidt@linux.ibm.com>
 
 	PR target/87064
Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 268117)
+++ lra-constraints.c	(working copy)
@@ -1497,10 +1497,11 @@ simplify_operand_subreg (int nop, machin
       alter_subreg (curr_id->operand_loc[nop], false);
       rtx subst = *curr_id->operand_loc[nop];
       lra_assert (MEM_P (subst));
-
+      const bool addr_is_valid = valid_address_p (GET_MODE (subst),
+						  XEXP (subst, 0),
+						  MEM_ADDR_SPACE (subst));
       if (!addr_was_valid
-	  || valid_address_p (GET_MODE (subst), XEXP (subst, 0),
-			      MEM_ADDR_SPACE (subst))
+	  || addr_is_valid
 	  || ((get_constraint_type (lookup_constraint
 				    (curr_static_id->operand[nop].constraint))
 	       != CT_SPECIAL_MEMORY)
@@ -1529,12 +1530,17 @@ simplify_operand_subreg (int nop, machin
 	     data into a register when the inner is narrower than outer or
 	     missing important data from memory when the inner is wider than
 	     outer.  This rule only applies to modes that are no wider than
-	     a word.  */
-	  if (!(maybe_ne (GET_MODE_PRECISION (mode),
-			  GET_MODE_PRECISION (innermode))
-		&& known_le (GET_MODE_SIZE (mode), UNITS_PER_WORD)
-		&& known_le (GET_MODE_SIZE (innermode), UNITS_PER_WORD)
-		&& WORD_REGISTER_OPERATIONS)
+	     a word.
+
+	     If valid memory becomes invalid after subreg elimination
+	     we still have to reload memory.
+	  */
+	  if ((! addr_was_valid || addr_is_valid)
+	      && !(maybe_ne (GET_MODE_PRECISION (mode),
+			     GET_MODE_PRECISION (innermode))
+		   && known_le (GET_MODE_SIZE (mode), UNITS_PER_WORD)
+		   && known_le (GET_MODE_SIZE (innermode), UNITS_PER_WORD)
+		   && WORD_REGISTER_OPERATIONS)
 	      && (!(MEM_ALIGN (subst) < GET_MODE_ALIGNMENT (mode)
 		    && targetm.slow_unaligned_access (mode, MEM_ALIGN (subst)))
 		  || (MEM_ALIGN (reg) < GET_MODE_ALIGNMENT (innermode)
@@ -1553,7 +1559,7 @@ simplify_operand_subreg (int nop, machin
 	  enum reg_class rclass
 	    = (enum reg_class) targetm.preferred_reload_class (reg, ALL_REGS);
 	  if (get_reload_reg (curr_static_id->operand[nop].type, innermode,
-			      reg, rclass, TRUE, "slow mem", &new_reg))
+			      reg, rclass, TRUE, "slow/invalid mem", &new_reg))
 	    {
 	      bool insert_before, insert_after;
 	      bitmap_set_bit (&lra_subreg_reload_pseudos, REGNO (new_reg));
@@ -1572,7 +1578,7 @@ simplify_operand_subreg (int nop, machin
 	  rclass
 	    = (enum reg_class) targetm.preferred_reload_class (reg, ALL_REGS);
 	  if (get_reload_reg (curr_static_id->operand[nop].type, mode, reg,
-			      rclass, TRUE, "slow mem", &new_reg))
+			      rclass, TRUE, "slow/invalid mem", &new_reg))
 	    {
 	      bool insert_before, insert_after;
 	      bitmap_set_bit (&lra_subreg_reload_pseudos, REGNO (new_reg));
@@ -1585,7 +1591,7 @@ simplify_operand_subreg (int nop, machin
 	    }
 	  *curr_id->operand_loc[nop] = new_reg;
 	  lra_process_new_insns (curr_insn, before, after,
-				 "Inserting slow mem reload");
+				 "Inserting slow/invalid mem reload");
 	  return true;
 	}
 
Index: testsuite/ChangeLog
===================================================================
--- testsuite/ChangeLog	(revision 268403)
+++ testsuite/ChangeLog	(working copy)
@@ -1,3 +1,8 @@
+2019-01-30  Vladimir Makarov  <vmakarov@redhat.com>
+
+	PR rtl-optimization/87246
+	* gcc.target/i386/pr87246.c: New.
+
 2019-01-30  Marek Polacek  <polacek@redhat.com>
 
 	PR c++/89119 - ICE with value-initialization in template.
@@ -15,7 +20,7 @@
 	* gcc.target/powerpc/vec-extract-uint128-1.c: New test.
 	* gcc.target/powerpc/vec-extract-ulong-1.c: New test.
 	* gcc.target/powerpc/vec-extract-ushort-1.c: New test.
-	
+
 2019-01-30  Richard Biener  <rguenther@suse.de>
 
 	PR tree-optimization/89111
Index: testsuite/gcc.target/i386/pr87246.c
===================================================================
--- testsuite/gcc.target/i386/pr87246.c	(nonexistent)
+++ testsuite/gcc.target/i386/pr87246.c	(working copy)
@@ -0,0 +1,22 @@
+/* PR rtl-optimization/87246 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -w -fnon-call-exceptions -fno-split-wide-types" } */
+
+__int128 zd;
+int c1;
+
+void
+s2 (__int128 *qv)
+{
+  if (*qv != 0)
+    {
+      zd = 0;
+      c1 = c1 <= *qv;
+    }
+}
+
+void
+lt (unsigned int vb)
+{
+  s2 (vb + 1);
+}
