This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/83147] New: LRA inheritance undo on multiple sets problem
- From: "krebbel at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 24 Nov 2017 18:08:19 +0000
- Subject: [Bug rtl-optimization/83147] New: LRA inheritance undo on multiple sets problem
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83147
Bug ID: 83147
Summary: LRA inheritance undo on multiple sets problem
Product: gcc
Version: 8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: krebbel at gcc dot gnu.org
Target Milestone: ---
Created attachment 42713
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42713&action=edit
Autoreduced testcase
Compiling the attached testcase with:
gcc -march=z196 -m64 -mzarch -O2 -o t.s t.cc
produces the following sequence:
...
stmg %r2,%r3,160(%r15)
ltg %r2,184(%r15) <--- read from uninitialized memory
lghi %r3,0
ltg %r1,168(%r15)
lghi %r1,1
locgre %r2,%r1
...
This currently makes bootstrap with "--with-arch=z196" fail on S/390.
The ltg instruction is a load and test being a parallel of a compare and a set
using the same source operand (272r.ira):
(insn 122 62 48 6 (parallel [
(set (reg:CCZ 33 %cc)
(compare:CCZ (subreg:DI (reg:TI 100 [ width+-8 ]) 8)
(const_int 0 [0])))
(set (reg:DI 118 [ nbwc ])
(subreg:DI (reg:TI 100 [ width+-8 ]) 8))
]) 1213 {*tstdi_extimm}
(expr_list:REG_UNUSED (reg:CCZ 33 %cc)
(nil)))
LRA generates an inheritance reload replacing both occurrences of the source
operand r100 with r132 (273r.reload):
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Creating newreg=132 from oldreg=100, assigning class GENERAL_REGS to
inheritance r132
Original reg change 100->132 (bb6):
122: {%cc:CCZ=cmp(r132:TI#8,0);r118:DI=r132:TI#8;}
REG_UNUSED %cc:CCZ
Add inheritance<-original before:
162: r132:TI=r100:TI
Inheritance reuse change 100->132 (bb6):
158: r129:DI=r132:TI#8
REG_DEAD r132:TI
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
And another one for r100 stacking on top of the first:
163: r133=r100
162: r132=r133
122: use r132
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Creating newreg=133 from oldreg=100, assigning class GENERAL_REGS to
inheritance r133
Original reg change 100->133 (bb5):
41: r78:DI=r133:TI#8
Add inheritance<-original before:
163: r133:TI=r100:TI
Inheritance reuse change 100->133 (bb6):
162: r132:TI=r133:TI
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
The inheritance undo code then tries to replace r132 in insn 122 with r133.
Unfortunately it only replaces one of the source operands.
The reason is that the target of the first part of the parallel (the cmp) is
REG_UNUSED and hence single_set ignores it and returns just the second part of
the insn. The code then operates on the source operand return by single_set
(lra-constraint.c:6698):
if (GET_CODE (SET_SRC (set)) == SUBREG)
SUBREG_REG (SET_SRC (set)) = SET_SRC (prev_set);
else
SET_SRC (set) = SET_SRC (prev_set);
The replacement perhaps needs to be done recursively to get all the sources?
********** Undoing inheritance #2: **********
Inherit 3 out of 4 (75.00%)
Insn after restoring regs:
158: r129:DI=r100:TI#8
REG_DEAD r100:TI
Change reload insn:
122: {%cc:CCZ=cmp(r132:TI#8,0);r118:DI=r133:TI#8;} <---- 2 different
sources
REG_UNUSED %cc:CCZ
Insn after restoring regs:
162: r100:TI=r133:TI
REG_DEAD r133:TI