re PR rtl-optimization/89225 (LRA hang on ppc64le compiling glibc starting with r268404)
authorVladimir Makarov <vmakarov@redhat.com>
Wed, 6 Feb 2019 21:48:45 +0000 (21:48 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Wed, 6 Feb 2019 21:48:45 +0000 (21:48 +0000)
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

gcc/ChangeLog
gcc/lra-constraints.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr89225.c [new file with mode: 0644]

index 21d1434ce6f96548887a87932d3bef16b96f5701..3b8a343f1d590a84eacca8760004a3c1fe496e9e 100644 (file)
@@ -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
index d581513f33f4be33ca3242003dfea658fbc144ca..3b975cc2c9ab405fb436cfc1cd4d38efff7db81c 100644 (file)
@@ -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)
index ad12b335f581b4343ad07c39f2b98774d45597e6..32b3cb18c380a7cad6f2dc86932763006724a888 100644 (file)
@@ -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 (file)
index 0000000..ac7f853
--- /dev/null
@@ -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);
+    }
+}