@@ -2190,14 +2190,9 @@ impl Assembler
21902190
21912191 let preferred_alloc = interval. preferred ;
21922192 let preferred_taken = preferred_alloc
2193- . and_then ( |alloc| alloc. assigned_reg ( regs) )
2194- . is_some_and ( |reg| {
2195- active. iter ( ) . any ( |active_interval| {
2196- active_interval. assigned
2197- . and_then ( |alloc| alloc. assigned_reg ( regs) )
2198- . is_some_and ( |active_reg| active_reg. reg_no == reg. reg_no )
2199- } )
2200- } ) ;
2193+ . is_some_and ( |alloc|
2194+ active. iter ( ) . any ( |active_interval| active_interval. assigned == Some ( alloc) )
2195+ ) ;
22012196
22022197 if let Some ( preferred_alloc) = preferred_alloc. filter ( |_| !preferred_taken) {
22032198 if let Some ( reg_idx) = preferred_alloc. alloc_pool_index ( num_registers) {
@@ -2217,14 +2212,15 @@ impl Assembler
22172212
22182213 if free_registers. is_empty ( ) {
22192214 // Spill: pick the longest-lived active interval (last in sorted active)
2220- // but only from the allocatable register pool. Fixed register
2221- // assignments represent preferred/ pinned physical registers
2222- // (for example SP) and should not be selected as spill victims .
2215+ // but only from the allocatable partition of the pool. An index
2216+ // at or past `num_registers` is a pinned physical register (for
2217+ // example SP), which is not ours to hand to someone else .
22232218 // Take the id and end point rather than a reference, so that `active`
22242219 // can be mutated below.
22252220 let spill = active. iter ( ) . rev ( )
22262221 . find ( |active_interval| {
2227- matches ! ( active_interval. assigned, Some ( Allocation :: Reg ( _) ) )
2222+ active_interval. assigned
2223+ . is_some_and ( |alloc| alloc. alloc_pool_index ( num_registers) . is_some ( ) )
22282224 } )
22292225 . map ( |active_interval| ( active_interval. id , active_interval. end ( ) ) ) ;
22302226 let slot = Allocation :: Stack ( num_stack_slots) ;
@@ -5109,11 +5105,7 @@ mod tests {
51095105 assert ! ( !pushes. is_empty( ) , "Expected at least one saved register across CCall" ) ;
51105106
51115107 // The survivor register should match v1's allocation
5112- let v1_reg = match assignments[ v1. vreg_idx ( ) ] . unwrap ( ) {
5113- Allocation :: Reg ( n) => Opnd :: Reg ( regs[ n] ) ,
5114- Allocation :: Fixed ( reg) => Opnd :: Reg ( reg) ,
5115- _ => unreachable ! ( ) ,
5116- } ;
5108+ let v1_reg = Opnd :: Reg ( assignments[ v1. vreg_idx ( ) ] . unwrap ( ) . assigned_reg ( & regs) . unwrap ( ) ) ;
51175109 let pushed_v1 = pushes. iter ( ) . any ( |insn| matches ! ( * * insn, Insn :: CPushPair ( first, second) if first == v1_reg || second == v1_reg) ) ;
51185110 let popped_v1 = pops. iter ( ) . any ( |insn| matches ! ( * * insn, Insn :: CPopPairInto ( first, second) if first == v1_reg || second == v1_reg) ) ;
51195111 assert ! ( pushed_v1, "CPushPair should save v1's register" ) ;
0 commit comments