diff options
author | Jakub Jelinek <jakub@redhat.com> | 2018-10-12 19:31:33 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2018-10-12 19:31:33 +0200 |
commit | 6b30e838cd7f8dc66aa69b76c8622bf375220e95 (patch) | |
tree | 5ab214903cce4de0cc9e4fe8f2937d5ee3a0a45a | |
parent | 1688485d3757ea2746e92d066c9f9041d6267350 (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/expmed.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr86627.c | 28 |
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; +} |