2017-03-08 Bernd Schmidt PR target/70549 * config/aarch64/aarch64.c (aarch64_secondary_reload): Reload CORE_REGS rclass constants in [SD]Fmode through FP_REGS. * g++.dg/opt/pr70549.C: New test. --- gcc/config/aarch64/aarch64.c.jj 2017-03-08 15:50:55.000000000 +0100 +++ gcc/config/aarch64/aarch64.c 2017-03-08 16:01:15.426080172 +0100 @@ -3846,8 +3846,13 @@ aarch64_secondary_reload (bool in_p ATTR && GET_MODE_SIZE (mode) == 16 && MEM_P (x)) return FP_REGS; + if (rclass == CORE_REGS + && (mode == SFmode || mode == DFmode) + && CONSTANT_P (x)) + return FP_REGS; + if (rclass == FP_REGS && (mode == TImode || mode == TFmode) && CONSTANT_P(x)) - return CORE_REGS; + return CORE_REGS; return NO_REGS; } --- gcc/testsuite/g++.dg/opt/pr70549.C.jj 2017-03-08 16:02:45.104918249 +0100 +++ gcc/testsuite/g++.dg/opt/pr70549.C 2017-03-08 16:02:14.000000000 +0100 @@ -0,0 +1,33 @@ +// PR target/70549 +// { dg-do compile } +// { dg-options "-O2" } +// { dg-additional-options "-fPIC" { target fpic } } + +struct A { float x; float y; }; +A a, b, c; +int d, e; +A bar (); +void foo (A, A); +inline A operator/ (A, A p2) { if (p2.x) return a; } +struct B { A dval; }; +int baz (A, B, A, int); + +void +test () +{ + B q; + A f, g, h, k; + h.x = 1.0; + f = h; + struct A i, j = f; + do { + i = bar (); + g = i / j; + foo (g, c); + int l = baz (k, q, b, e); + if (l) + goto cleanup; + j = i; + } while (d); +cleanup:; +}