[Bug rtl-optimization/89195] [7/8/9 regression] Corrupted stack offset after combine
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
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
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
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
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
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
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
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
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
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
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
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
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
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