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;) + ; +}