diff options
author | Vladimir Makarov <vmakarov@redhat.com> | 2019-02-06 21:48:45 +0000 |
---|---|---|
committer | Vladimir Makarov <vmakarov@gcc.gnu.org> | 2019-02-06 21:48:45 +0000 |
commit | f8dc3fb2023b627e0c45ce0ed255aa77e367ca73 (patch) | |
tree | d324efb4c403f7bfa863e2d57ba2fc0507eb5b19 /gcc | |
parent | a4f73f96f182d9aff6ec63c3926a773a2a2c4075 (diff) | |
download | gcc-f8dc3fb2023b627e0c45ce0ed255aa77e367ca73.zip gcc-f8dc3fb2023b627e0c45ce0ed255aa77e367ca73.tar.gz gcc-f8dc3fb2023b627e0c45ce0ed255aa77e367ca73.tar.bz2 |
re PR rtl-optimization/89225 (LRA hang on ppc64le compiling glibc starting with r268404)
2019-02-06 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/89225
* lra-constaints.c (simplify_operand_subreg): Add subreg mode
sizes check.
2019-02-06 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/89225
* gcc.target/powerpc/pr89225.c: New.
From-SVN: r268597
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/lra-constraints.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/pr89225.c | 73 |
4 files changed, 89 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 21d1434..3b8a343 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-02-06 Vladimir Makarov <vmakarov@redhat.com> + + PR rtl-optimization/89225 + * lra-constaints.c (simplify_operand_subreg): Add subreg mode + sizes check. + 2019-02-06 Eric Botcazou <ebotcazou@adacore.com> * config/i386/i386.c (ix86_expand_prologue): Emit a memory blockage diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index d581513..3b975cc 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -1533,9 +1533,12 @@ simplify_operand_subreg (int nop, machine_mode reg_mode) a word. If valid memory becomes invalid after subreg elimination - we still have to reload memory. + and address might be different we still have to reload + memory. */ - if ((! addr_was_valid || addr_is_valid) + if ((! addr_was_valid + || addr_is_valid + || known_eq (GET_MODE_SIZE (mode), GET_MODE_SIZE (innermode))) && !(maybe_ne (GET_MODE_PRECISION (mode), GET_MODE_PRECISION (innermode)) && known_le (GET_MODE_SIZE (mode), UNITS_PER_WORD) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ad12b33..32b3cb1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-02-06 Vladimir Makarov <vmakarov@redhat.com> + + PR rtl-optimization/89225 + * gcc.target/powerpc/pr89225.c: New. + 2019-02-06 Eric Botcazou <ebotcazou@adacore.com> * gnat.dg/opt76.adb: New test. diff --git a/gcc/testsuite/gcc.target/powerpc/pr89225.c b/gcc/testsuite/gcc.target/powerpc/pr89225.c new file mode 100644 index 0000000..ac7f853 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr89225.c @@ -0,0 +1,73 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-options "-O2 -fstack-protector-strong -mlong-double-128" } */ + +extern long double foo (long double); +extern double bar (double); +typedef long long int64_t; +typedef unsigned long long uint64_t; +typedef union { int64_t i[2]; long double x; double d[2]; } mynumber; +static const double t512 = 0x1p512, tm256 = 0x1p-256, two54 = 0x1p54, twom54 = 0x1p-54; + +long double +foo (long double x) +{ + static const long double big = 134217728.0, big1 = 134217729.0; + long double t, s, i; + mynumber a, c; + uint64_t k, l; + int64_t m, n; + double d; + + a.x = x; + k = a.i[0] & 0x7fffffffffffffffL; + + if (k > 0x000fffff00000000L && k < 0x7ff0000000000000L) + { + if (x < 0) + return (big1 - big1) / (big - big); + l = (k & 0x001fffffffffffffL) | 0x3fe0000000000000L; + if ((a.i[1] & 0x7fffffffffffffffL) != 0) + { + n = (int64_t) ((l - k) * 2) >> 53; + m = (a.i[1] >> 52) & 0x7ff; + if (m == 0) + { + a.d[1] *= two54; + m = ((a.i[1] >> 52) & 0x7ff) - 54; + } + m += n; + if (m > 0) + a.i[1] = (a.i[1] & 0x800fffffffffffffL) | (m << 52); + else if (m <= -54) + { + a.i[1] &= 0x8000000000000000L; + } + else + { + m += 54; + a.i[1] = (a.i[1] & 0x800fffffffffffffL) | (m << 52); + a.d[1] *= twom54; + } + } + a.i[0] = l; + s = a.x; + d = bar (a.d[0]); + c.i[0] = 0x2000000000000000L + ((k & 0x7fe0000000000000L) >> 1); + c.i[1] = 0; + i = d; + t = 0.5L * (i + s / i); + i = 0.5L * (t + s / t); + return c.x * i; + } + else + { + if (k >= 0x7ff0000000000000L) + + return x * x + x; + if (x == 0) + return x; + if (x < 0) + return (big1 - big1) / (big - big); + return tm256 * foo (x * t512); + } +} |