diff options
author | Jakub Jelinek <jakub@redhat.com> | 2018-07-24 16:23:18 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2018-07-24 16:23:18 +0200 |
commit | ebac3c0236c626f80b005af53505de5b79cba99d (patch) | |
tree | 72d98ce93aebf63b039d8879a807402db7e0c088 /gcc/expmed.c | |
parent | 337dc307549968ed56e0ef7a60331e8a69e25b56 (diff) | |
download | gcc-ebac3c0236c626f80b005af53505de5b79cba99d.zip gcc-ebac3c0236c626f80b005af53505de5b79cba99d.tar.gz gcc-ebac3c0236c626f80b005af53505de5b79cba99d.tar.bz2 |
re PR middle-end/86627 (Signed 128-bit division by 2 no longer expanded to RTL)
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: r262948
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r-- | gcc/expmed.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c index f114eb4..101e7b8 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -4480,6 +4480,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. */ @@ -4522,9 +4527,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode, || (optab_handler (sdivmod_optab, int_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) { |