]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR middle-end/86627 (Signed 128-bit division by 2 no longer expanded...
authorJakub Jelinek <jakub@redhat.com>
Fri, 12 Oct 2018 17:31:33 +0000 (19:31 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 12 Oct 2018 17:31:33 +0000 (19:31 +0200)
Backported from mainline
2018-07-24  Jakub Jelinek  <jakub@redhat.com>

PR middle-end/86627
* expmed.c (expand_divmod): Punt if d == HOST_WIDE_INT_MIN
and size > HOST_BITS_PER_WIDE_INT.  For size > HOST_BITS_PER_WIDE_INT
and abs_d == d, do the power of two handling if profitable.

* gcc.target/i386/pr86627.c: New test.

From-SVN: r265119

gcc/ChangeLog
gcc/expmed.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr86627.c [new file with mode: 0644]

index 0af69b9be55dcc19c56d976d40887fbc1be09292..c09e3c77a846a9544a913d48d12f16c47325d4e1 100644 (file)
@@ -1,6 +1,13 @@
 2018-10-12  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2018-07-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/86627
+       * expmed.c (expand_divmod): Punt if d == HOST_WIDE_INT_MIN
+       and size > HOST_BITS_PER_WIDE_INT.  For size > HOST_BITS_PER_WIDE_INT
+       and abs_d == d, do the power of two handling if profitable.
+
        2018-07-17  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/86542
index 8e069455bc2b5b2c8186617d116eaf298f75e16f..2b42deedb65da59ac3db3f9367810566de24daea 100644 (file)
@@ -4345,6 +4345,11 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
                HOST_WIDE_INT d = INTVAL (op1);
                unsigned HOST_WIDE_INT abs_d;
 
+               /* Not prepared to handle division/remainder by
+                  0xffffffffffffffff8000000000000000 etc.  */
+               if (d == HOST_WIDE_INT_MIN && size > HOST_BITS_PER_WIDE_INT)
+                 break;
+
                /* Since d might be INT_MIN, we have to cast to
                   unsigned HOST_WIDE_INT before negating to avoid
                   undefined signed overflow.  */
@@ -4388,9 +4393,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
                                                compute_mode)
                                 != CODE_FOR_nothing)))
                  ;
-               else if (EXACT_POWER_OF_2_OR_ZERO_P (abs_d)
-                        && (size <= HOST_BITS_PER_WIDE_INT
-                            || abs_d != (unsigned HOST_WIDE_INT) d))
+               else if (EXACT_POWER_OF_2_OR_ZERO_P (abs_d))
                  {
                    if (rem_flag)
                      {
index 29b048361a5fdd5e971f41b674ce603ce94229f6..986f6b6fdd5f0a67ea9c31e2b42ffb1ca9a47a59 100644 (file)
@@ -1,6 +1,11 @@
 2018-10-12  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2018-07-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/86627
+       * gcc.target/i386/pr86627.c: New test.
+
        2018-07-16  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/3698
diff --git a/gcc/testsuite/gcc.target/i386/pr86627.c b/gcc/testsuite/gcc.target/i386/pr86627.c
new file mode 100644 (file)
index 0000000..5aefbed
--- /dev/null
@@ -0,0 +1,28 @@
+/* PR middle-end/86627 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "call\[^\n\r]*__divti3" } } */
+
+__int128_t
+f1 (__int128_t a)
+{
+  return a / 2;
+}
+
+__int128_t
+f2 (__int128_t a)
+{
+  return a / -2;
+}
+
+__int128_t
+f3 (__int128_t a)
+{
+  return a / 0x4000000000000000LL;
+}
+
+__int128_t
+f4 (__int128_t a)
+{
+  return a / -0x4000000000000000LL;
+}