aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-10-12 19:31:33 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2018-10-12 19:31:33 +0200
commit6b30e838cd7f8dc66aa69b76c8622bf375220e95 (patch)
tree5ab214903cce4de0cc9e4fe8f2937d5ee3a0a45a
parent1688485d3757ea2746e92d066c9f9041d6267350 (diff)
downloadgcc-6b30e838cd7f8dc66aa69b76c8622bf375220e95.zip
gcc-6b30e838cd7f8dc66aa69b76c8622bf375220e95.tar.gz
gcc-6b30e838cd7f8dc66aa69b76c8622bf375220e95.tar.bz2
backport: re PR middle-end/86627 (Signed 128-bit division by 2 no longer expanded to RTL)
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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/expmed.c9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr86627.c28
4 files changed, 46 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0af69b9..c09e3c7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 8e06945..2b42dee 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -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)
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 29b0483..986f6b6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..5aefbed
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr86627.c
@@ -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;
+}