diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp index 871824553aa4d..970659cb112f0 100644 --- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp +++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp @@ -595,12 +595,15 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) { const MachineOperand &CopySrc = *CopyOperands->Source; Register CopySrcReg = CopySrc.getReg(); - // FIXME: Don't handle partial uses of wider COPYs yet. + // When the use is a subregister of the COPY destination, + // record the subreg index. + unsigned SubregIdx = 0; + + // This can only occur when we are dealing with physical registers. if (MOUse.getReg() != CopyDstReg) { - LLVM_DEBUG( - dbgs() << "MCP: FIXME! Not forwarding COPY to sub-register use:\n " - << MI); - continue; + SubregIdx = TRI->getSubRegIndex(CopyDstReg, MOUse.getReg()); + if (!SubregIdx) + continue; } // Don't forward COPYs of reserved regs unless they are constant. @@ -633,7 +636,11 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) { << "\n with " << printReg(CopySrcReg, TRI) << "\n in " << MI << " from " << *Copy); - MOUse.setReg(CopySrcReg); + if (SubregIdx) + MOUse.setReg(TRI->getSubReg(CopySrcReg, SubregIdx)); + else + MOUse.setReg(CopySrcReg); + if (!CopySrc.isRenamable()) MOUse.setIsRenamable(false); MOUse.setIsUndef(CopySrc.isUndef()); diff --git a/llvm/test/CodeGen/Thumb2/mve-vst3.ll b/llvm/test/CodeGen/Thumb2/mve-vst3.ll index 55e5d1aa5e342..65fb570862e4c 100644 --- a/llvm/test/CodeGen/Thumb2/mve-vst3.ll +++ b/llvm/test/CodeGen/Thumb2/mve-vst3.ll @@ -166,44 +166,43 @@ define void @vst3_v16i32(ptr %src, ptr %dst) { ; CHECK-NEXT: vmov.f32 s22, s3 ; CHECK-NEXT: vstrw.32 q7, [sp, #48] @ 16-byte Spill ; CHECK-NEXT: vmov.f32 s9, s0 -; CHECK-NEXT: vmov.f32 s8, s4 -; CHECK-NEXT: vmov.f32 s11, s5 ; CHECK-NEXT: vmov.f32 s0, s30 -; CHECK-NEXT: vstrw.32 q2, [sp, #128] @ 16-byte Spill ; CHECK-NEXT: vmov.f32 s1, s15 -; CHECK-NEXT: vldrw.u32 q2, [sp, #16] @ 16-byte Reload ; CHECK-NEXT: vmov.f32 s2, s19 ; CHECK-NEXT: vmov.f32 s3, s31 ; CHECK-NEXT: vstrw.32 q0, [sp, #112] @ 16-byte Spill +; CHECK-NEXT: vmov.f32 s8, s4 +; CHECK-NEXT: vmov.f32 s11, s5 ; CHECK-NEXT: vmov.f32 s0, s17 +; CHECK-NEXT: vstrw.32 q2, [sp, #128] @ 16-byte Spill ; CHECK-NEXT: vmov.f32 s2, s14 +; CHECK-NEXT: vldrw.u32 q2, [sp, #16] @ 16-byte Reload ; CHECK-NEXT: vmov.f32 s3, s18 ; CHECK-NEXT: vmov.f32 s21, s7 +; CHECK-NEXT: vldrw.u32 q1, [sp] @ 16-byte Reload ; CHECK-NEXT: vstrw.32 q0, [sp, #96] @ 16-byte Spill ; CHECK-NEXT: vldrw.u32 q0, [sp, #144] @ 16-byte Reload ; CHECK-NEXT: vstrw.32 q5, [r1, #32] -; CHECK-NEXT: vmov.f32 s22, s11 -; CHECK-NEXT: vldrw.u32 q1, [sp] @ 16-byte Reload -; CHECK-NEXT: vmov.f64 d0, d4 -; CHECK-NEXT: vmov.f32 s19, s10 -; CHECK-NEXT: vldrw.u32 q2, [sp, #80] @ 16-byte Reload ; CHECK-NEXT: vmov.f32 s21, s7 -; CHECK-NEXT: vmov.f64 d14, d4 ; CHECK-NEXT: vmov.f32 s20, s2 ; CHECK-NEXT: vmov.f32 s23, s3 +; CHECK-NEXT: vldrw.u32 q0, [sp, #64] @ 16-byte Reload +; CHECK-NEXT: vmov.f32 s22, s11 ; CHECK-NEXT: vstrw.32 q5, [sp, #32] @ 16-byte Spill ; CHECK-NEXT: vmov.f32 s21, s16 ; CHECK-NEXT: vmov.f32 s23, s13 -; CHECK-NEXT: vmov.f32 s16, s1 -; CHECK-NEXT: vmov.f32 s13, s0 -; CHECK-NEXT: vldrw.u32 q0, [sp, #64] @ 16-byte Reload +; CHECK-NEXT: vmov.f32 s16, s9 +; CHECK-NEXT: vmov.f32 s19, s10 +; CHECK-NEXT: vmov.f32 s13, s8 +; CHECK-NEXT: vldrw.u32 q2, [sp, #80] @ 16-byte Reload +; CHECK-NEXT: vmov.f32 s20, s12 +; CHECK-NEXT: vmov.f64 d14, d4 ; CHECK-NEXT: vmov r0, r3, d14 ; CHECK-NEXT: vldrw.u32 q7, [sp, #48] @ 16-byte Reload ; CHECK-NEXT: vmov.f32 s7, s11 ; CHECK-NEXT: vmov.f32 s8, s24 ; CHECK-NEXT: vmov.f32 s9, s0 ; CHECK-NEXT: vmov.f32 s11, s25 -; CHECK-NEXT: vmov.f32 s20, s12 ; CHECK-NEXT: vmov.f32 s12, s4 ; CHECK-NEXT: vmov.f32 s4, s10 ; CHECK-NEXT: vmov.32 q2[2], r0