Index: lib/Target/PowerPC/PPCFrameLowering.cpp =================================================================== --- lib/Target/PowerPC/PPCFrameLowering.cpp +++ lib/Target/PowerPC/PPCFrameLowering.cpp @@ -856,11 +856,15 @@ if (MustSaveCR && !(SingleScratchReg && MustSaveLR)) { // will only occur for PPC64 - // FIXME: In the ELFv2 ABI, we are not required to save all CR fields. - // If only one or two CR fields are clobbered, it could be more - // efficient to use mfocrf to selectively save just those fields. + // In the ELFv2 ABI, we are not required to save all CR fields. + // If only one or two CR fields are clobbered, it is more efficient to use + // mfocrf to selectively save just those fields, because mfocrf has short + // latency compares to mfcr. + unsigned MfcrOpcode = PPC::MFCR8; + if (MustSaveCRs.size() == 1) + MfcrOpcode = PPC::MFOCRF8; MachineInstrBuilder MIB = - BuildMI(MBB, MBBI, dl, TII.get(PPC::MFCR8), TempReg); + BuildMI(MBB, MBBI, dl, TII.get(MfcrOpcode), TempReg); for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i) MIB.addReg(MustSaveCRs[i], RegState::ImplicitKill); } Index: test/CodeGen/PowerPC/crsave.ll =================================================================== --- test/CodeGen/PowerPC/crsave.ll +++ test/CodeGen/PowerPC/crsave.ll @@ -21,7 +21,7 @@ ; PPC32-NEXT: mtocrf 32, 12 ; PPC64: .cfi_startproc -; PPC64: mfcr 12 +; PPC64: mfocrf 12 ; PPC64: stw 12, 8(1) ; PPC64: stdu 1, -[[AMT:[0-9]+]](1) ; PPC64: .cfi_def_cfa_offset 128 @@ -60,3 +60,22 @@ ; PPC64: mtocrf 16, 12 ; PPC64: mtocrf 8, 12 +; Generate mfocrf in prologue when we need to save 1 nonvolatile CR field +define void @cloberOneNvCrField() { +entry: + tail call void asm sideeffect "# clobbers", "~{cr2}"() + ret void + +; PPC64-LABEL: @cloberOneNvCrField +; PPC64: mfocrf [[REG1:[0-9]+]], +} + +; Generate mfcr in prologue when we need to save all nonvolatile CR field +define void @cloberAllNvCrField() { +entry: + tail call void asm sideeffect "# clobbers", "~{cr2},~{cr3},~{cr4}"() + ret void + +; PPC64-LABEL: @cloberAllNvCrField +; PPC64: mfcr [[REG1:[0-9]+]] +} Index: test/CodeGen/PowerPC/pr26690.ll =================================================================== --- test/CodeGen/PowerPC/pr26690.ll +++ test/CodeGen/PowerPC/pr26690.ll @@ -101,7 +101,7 @@ ret i32 2 } -; CHECK: mfcr {{[0-9]+}} +; CHECK: mfocrf {{[0-9]+}} !llvm.ident = !{!0}