From: Jakub Jelinek Date: Fri, 12 Oct 2018 14:53:11 +0000 (+0200) Subject: backport: re PR middle-end/86627 (Signed 128-bit division by 2 no longer expanded... X-Git-Tag: releases/gcc-7.4.0~105 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5dd76907d07ee1145d7a5ff8b9c0983695da404b;p=thirdparty%2Fgcc.git 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 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6f147d3a1b28..8363ff264063 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,13 @@ 2018-10-12 Jakub Jelinek Backported from mainline + 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-17 Jakub Jelinek PR middle-end/86542 diff --git a/gcc/expmed.c b/gcc/expmed.c index 30001ac0a713..b9f12576b0cf 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -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) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d8a76b9b5122..c9f55dda7527 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2018-10-12 Jakub Jelinek Backported from mainline + 2018-07-24 Jakub Jelinek + + PR middle-end/86627 + * gcc.target/i386/pr86627.c: New test. + 2018-07-10 Jakub Jelinek 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 index 000000000000..5aefbed0a0b9 --- /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; +}