From ebac3c0236c626f80b005af53505de5b79cba99d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 24 Jul 2018 16:23:18 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 7 +++++++ gcc/expmed.c | 9 ++++++--- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/gcc.target/i386/pr86627.c | 28 ++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr86627.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ff8ed78..c7b921b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-07-24 Jakub Jelinek + + 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-24 Richard Biener * match.pd: Add BIT_FIELD_REF canonicalizations. 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) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a723a52..ca4d0bc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-07-24 Jakub Jelinek + PR middle-end/86627 + * gcc.target/i386/pr86627.c: New test. + PR testsuite/86649 * g++.dg/tree-ssa-/pr19476-1.C: Check dom2 dump instead of ccp1. * g++.dg/tree-ssa-/pr19476-5.C: Likewise. 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; +} -- 2.7.4