[Bug rtl-optimization/89195] [7/8/9 regression] Corrupted stack offset after combine

2019-02-04 Thread wilco at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89195

Wilco  changed:

   What|Removed |Added

 Target||aarch64
   Target Milestone|--- |9.0
  Known to fail||7.0, 8.0, 9.0

[Bug rtl-optimization/89195] [7/8/9 regression] Corrupted stack offset after combine

2019-02-04 Thread wilco at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89195

--- Comment #1 from Wilco  ---
make_extraction does:

  if (MEM_P (inner))
{
  poly_int64 offset;

  /* POS counts from lsb, but make OFFSET count in memory order.  */
  if (BYTES_BIG_ENDIAN)
offset = bits_to_bytes_round_down (GET_MODE_PRECISION (is_mode)
   - len - pos);
  else
offset = pos / BITS_PER_UNIT;
  new_rtx = adjust_address_nv (inner, tmode, offset);

len is unsigned HOST_WIDE_INT, so bits_to_bytes_round_down does an unsigned
division...

[Bug rtl-optimization/89195] [7/8/9 regression] Corrupted stack offset after combine

2019-02-04 Thread segher at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89195

Segher Boessenkool  changed:

   What|Removed |Added

 CC||segher at gcc dot gnu.org

--- Comment #2 from Segher Boessenkool  ---
r256198 did

  /* POS counts from lsb, but make OFFSET count in memory order.  */
  if (BYTES_BIG_ENDIAN)
-   offset = (GET_MODE_PRECISION (is_mode) - len - pos) /
BITS_PER_UNIT;
+   offset = bits_to_bytes_round_down (GET_MODE_PRECISION (is_mode)
+  - len - pos);
  else
offset = pos / BITS_PER_UNIT;

Was it correct before that?  At least it was symmetric so it *seemed* correct..

[Bug rtl-optimization/89195] [7/8/9 regression] Corrupted stack offset after combine

2019-02-04 Thread segher at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89195

--- Comment #3 from Segher Boessenkool  ---
(In reply to Wilco from comment #1)
> len is unsigned HOST_WIDE_INT, so bits_to_bytes_round_down does an unsigned
> division...

That shouldn't make a difference though, both dividend and divisor should be
non-negative.  Are they?  Well I guess not...  So pos points outside of the
register here?!

[Bug rtl-optimization/89195] [7/8/9 regression] Corrupted stack offset after combine

2019-02-05 Thread wilco at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89195

--- Comment #4 from Wilco  ---
(In reply to Segher Boessenkool from comment #3)
> (In reply to Wilco from comment #1)
> > len is unsigned HOST_WIDE_INT, so bits_to_bytes_round_down does an unsigned
> > division...
> 
> That shouldn't make a difference though, both dividend and divisor should be
> non-negative.  Are they?  Well I guess not...  So pos points outside of the
> register here?!

pos is a frame offset so always negative. And yes this code is then creating an
access outside the original object (starting at -1 or +1 depending on
endianness).

> Was it correct before that?  At least it was symmetric so it *seemed* 
> correct..

It was broken in the same way. If I cast just len to HOST_WIDE_INT it works
fine.

[Bug rtl-optimization/89195] [7/8/9 regression] Corrupted stack offset after combine

2019-02-05 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89195

Richard Biener  changed:

   What|Removed |Added

   Keywords||wrong-code
   Priority|P3  |P2
   Target Milestone|9.0 |7.5

[Bug rtl-optimization/89195] [7/8/9 regression] Corrupted stack offset after combine

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

Jakub Jelinek  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2019-02-05
 CC||jakub at gcc dot gnu.org
 Ever confirmed|0   |1

--- Comment #5 from Jakub Jelinek  ---
Started with r242414 aka PR77881 fix.

[Bug rtl-optimization/89195] [7/8/9 regression] Corrupted stack offset after combine

2019-02-05 Thread segher at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89195

--- Comment #6 from Segher Boessenkool  ---
pos should be always non-negative.  pos is the offset (in bits, counted from
the right) in the *field*.

[Bug rtl-optimization/89195] [7/8/9 regression] Corrupted stack offset after combine

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

--- Comment #7 from Jakub Jelinek  ---
While I can see how doing - (HOST_WIDE_INT) len instead of - len fixes the ICE,
I wonder if what make_extraction does isn't invalid.
In particular, we have later on:
  /* Unless INNER is not MEM, reject this if we would be spanning bytes or
 if the position is not a constant and the length is not 1.  In all
 other cases, we would only be going outside our object in cases when
 an original shift would have been undefined.  */
  if (MEM_P (inner)
  && ((pos_rtx == 0 && maybe_gt (pos + len, GET_MODE_PRECISION (is_mode)))
  || (pos_rtx != 0 && len != 1)))
return 0;
and I think we need this !maybe_gt (pos + len, GET_MODE_PRECISION (is_mode)))
even in the:
  || (MEM_P (inner) && pos_rtx == 0
  && (pos
  % (STRICT_ALIGNMENT ? GET_MODE_ALIGNMENT (tmode)
 : BITS_PER_UNIT)) == 0
  /* We can't do this if we are widening INNER_MODE (it
 may not be aligned, for one thing).  */
  && !paradoxical_subreg_p (tmode, inner_mode)
  && (inner_mode == tmode
  || (! mode_dependent_address_p (XEXP (inner, 0),
  MEM_ADDR_SPACE (inner))
  && ! MEM_VOLATILE_P (inner))
conditions, because otherwise we have a MEM and we try to read some other bytes
outside of that MEM, but those might not be accessible at all etc.
So, add && known_le (pos + len, GET_MODE_PRECISION (is_mode)) here?

[Bug rtl-optimization/89195] [7/8/9 regression] Corrupted stack offset after combine

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

--- Comment #8 from Jakub Jelinek  ---
Created attachment 45606
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45606&action=edit
gcc9-pr89195.patch

Now in patch form (untested so far).

[Bug rtl-optimization/89195] [7/8/9 regression] Corrupted stack offset after combine

2019-02-05 Thread segher at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89195

--- Comment #9 from Segher Boessenkool  ---
That patch is pre-approved if it regchecks fine (on more than just x86). 
Thanks!

[Bug rtl-optimization/89195] [7/8/9 regression] Corrupted stack offset after combine

2019-02-05 Thread wilco at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89195

--- Comment #10 from Wilco  ---
(In reply to Jakub Jelinek from comment #8)
> Created attachment 45606 [details]
> gcc9-pr89195.patch
> 
> Now in patch form (untested so far).

That works fine indeed. It avoids accessing the object out of bounds but still
allows the optimization for eg. i:16 using a 16-bit access within the struct.

[Bug rtl-optimization/89195] [7/8/9 regression] Corrupted stack offset after combine

2019-02-05 Thread wilco at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89195

--- Comment #11 from Wilco  ---
(In reply to Segher Boessenkool from comment #9)
> That patch is pre-approved if it regchecks fine (on more than just x86). 
> Thanks!

check-gcc is clean on aarch64_be-none-elf

[Bug rtl-optimization/89195] [7/8/9 regression] Corrupted stack offset after combine

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

--- Comment #12 from Jakub Jelinek  ---
Author: jakub
Date: Tue Feb  5 15:38:57 2019
New Revision: 268542

URL: https://gcc.gnu.org/viewcvs?rev=268542&root=gcc&view=rev
Log:
PR rtl-optimization/89195
* combine.c (make_extraction): For MEMs, don't extract bytes outside
of the original MEM.

* gcc.c-torture/execute/pr89195.c: New test.

Added:
trunk/gcc/testsuite/gcc.c-torture/execute/pr89195.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/combine.c
trunk/gcc/testsuite/ChangeLog