Commit f8dc3fb2 by Vladimir Makarov Committed by Vladimir Makarov

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
parent a4f73f96
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> 2019-02-06 Eric Botcazou <ebotcazou@adacore.com>
* config/i386/i386.c (ix86_expand_prologue): Emit a memory blockage * config/i386/i386.c (ix86_expand_prologue): Emit a memory blockage
......
...@@ -1533,9 +1533,12 @@ simplify_operand_subreg (int nop, machine_mode reg_mode) ...@@ -1533,9 +1533,12 @@ simplify_operand_subreg (int nop, machine_mode reg_mode)
a word. a word.
If valid memory becomes invalid after subreg elimination 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), && !(maybe_ne (GET_MODE_PRECISION (mode),
GET_MODE_PRECISION (innermode)) GET_MODE_PRECISION (innermode))
&& known_le (GET_MODE_SIZE (mode), UNITS_PER_WORD) && known_le (GET_MODE_SIZE (mode), UNITS_PER_WORD)
......
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> 2019-02-06 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/opt76.adb: New test. * gnat.dg/opt76.adb: New test.
......
/* { 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);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment