diff --git a/llvm/lib/Target/PowerPC/PPCInstrHTM.td b/llvm/lib/Target/PowerPC/PPCInstrHTM.td --- a/llvm/lib/Target/PowerPC/PPCInstrHTM.td +++ b/llvm/lib/Target/PowerPC/PPCInstrHTM.td @@ -164,9 +164,8 @@ (TSR 0)>; def : Pat<(i64 (int_ppc_ttest)), - (RLDICL (i64 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), - (TABORTWCI 0, (LI 0), 0), sub_32)), - 36, 28)>; + (i64 (INSERT_SUBREG + (i64 (IMPLICIT_DEF)), (TABORTWCI 0, (LI 0), 0), sub_32))>; } // [HasHTM] diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -1272,14 +1272,22 @@ .addImm(31); return; } else if (PPC::CRRCRegClass.contains(SrcReg) && - PPC::G8RCRegClass.contains(DestReg)) { - BuildMI(MBB, I, DL, get(PPC::MFOCRF8), DestReg).addReg(SrcReg); - getKillRegState(KillSrc); - return; - } else if (PPC::CRRCRegClass.contains(SrcReg) && - PPC::GPRCRegClass.contains(DestReg)) { - BuildMI(MBB, I, DL, get(PPC::MFOCRF), DestReg).addReg(SrcReg); + (PPC::G8RCRegClass.contains(DestReg) || + PPC::GPRCRegClass.contains(DestReg))) { + bool Is64Bit = PPC::G8RCRegClass.contains(DestReg); + unsigned MvCode = Is64Bit ? PPC::MFOCRF8 : PPC::MFOCRF; + unsigned ShCode = Is64Bit ? PPC::RLWINM8 : PPC::RLWINM; + unsigned CRNum = TRI->getEncodingValue(SrcReg); + BuildMI(MBB, I, DL, get(MvCode), DestReg).addReg(SrcReg); getKillRegState(KillSrc); + if (CRNum == 7) + return; + // Shift the CR bits to make the CR field in the lowest 4 bits of GRC. + BuildMI(MBB, I, DL, get(ShCode), DestReg) + .addReg(DestReg, RegState::Kill) + .addImm(CRNum * 4 + 4) + .addImm(28) + .addImm(31); return; } else if (PPC::G8RCRegClass.contains(SrcReg) && PPC::VSFRCRegClass.contains(DestReg)) { diff --git a/llvm/test/CodeGen/PowerPC/htm-ttest.ll b/llvm/test/CodeGen/PowerPC/htm-ttest.ll --- a/llvm/test/CodeGen/PowerPC/htm-ttest.ll +++ b/llvm/test/CodeGen/PowerPC/htm-ttest.ll @@ -8,7 +8,7 @@ ; CHECK-NEXT: li 3, 0 ; CHECK-NEXT: tabortwci. 0, 3, 0 ; CHECK-NEXT: mfocrf 3, 128 -; CHECK-NEXT: rldicl 3, 3, 36, 28 +; CHECK-NEXT: srwi 3, 3, 28 ; CHECK-NEXT: rlwinm. 3, 3, 31, 30, 31 ; CHECK-NEXT: beqlr+ 0 ; CHECK-NEXT: # %bb.1: diff --git a/llvm/test/CodeGen/PowerPC/reg_copy.mir b/llvm/test/CodeGen/PowerPC/reg_copy.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/reg_copy.mir @@ -0,0 +1,86 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=powerpc64le-unknown-linux-gnu \ +# RUN: -run-pass postrapseudos %s -o - -verify-machineinstrs | FileCheck %s + +--- +name: copy_cr0_gprc +body: | + bb.0.entry: + liveins: $v2, $v3 + ; CHECK-LABEL: name: copy_cr0_gprc + ; CHECK: renamable $cr0 = nofpexcept XVTDIVDP killed renamable $v2, killed renamable $v3, implicit $rm + ; CHECK: $r3 = MFOCRF $cr0 + ; CHECK: $r3 = RLWINM killed $r3, 4, 28, 31, implicit-def $x3 + ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit $x3 + renamable $cr0 = nofpexcept XVTDIVDP killed renamable $v2, killed renamable $v3, implicit $rm + renamable $r3 = COPY killed renamable $cr0, implicit-def $x3 + BLR8 implicit $lr8, implicit $rm, implicit $x3 +... +--- +name: copy_cr3_gprc +body: | + bb.0.entry: + liveins: $v2, $v3 + ; CHECK-LABEL: name: copy_cr3_gprc + ; CHECK: renamable $cr3 = nofpexcept XVTDIVDP killed renamable $v2, killed renamable $v3, implicit $rm + ; CHECK: $r3 = MFOCRF $cr3 + ; CHECK: $r3 = RLWINM killed $r3, 16, 28, 31, implicit-def $x3 + ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit $x3 + renamable $cr3 = nofpexcept XVTDIVDP killed renamable $v2, killed renamable $v3, implicit $rm + renamable $r3 = COPY killed renamable $cr3, implicit-def $x3 + BLR8 implicit $lr8, implicit $rm, implicit $x3 +... +--- +name: copy_cr7_gprc +body: | + bb.0.entry: + liveins: $v2, $v3 + ; CHECK-LABEL: name: copy_cr7_gprc + ; CHECK: renamable $cr7 = nofpexcept XVTDIVDP killed renamable $v2, killed renamable $v3, implicit $rm + ; CHECK: $r3 = MFOCRF $cr7, implicit-def $x3 + ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit $x3 + renamable $cr7 = nofpexcept XVTDIVDP killed renamable $v2, killed renamable $v3, implicit $rm + renamable $r3 = COPY killed renamable $cr7, implicit-def $x3 + BLR8 implicit $lr8, implicit $rm, implicit $x3 +... +--- +name: copy_cr0_g8rc +body: | + bb.0.entry: + liveins: $v2, $v3 + ; CHECK-LABEL: name: copy_cr0_g8rc + ; CHECK: renamable $cr0 = nofpexcept XVTDIVDP killed renamable $v2, killed renamable $v3, implicit $rm + ; CHECK: $x5 = MFOCRF8 $cr0 + ; CHECK: $x5 = RLWINM8 killed $x5, 4, 28, 31, implicit-def $x3 + ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit $x3 + renamable $cr0 = nofpexcept XVTDIVDP killed renamable $v2, killed renamable $v3, implicit $rm + renamable $x5 = COPY killed renamable $cr0, implicit-def $x3 + BLR8 implicit $lr8, implicit $rm, implicit $x3 +... +--- +name: copy_cr3_g8rc +body: | + bb.0.entry: + liveins: $v2, $v3 + ; CHECK-LABEL: name: copy_cr3_g8rc + ; CHECK: renamable $cr3 = nofpexcept XVTDIVDP killed renamable $v2, killed renamable $v3, implicit $rm + ; CHECK: $x5 = MFOCRF8 $cr3 + ; CHECK: $x5 = RLWINM8 killed $x5, 16, 28, 31, implicit-def $x3 + ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit $x3 + renamable $cr3 = nofpexcept XVTDIVDP killed renamable $v2, killed renamable $v3, implicit $rm + renamable $x5 = COPY killed renamable $cr3, implicit-def $x3 + BLR8 implicit $lr8, implicit $rm, implicit $x3 +... +--- +name: copy_cr7_g8rc +body: | + bb.0.entry: + liveins: $v2, $v3 + ; CHECK-LABEL: name: copy_cr7_g8rc + ; CHECK: renamable $cr7 = nofpexcept XVTDIVDP killed renamable $v2, killed renamable $v3, implicit $rm + ; CHECK: $x5 = MFOCRF8 $cr7, implicit-def $x3 + ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit $x3 + renamable $cr7 = nofpexcept XVTDIVDP killed renamable $v2, killed renamable $v3, implicit $rm + renamable $x5 = COPY killed renamable $cr7, implicit-def $x3 + BLR8 implicit $lr8, implicit $rm, implicit $x3 +...