[Bug rtl-optimization/89354] [7/8/9 Regression] Combine pass yields wrong code with -O2 and -msse2 for 32bit target

2019-02-14 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89354

--- Comment #5 from Jakub Jelinek  ---
Author: jakub
Date: Thu Feb 14 23:12:26 2019
New Revision: 268914

URL: https://gcc.gnu.org/viewcvs?rev=268914=gcc=rev
Log:
PR rtl-optimization/89354
* combine.c (make_extraction): Punt if extraction_mode is narrower
than len bits.

* gcc.dg/pr89354.c: New test.

Added:
branches/gcc-8-branch/gcc/testsuite/gcc.dg/pr89354.c
Modified:
branches/gcc-8-branch/gcc/ChangeLog
branches/gcc-8-branch/gcc/combine.c
branches/gcc-8-branch/gcc/testsuite/ChangeLog

[Bug rtl-optimization/89354] [7/8/9 Regression] Combine pass yields wrong code with -O2 and -msse2 for 32bit target

2019-02-14 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89354

--- Comment #4 from Jakub Jelinek  ---
Author: jakub
Date: Thu Feb 14 23:10:47 2019
New Revision: 268913

URL: https://gcc.gnu.org/viewcvs?rev=268913=gcc=rev
Log:
PR rtl-optimization/89354
* combine.c (make_extraction): Punt if extraction_mode is narrower
than len bits.

* gcc.dg/pr89354.c: New test.

Added:
trunk/gcc/testsuite/gcc.dg/pr89354.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/combine.c
trunk/gcc/testsuite/ChangeLog

[Bug rtl-optimization/89354] [7/8/9 Regression] Combine pass yields wrong code with -O2 and -msse2 for 32bit target

2019-02-14 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89354

--- Comment #3 from Jakub Jelinek  ---
Created attachment 45724
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45724=edit
gcc9-pr89354.patch

Untested fix.  I think the bug is in make_extraction, which for VOIDmode,
(mem:DI ...), 0, NULL_RTX, 33, 1, 1, 0 arguments returns strangely (for 32-bit
target) (zero_extract:SI (mem:DI ...) (const_int 33) (const_int 0)).  That
looks bogus to me, because those 33 bits can't fit into SImode.

Then make_field_assignment does:
  assign = make_extraction (VOIDmode, dest, pos, NULL_RTX, len, 1, 1, 0);
  if (assign == 0)
return x;

  machine_mode new_mode = (GET_CODE (assign) == STRICT_LOW_PART
   ? GET_MODE (XEXP (assign, 0)) : GET_MODE (assign));

which sets new_mode to SImode too, and
  src = canon_reg_for_combine (simplify_shift_const (NULL_RTX, LSHIFTRT,
 src_mode, other, pos),
   dest);
  src = force_to_mode (src, new_mode,
   len >= HOST_BITS_PER_WIDE_INT
   ? HOST_WIDE_INT_M1U
   : (HOST_WIDE_INT_1U << len) - 1,
   0);
other is (const_int 0x1) and as pos is 0, the first call just returns
the same constant, but force_to_mode turns it into const0_rtx, which is where
we lose the |= 0x1ULL.

[Bug rtl-optimization/89354] [7/8/9 Regression] Combine pass yields wrong code with -O2 and -msse2 for 32bit target

2019-02-14 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89354

Jakub Jelinek  changed:

   What|Removed |Added

 Status|NEW |ASSIGNED
   Assignee|unassigned at gcc dot gnu.org  |jakub at gcc dot gnu.org

[Bug rtl-optimization/89354] [7/8/9 Regression] Combine pass yields wrong code with -O2 and -msse2 for 32bit target

2019-02-14 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89354

--- Comment #2 from Jakub Jelinek  ---
-mno-stv also cures it.

[Bug rtl-optimization/89354] [7/8/9 Regression] Combine pass yields wrong code with -O2 and -msse2 for 32bit target

2019-02-14 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89354

Jakub Jelinek  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2019-02-14
 CC||jakub at gcc dot gnu.org
   Target Milestone|--- |7.5
Summary|Combine pass yields wrong   |[7/8/9 Regression] Combine
   |code with -O2 and -msse2|pass yields wrong code with
   |for 32bit target|-O2 and -msse2 for 32bit
   ||target
 Ever confirmed|0   |1

--- Comment #1 from Jakub Jelinek  ---
Started with r228231, will have a look.

Slightly simplified testcase:
static unsigned long long q = 0;

__attribute__((noipa)) static void
bar (void)
{
  q = (q & ~0x1ULL) | 0x1ULL;
}

int
main ()
{
  __asm volatile ("" : "+m" (q));
  bar ();
  if (q != 0x1ULL)
__builtin_abort ();
  return 0;
}