+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-24 Richard Biener <rguenther@suse.de>
* match.pd: Add BIT_FIELD_REF canonicalizations.
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. */
|| (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)
{
2018-07-24 Jakub Jelinek <jakub@redhat.com>
+ 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.
--- /dev/null
+/* 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;
+}