public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug target/116429] New: [LRA] [M86k] Wrong spill offset
@ 2024-08-20 9:09 schwab@linux-m68k.org
2024-08-20 17:26 ` [Bug target/116429] " matz at gcc dot gnu.org
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: schwab@linux-m68k.org @ 2024-08-20 9:09 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116429
Bug ID: 116429
Summary: [LRA] [M86k] Wrong spill offset
Product: gcc
Version: 15.0
Status: UNCONFIRMED
Keywords: ra, wrong-code
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: schwab@linux-m68k.org
Blocks: 113939
Target Milestone: ---
Target: m68k
Created attachment 58961
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58961&action=edit
io.ii
$ gcc/xg++ -B gcc/ io.ii -std=gnu++26 -S -O2 -mlra io.ii
.L1540:
move.l %d2,%d0
and.l 100(%sp),%d0
cmp.l %d0,%d2
jne .L1622
move.l %a0,48(%sp)
clr.l -(%sp)
.cfi_def_cfa_offset 96
pea 37.w
.cfi_def_cfa_offset 100
move.l %a1,-(%sp)
.cfi_def_cfa_offset 104
move.l %a2,%d0
sub.l %a1,%d0
.cfi_def_cfa_offset 108
move.l %a1,60(%sp)
move.l %d0,-(%sp)
jsr (_ZNKSt17basic_string_viewIcSt11char_traitsIcEE4findEcj.isra.0)
lea (16,%sp),%sp
.cfi_def_cfa_offset 92
move.l 44(%sp),%a1
move.l 48(%sp),%a0
60(%sp) should be 56(%sp), overwriting the value of %a0 at 48(%sp)
From the reload dump:
(insn 1033 549 550 122 (set (mem/c:SI (plus:SI (reg/f:SI 15 %sp)
(const_int 48 [0x30])) [492 %sfp+-40 S4 A16])
(reg/v/f:SI 8 %a0 [orig:69 __first ] [69])) 55 {*movsi_m68k2}
(nil))
(insn 550 1033 551 122 (set (mem:SI (pre_dec:SI (reg/f:SI 15 %sp)) [8 S4 A16])
(const_int 0 [0]))
"m68k-linux/libstdc++-v3/include/bits/chrono_io.h":478:68 discrim 1 50
{pushexthisi_const}
(expr_list:REG_ARGS_SIZE (const_int 4 [0x4])
(nil)))
(insn 551 550 552 122 (set (mem:SI (pre_dec:SI (reg/f:SI 15 %sp)) [8 S4 A16])
(const_int 37 [0x25]))
"m68k-linux/libstdc++-v3/include/bits/chrono_io.h":478:68 discrim 1 50
{pushexthisi_const}
(expr_list:REG_ARGS_SIZE (const_int 8 [0x8])
(nil)))
(insn 552 551 553 122 (set (mem/f:SI (pre_dec:SI (reg/f:SI 15 %sp)) [3 S4
A16])
(reg/f:SI 9 %a1 [orig:37 _19 ] [37]))
"m68k-linux/libstdc++-v3/include/bits/chrono_io.h":478:68 discrim 1 55
{*movsi_m68k2}
(expr_list:REG_ARGS_SIZE (const_int 12 [0xc])
(nil)))
(note 553 552 996 122 NOTE_INSN_DELETED)
(insn 996 553 554 122 (set (reg:SI 0 %d0 [262])
(reg/v/f:SI 10 %a2 [orig:116 <retval> ] [116]))
"m68k-linux/libstdc++-v3/include/bits/chrono_io.h":478:68 discrim 1 55
{*movsi_m68k2}
(nil))
(insn 554 996 1031 122 (set (reg:SI 0 %d0 [262])
(minus:SI (reg:SI 0 %d0 [262])
(reg/f:SI 9 %a1 [orig:37 _19 ] [37])))
"m68k-linux/libstdc++-v3/include/bits/chrono_io.h":478:68 discrim 1 176
{subsi3}
(expr_list:REG_ARGS_SIZE (const_int 16 [0x10])
(nil)))
(insn 1031 554 997 122 (set (mem/c:SI (plus:SI (reg/f:SI 15 %sp)
(const_int 60 [0x3c])) [492 %sfp+-44 S4 A16])
(reg/f:SI 9 %a1 [orig:37 _19 ] [37]))
"m68k-linux/libstdc++-v3/include/bits/chrono_io.h":478:68 discrim 1 55
{*movsi_m68k2}
(nil))
(insn 997 1031 556 122 (set (mem:SI (pre_dec:SI (reg/f:SI 15 %sp)) [8 S4 A16])
(reg:SI 0 %d0 [262]))
"m68k-linux/libstdc++-v3/include/bits/chrono_io.h":478:68 discrim 1 55
{*movsi_m68k2}
(nil))
(call_insn/i 556 997 557 122 (set (reg:SI 0 %d0)
(call (mem:QI (symbol_ref:SI
("_ZNKSt17basic_string_viewIcSt11char_traitsIcEE4findEcj.isra.0") [flags 0x3]
<function_decl 0x7f3905387a00 find.isra>) [0 find.isra S1 A8])
(const_int 16 [0x10])))
"m68k-linux/libstdc++-v3/include/bits/chrono_io.h":478:68 discrim 1 393
{*non_symbolic_call_value}
(expr_list:REG_CALL_DECL (symbol_ref:SI
("_ZNKSt17basic_string_viewIcSt11char_traitsIcEE4findEcj.isra.0") [flags 0x3]
<function_decl 0x7f3905387a00 find.isra>)
(expr_list:REG_EH_REGION (const_int 0 [0])
(nil)))
(nil))
(insn 557 556 1032 122 (set (reg/f:SI 15 %sp)
(plus:SI (reg/f:SI 15 %sp)
(const_int 16 [0x10])))
"m68k-linux/libstdc++-v3/include/bits/chrono_io.h":478:68 discrim 1 150
{*addsi3_internal}
(expr_list:REG_ARGS_SIZE (const_int 0 [0])
(nil)))
(insn 1032 557 1034 122 (set (reg/f:SI 9 %a1 [orig:37 _19 ] [37])
(mem/c:SI (plus:SI (reg/f:SI 15 %sp)
(const_int 44 [0x2c])) [492 %sfp+-44 S4 A16]))
"m68k-linux/libstdc++-v3/include/bits/chrono_io.h":479:8 55 {*movsi_m68k2}
(nil))
(insn 1034 1032 559 122 (set (reg/v/f:SI 8 %a0 [orig:69 __first ] [69])
(mem/c:SI (plus:SI (reg/f:SI 15 %sp)
(const_int 48 [0x30])) [492 %sfp+-40 S4 A16]))
"m68k-linux/libstdc++-v3/include/bits/chrono_io.h":479:8 55 {*movsi_m68k2}
(nil))
Referenced Bugs:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113939
[Bug 113939] Switch m68k to LRA
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug target/116429] [LRA] [M86k] Wrong spill offset
2024-08-20 9:09 [Bug target/116429] New: [LRA] [M86k] Wrong spill offset schwab@linux-m68k.org
@ 2024-08-20 17:26 ` matz at gcc dot gnu.org
2024-08-27 13:35 ` cvs-commit at gcc dot gnu.org
2024-08-27 14:04 ` schwab@linux-m68k.org
2 siblings, 0 replies; 4+ messages in thread
From: matz at gcc dot gnu.org @ 2024-08-20 17:26 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116429
Michael Matz <matz at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |matz at gcc dot gnu.org
--- Comment #1 from Michael Matz <matz at gcc dot gnu.org> ---
This is a problem in LRAs setup_sp_offset. The per-insn sp_offset item is
supposed to reflect the sp_offset before the insn in question. So, we
(correctly) start with this sequence of insns before LRA, and figure out
(again,
correctly) the sp_offsets noted:
we start at sp_off = 0
550: [--sp] = 0 sp_off = 0 {pushexthisi_const}
551: [--sp] = 37 sp_off = -4 {pushexthisi_const}
552: [--sp] = r37 sp_off = -8 {movsi_m68k2}
554: [--sp] = r116 - r37 sp_off = -12 {subsi3}
556: call sp_off = -16
Now, insn 554 (subsi3) doesn't match constraints, the destination is a reg,
needs to match the first input. So we generate reloads:
Creating newreg=262, assigning class DATA_REGS to r262
554: r262:SI=r262:SI-r37:SI
REG_ARGS_SIZE 0x10
Inserting insn reload before:
996: r262:SI=r116:SI
Inserting insn reload after:
997: [--%sp:SI]=r262:SI
Considering alt=0 of insn 997: (0) =g (1) damSKT
1 Non pseudo reload: reject++
overall=1,losers=0,rld_nregs=0
Choosing alt 0 in insn 997: (0) =g (1) damSKT {*movsi_m68k2}
(sp_off=-16)
Note how insn 997 (the after-reload) now has sp_off=-16 already. It all
goes downhill from there. We end up with these insns:
552: [--sp] = r37 sp_off = -8 {movsi_m68k2}
996: r262 = r116 sp_off = -12
554: r262 = r262 - r37 sp_off = -12
997: [--sp] = r262 sp_off = -16 (!!! should be -12)
556: call sp_off = -16
The call insn sp_off remains at the correct -16, but internally it's already
inconsistent here. If the sp_off before and insn is -16, and that insn
pre_decs sp, then the after-insn sp_off should be -20.
This is all because setup_sp_offset updates the sp_offset for new insns
incorrectly. It tries to setup it for the whole (new) insn sequence in order,
but for mysterious reasons starts off with the given sp_offset from the
_next_ instruction after the last insn in the new seq. That can't ever be
right. The sp-offset simulation runs in a forward direction (via NEXT_INSN).
The only connection to sp_offset of the next insn after the sequence is that
the offset should end up being equal to that one after simulating the sequence.
(Note how the local varname for the startup point is called 'before' :) )
It's possible that sometime it is correct that the sp_off of the after-last
insn is the correct one to start with. But then also the simulation of the
insn sequence needs to run backward, not forward. Generally that probably
can only be decided if setup_sp_offset is given information about on which
of the borders of the sequence it can rely. But as written it's internally
inconsistent. Making it consistent as per below fixes this instance of
the problem. I wouldn't be surprised if it introduces bugs elsewhere,
in which case setup_sp_offset really needs to be amended by more information.
diff --git a/gcc/lra.cc b/gcc/lra.cc
index fb32e134004..5afb21c3ea6 100644
--- a/gcc/lra.cc
+++ b/gcc/lra.cc
@@ -1868,9 +1868,13 @@ push_insns (rtx_insn *from, rtx_insn *to)
static poly_int64
setup_sp_offset (rtx_insn *from, rtx_insn *last)
{
- rtx_insn *before = next_nonnote_nondebug_insn_bb (last);
- poly_int64 offset = (before == NULL_RTX || ! INSN_P (before)
- ? 0 : lra_get_insn_recog_data (before)->sp_offset);
+ //rtx_insn *before = next_nonnote_nondebug_insn_bb (last);
+ rtx_insn *before = prev_nonnote_nondebug_insn_bb (from);
+ poly_int64 offset = 0;
+
+ if (before && INSN_P (before))
+ offset = lra_update_sp_offset (PATTERN (before),
+ lra_get_insn_recog_data
(before)->sp_offset);
for (rtx_insn *insn = from; insn != NEXT_INSN (last); insn = NEXT_INSN
(insn))
{
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug target/116429] [LRA] [M86k] Wrong spill offset
2024-08-20 9:09 [Bug target/116429] New: [LRA] [M86k] Wrong spill offset schwab@linux-m68k.org
2024-08-20 17:26 ` [Bug target/116429] " matz at gcc dot gnu.org
@ 2024-08-27 13:35 ` cvs-commit at gcc dot gnu.org
2024-08-27 14:04 ` schwab@linux-m68k.org
2 siblings, 0 replies; 4+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-08-27 13:35 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116429
--- Comment #2 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Michael Matz <matz@gcc.gnu.org>:
https://gcc.gnu.org/g:e223ac9c225352e3aeea7180a3b56a96ecdbe2fd
commit r15-3221-ge223ac9c225352e3aeea7180a3b56a96ecdbe2fd
Author: Michael Matz <matz@suse.de>
Date: Thu Aug 22 17:21:42 2024 +0200
LRA: Fix setup_sp_offset
This is part of making m68k work with LRA. See PR116429.
In short: setup_sp_offset is internally inconsistent. It wants to
setup the sp_offset for newly generated instructions. sp_offset for
an instruction is always the state of the sp-offset right before that
instruction. For that it starts at the (assumed correct) sp_offset
of the instruction right after the given (new) sequence, and then
iterates that sequence forward simulating its effects on sp_offset.
That can't ever be right: either it needs to start at the front
and simulate forward, or start at the end and simulate backward.
The former seems to be the more natural way. Funnily the local
variable holding that instruction is also called 'before'.
This changes it to the first variant: start before the sequence,
do one simulation step to get the sp-offset state in front of the
sequence and then continue simulating.
More details: in the problematic testcase we start with this
situation (sp_off before 550 is 0):
550: [--sp] = 0 sp_off = 0 {pushexthisi_const}
551: [--sp] = 37 sp_off = -4 {pushexthisi_const}
552: [--sp] = r37 sp_off = -8 {movsi_m68k2}
554: [--sp] = r116 - r37 sp_off = -12 {subsi3}
556: call sp_off = -16
insn 554 doesn't match its constraints and needs some reloads:
Creating newreg=262, assigning class DATA_REGS to r262
554: r262:SI=r262:SI-r37:SI
REG_ARGS_SIZE 0x10
Inserting insn reload before:
996: r262:SI=r116:SI
Inserting insn reload after:
997: [--%sp:SI]=r262:SI
Considering alt=0 of insn 997: (0) =g (1) damSKT
1 Non pseudo reload: reject++
overall=1,losers=0,rld_nregs=0
Choosing alt 0 in insn 997: (0) =g (1) damSKT {*movsi_m68k2}
(sp_off=-16)
Note how insn 997 (the after-reload) now has sp_off=-16 already. It all
goes downhill from there. We end up with these insns:
552: [--sp] = r37 sp_off = -8 {movsi_m68k2}
996: r262 = r116 sp_off = -12
554: r262 = r262 - r37 sp_off = -12
997: [--sp] = r262 sp_off = -16 (!!! should be -12)
556: call sp_off = -16
The call insn sp_off remains at the correct -16, but internally it's
already
inconsistent here. If the sp_off before an insn is -16, and that insn
pre_decs sp, then the after-insn sp_off should be -20.
PR target/116429
* lra.cc (setup_sp_offset): Start with sp_offset from
before the new sequence, not from after.
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug target/116429] [LRA] [M86k] Wrong spill offset
2024-08-20 9:09 [Bug target/116429] New: [LRA] [M86k] Wrong spill offset schwab@linux-m68k.org
2024-08-20 17:26 ` [Bug target/116429] " matz at gcc dot gnu.org
2024-08-27 13:35 ` cvs-commit at gcc dot gnu.org
@ 2024-08-27 14:04 ` schwab@linux-m68k.org
2 siblings, 0 replies; 4+ messages in thread
From: schwab@linux-m68k.org @ 2024-08-27 14:04 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116429
Andreas Schwab <schwab@linux-m68k.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
Resolution|--- |FIXED
--- Comment #3 from Andreas Schwab <schwab@linux-m68k.org> ---
Fixed for gcc 15.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-08-27 14:04 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-08-20 9:09 [Bug target/116429] New: [LRA] [M86k] Wrong spill offset schwab@linux-m68k.org
2024-08-20 17:26 ` [Bug target/116429] " matz at gcc dot gnu.org
2024-08-27 13:35 ` cvs-commit at gcc dot gnu.org
2024-08-27 14:04 ` schwab@linux-m68k.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).