diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7dce604..0cb7cfd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
 2018-06-12  Richard Sandiford  <richard.sandiford@linaro.org>
 
+	* lra-constraints.c (simplify_operand_subreg): In the paradoxical
+	case, check whether the outer register overlaps an unallocatable
+	register, not just whether it fits the required class.
+
+2018-06-12  Richard Sandiford  <richard.sandiford@linaro.org>
+
 	* poly-int.h (can_div_trunc_p): Add new overload in which all values
 	are poly_ints.
 	* alias.c (get_addr): Extend CONST_INT handling to poly_int_rtx_p.
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 5405c4d..7eeec76 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -1722,7 +1722,13 @@ simplify_operand_subreg (int nop, machine_mode reg_mode)
         (subreg:TI (reg:TI 180 [orig:107 __comp ] [107]) 0)) {*movti_internal_rex64}
 
      Two reload hard registers will be allocated to reg180 to save TImode data
-     in LRA_assign.  */
+     in LRA_assign.
+
+     For LRA pseudos this should normally be handled by the biggest_mode
+     mechanism.  However, it's possible for new uses of an LRA pseudo
+     to be introduced after we've allocated it, such as when undoing
+     inheritance, and the allocated register might not then be appropriate
+     for the new uses.  */
   else if (REG_P (reg)
 	   && REGNO (reg) >= FIRST_PSEUDO_REGISTER
 	   && (hard_regno = lra_get_regno_hard_regno (REGNO (reg))) >= 0
@@ -1731,7 +1737,9 @@ simplify_operand_subreg (int nop, machine_mode reg_mode)
 	   && (regclass = lra_get_allocno_class (REGNO (reg)))
 	   && (type != OP_IN
 	       || !in_hard_reg_set_p (reg_class_contents[regclass],
-				      mode, hard_regno)))
+				      mode, hard_regno)
+	       || overlaps_hard_reg_set_p (lra_no_alloc_regs,
+					   mode, hard_regno)))
     {
       /* The class will be defined later in curr_insn_transform.  */
       enum reg_class rclass
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 72d8a6a..5f01694 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2018-06-12  Richard Sandiford  <richard.sandiford@linaro.org>
+
+	* g++.dg/torture/aarch64-vect-init-1.C: New test.
+
 2018-06-12  Paolo Carlini  <paolo.carlini@oracle.com>
 
 	* g++.dg/init/delete3.C: New.
diff --git a/gcc/testsuite/g++.dg/torture/aarch64-vect-init-1.C b/gcc/testsuite/g++.dg/torture/aarch64-vect-init-1.C
new file mode 100644
index 0000000..681b71a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/aarch64-vect-init-1.C
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mcpu=cortex-a72" { target aarch64*-*-* } } */
+
+class A {
+public:
+  unsigned char *fn1();
+  int fn2();
+};
+
+class B {
+  A fld1;
+  int fld2;
+  void fn3();
+  unsigned char fld3;
+};
+
+int a;
+
+void
+B::fn3() {
+  int b = fld1.fn2() / 8;
+  unsigned char *c = fld1.fn1(), *d = &fld3, *e = c;
+  for (; a < fld2;)
+    for (int j = 0; j < b; j++)
+      *d++ = e[j];
+  for (; 0 < fld2;)
+    for (int j = 0; j < b; j++)
+      e[j] = *d++;
+  for (; fld2;)
+    ;
+}