@@ -128,6 +128,17 @@ impl Assembler
128128 let mut iterator = self . insns . into_iter ( ) . enumerate ( ) . peekable ( ) ;
129129 let mut asm = Assembler :: new_with_label_names ( take ( & mut self . label_names ) , live_ranges. len ( ) ) ;
130130
131+ // When we add news instructions to `asm`, we also create new VRegs not in the old
132+ // assembler. All VRegs with index larger than the old `live_ranges` live in the
133+ // new assembler since all old VRegs are inherited and keep their index.
134+ fn vreg_outlives_insn ( vreg_idx : usize , older_live_ranges : & Vec < LiveRange > , new_asm : & Assembler , insn_idx : usize ) -> bool {
135+ older_live_ranges
136+ . get ( vreg_idx)
137+ . map_or_else ( || new_asm. live_ranges . get ( vreg_idx) , Some )
138+ . map ( |live_range| live_range. end ( ) > insn_idx)
139+ . expect ( "VReg in old or new assembler" )
140+ }
141+
131142 while let Some ( ( index, mut insn) ) = iterator. next ( ) {
132143 let is_load = matches ! ( insn, Insn :: Load { .. } | Insn :: LoadInto { .. } ) ;
133144 let mut opnd_iter = insn. opnd_iter_mut ( ) ;
@@ -183,7 +194,7 @@ impl Assembler
183194 } ,
184195 // Instruction output whose live range spans beyond this instruction
185196 ( Opnd :: VReg { idx, .. } , _) => {
186- if live_ranges [ idx ] . end ( ) > index {
197+ if vreg_outlives_insn ( idx , & live_ranges , & asm , index) {
187198 * left = asm. load ( * left) ;
188199 }
189200 } ,
@@ -248,7 +259,7 @@ impl Assembler
248259 match opnd {
249260 // Instruction output whose live range spans beyond this instruction
250261 Opnd :: VReg { idx, .. } => {
251- if live_ranges [ * idx] . end ( ) > index {
262+ if vreg_outlives_insn ( * idx, & live_ranges , & asm , index) {
252263 * opnd = asm. load ( * opnd) ;
253264 }
254265 } ,
@@ -272,7 +283,7 @@ impl Assembler
272283 // If we have an instruction output whose live range
273284 // spans beyond this instruction, we have to load it.
274285 Opnd :: VReg { idx, .. } => {
275- if live_ranges [ idx ] . end ( ) > index {
286+ if vreg_outlives_insn ( idx , & live_ranges , & asm , index) {
276287 * truthy = asm. load ( * truthy) ;
277288 }
278289 } ,
@@ -307,7 +318,7 @@ impl Assembler
307318 // If we have an instruction output whose live range
308319 // spans beyond this instruction, we have to load it.
309320 Opnd :: VReg { idx, .. } => {
310- if live_ranges [ idx ] . end ( ) > index {
321+ if vreg_outlives_insn ( idx , & live_ranges , & asm , index) {
311322 * opnd = asm. load ( * opnd) ;
312323 }
313324 } ,
0 commit comments