]> 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 14:53:11 +0000 (16:53 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 12 Oct 2018 14:53:11 +0000 (16:53 +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: r265109

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

index 6f147d3a1b28b58cebb8b03dc3590abb594c983c..8363ff2640631756e9574ee4095ba88c30c70841 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 30001ac0a713f99f9a13b965c73ccfd4b2da90b8..b9f12576b0cf0c07b44de8a2e207628b85326a34 100644 (file)
@@ -4314,6 +4314,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.  */
@@ -4357,9 +4362,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 d8a76b9b51228912fc6e5147d8a298c44ec8a820..c9f55dda7527ffa81467fab49c4935d1d31a4523 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-10  Jakub Jelinek  <jakub@redhat.com>
 
        PR fortran/86421
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;
+}