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