diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp index ed84377ade930a..deac690a76118a 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -3244,64 +3244,18 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI, return false; } -// This function tries to combine two RLWINMs. We not only perform such -// optimization in SSA, but also after RA, since some RLWINM is generated after -// RA. -bool PPCInstrInfo::simplifyRotateAndMaskInstr(MachineInstr &MI, - MachineInstr *&ToErase) const { - bool Is64Bit = false; - switch (MI.getOpcode()) { - case PPC::RLWINM: - case PPC::RLWINM_rec: - break; - case PPC::RLWINM8: - case PPC::RLWINM8_rec: - Is64Bit = true; - break; - default: - return false; - } +bool PPCInstrInfo::combineRLWINM(MachineInstr &MI, + MachineInstr **ToErase) const { MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo(); - Register FoldingReg = MI.getOperand(1).getReg(); - MachineInstr *SrcMI = nullptr; - bool CanErase = false; - bool OtherIntermediateUse = true; - if (MRI->isSSA()) { - if (!Register::isVirtualRegister(FoldingReg)) - return false; - SrcMI = MRI->getVRegDef(FoldingReg); - } else { - SrcMI = getDefMIPostRA(FoldingReg, MI, OtherIntermediateUse); - } - if (!SrcMI) + unsigned FoldingReg = MI.getOperand(1).getReg(); + if (!Register::isVirtualRegister(FoldingReg)) return false; - // TODO: The pairs of RLWINM8(RLWINM) or RLWINM(RLWINM8) never occur before - // RA, but after RA. And We can fold RLWINM8(RLWINM) -> RLWINM8, or - // RLWINM(RLWINM8) -> RLWINM. - switch (SrcMI->getOpcode()) { - case PPC::RLWINM: - case PPC::RLWINM_rec: - if (Is64Bit) - return false; - break; - case PPC::RLWINM8: - case PPC::RLWINM8_rec: - if (!Is64Bit) - return false; - break; - default: + MachineInstr *SrcMI = MRI->getVRegDef(FoldingReg); + if (SrcMI->getOpcode() != PPC::RLWINM && + SrcMI->getOpcode() != PPC::RLWINM_rec && + SrcMI->getOpcode() != PPC::RLWINM8 && + SrcMI->getOpcode() != PPC::RLWINM8_rec) return false; - } - if (MRI->isSSA()) { - CanErase = !SrcMI->hasImplicitDef() && MRI->hasOneNonDBGUse(FoldingReg); - } else { - CanErase = !OtherIntermediateUse && MI.getOperand(1).isKill() && - !SrcMI->hasImplicitDef(); - // In post-RA, if SrcMI also defines the register to be forwarded, we can - // only do the folding if SrcMI is going to be erased. - if (!CanErase && SrcMI->definesRegister(SrcMI->getOperand(1).getReg())) - return false; - } assert((MI.getOperand(2).isImm() && MI.getOperand(3).isImm() && MI.getOperand(4).isImm() && SrcMI->getOperand(2).isImm() && SrcMI->getOperand(3).isImm() && SrcMI->getOperand(4).isImm()) && @@ -3312,6 +3266,7 @@ bool PPCInstrInfo::simplifyRotateAndMaskInstr(MachineInstr &MI, uint64_t MBMI = MI.getOperand(3).getImm(); uint64_t MESrc = SrcMI->getOperand(4).getImm(); uint64_t MEMI = MI.getOperand(4).getImm(); + assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) && "Invalid PPC::RLWINM Instruction!"); // If MBMI is bigger than MEMI, we always can not get run of ones. @@ -3355,6 +3310,8 @@ bool PPCInstrInfo::simplifyRotateAndMaskInstr(MachineInstr &MI, // If final mask is 0, MI result should be 0 too. if (FinalMask.isNullValue()) { + bool Is64Bit = + (MI.getOpcode() == PPC::RLWINM8 || MI.getOpcode() == PPC::RLWINM8_rec); Simplified = true; LLVM_DEBUG(dbgs() << "Replace Instr: "); LLVM_DEBUG(MI.dump()); @@ -3412,10 +3369,12 @@ bool PPCInstrInfo::simplifyRotateAndMaskInstr(MachineInstr &MI, LLVM_DEBUG(dbgs() << "To: "); LLVM_DEBUG(MI.dump()); } - if (Simplified && CanErase) { - // If SrcMI has no implicit def, and FoldingReg has no non-debug use or - // its flag is "killed", it's safe to delete SrcMI. Otherwise keep it. - ToErase = SrcMI; + if (Simplified & MRI->use_nodbg_empty(FoldingReg) && + !SrcMI->hasImplicitDef()) { + // If FoldingReg has no non-debug use and it has no implicit def (it + // is not RLWINMO or RLWINM8o), it's safe to delete its def SrcMI. + // Otherwise keep it. + *ToErase = SrcMI; LLVM_DEBUG(dbgs() << "Delete dead instruction: "); LLVM_DEBUG(SrcMI->dump()); } diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.h b/llvm/lib/Target/PowerPC/PPCInstrInfo.h index db63b013a923af..962456e784fae5 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.h +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.h @@ -585,8 +585,7 @@ class PPCInstrInfo : public PPCGenInstrInfo { bool convertToImmediateForm(MachineInstr &MI, MachineInstr **KilledDef = nullptr) const; bool foldFrameOffset(MachineInstr &MI) const; - bool simplifyRotateAndMaskInstr(MachineInstr &MI, - MachineInstr *&ToErase) const; + bool combineRLWINM(MachineInstr &MI, MachineInstr **ToErase = nullptr) const; bool isADDIInstrEligibleForFolding(MachineInstr &ADDIMI, int64_t &Imm) const; bool isADDInstrEligibleForFolding(MachineInstr &ADDMI) const; bool isImmInstrEligibleForFolding(MachineInstr &MI, unsigned &BaseReg, diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp index 307fffae870cab..c28e09fc047ebf 100644 --- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp +++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp @@ -987,7 +987,7 @@ bool PPCMIPeephole::simplifyCode(void) { case PPC::RLWINM_rec: case PPC::RLWINM8: case PPC::RLWINM8_rec: { - Simplified = TII->simplifyRotateAndMaskInstr(MI, ToErase); + Simplified = TII->combineRLWINM(MI, &ToErase); if (Simplified) ++NumRotatesCollapsed; break; diff --git a/llvm/lib/Target/PowerPC/PPCPreEmitPeephole.cpp b/llvm/lib/Target/PowerPC/PPCPreEmitPeephole.cpp index f3def378a93c55..04749cdd61c41b 100644 --- a/llvm/lib/Target/PowerPC/PPCPreEmitPeephole.cpp +++ b/llvm/lib/Target/PowerPC/PPCPreEmitPeephole.cpp @@ -37,8 +37,6 @@ STATISTIC(NumberOfSelfCopies, "Number of self copy instructions eliminated"); STATISTIC(NumFrameOffFoldInPreEmit, "Number of folding frame offset by using r+r in pre-emit peephole"); -STATISTIC(NumRotateInstrFoldInPreEmit, - "Number of folding Rotate instructions in pre-emit peephole"); static cl::opt EnablePCRelLinkerOpt("ppc-pcrel-linker-opt", cl::Hidden, cl::init(true), @@ -474,13 +472,6 @@ static bool hasPCRelativeForm(MachineInstr &Use) { LLVM_DEBUG(dbgs() << "Frame offset folding by using index form: "); LLVM_DEBUG(MI.dump()); } - MachineInstr *ToErase = nullptr; - if (TII->simplifyRotateAndMaskInstr(MI, ToErase)) { - Changed = true; - NumRotateInstrFoldInPreEmit++; - if (ToErase) - InstrsToErase.push_back(ToErase); - } } // Eliminate conditional branch based on a constant CR bit by diff --git a/llvm/test/CodeGen/PowerPC/fold-rlwinm-after-ra.mir b/llvm/test/CodeGen/PowerPC/fold-rlwinm-after-ra.mir deleted file mode 100644 index 182929053c63ea..00000000000000 --- a/llvm/test/CodeGen/PowerPC/fold-rlwinm-after-ra.mir +++ /dev/null @@ -1,163 +0,0 @@ -# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py -# RUN: llc -mcpu=pwr9 -mtriple=powerpc64le-unknown-unknown -stop-after \ -# RUN: ppc-pre-emit-peephole %s -o - | FileCheck %s - ---- -name: testFoldRLWINM -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $r3 - ; CHECK-LABEL: name: testFoldRLWINM - ; CHECK: liveins: $r3 - ; CHECK: renamable $r3 = RLWINM killed renamable $r3, 14, 0, 12, implicit-def $x3 - ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit killed $x3 - $r3 = RLWINM killed $r3, 27, 5, 31 - dead renamable $r3 = RLWINM killed renamable $r3, 19, 0, 12, implicit-def $x3 - BLR8 implicit $lr8, implicit $rm, implicit killed $x3 -... ---- -name: testFoldRLWINMSrcFullMask1 -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $r3 - ; CHECK-LABEL: name: testFoldRLWINMSrcFullMask1 - ; CHECK: liveins: $r3 - ; CHECK: renamable $r3 = RLWINM killed renamable $r3, 14, 0, 12, implicit-def $x3 - ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit killed $x3 - $r3 = RLWINM killed $r3, 27, 0, 31 - dead renamable $r3 = RLWINM killed renamable $r3, 19, 0, 12, implicit-def $x3 - BLR8 implicit $lr8, implicit $rm, implicit killed $x3 -... ---- -name: testFoldRLWINMSrcFullMask2 -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $r2, $r3 - ; CHECK-LABEL: name: testFoldRLWINMSrcFullMask2 - ; CHECK: liveins: $r2, $r3 - ; CHECK: renamable $r3 = RLWINM $r2, 14, 10, 1, implicit-def $x3 - ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit killed $x3 - $r3 = RLWINM killed $r2, 27, 10, 9 - dead renamable $r3 = RLWINM killed renamable $r3, 19, 10, 1, implicit-def $x3 - BLR8 implicit $lr8, implicit $rm, implicit killed $x3 -... ---- -name: testFoldRLWINMSrcWrapped -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $r3 - ; CHECK-LABEL: name: testFoldRLWINMSrcWrapped - ; CHECK: liveins: $r3 - ; CHECK: renamable $r3 = RLWINM killed renamable $r3, 14, 11, 12, implicit-def $x3 - ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit killed $x3 - $r3 = RLWINM killed $r3, 27, 30, 10 - dead renamable $r3 = RLWINM killed renamable $r3, 19, 0, 12, implicit-def $x3 - BLR8 implicit $lr8, implicit $rm, implicit killed $x3 -... ---- -name: testFoldRLWINMUserWrapped -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $r3 - ; CHECK-LABEL: name: testFoldRLWINMUserWrapped - ; CHECK: liveins: $r3 - ; CHECK: $r3 = RLWINM killed $r3, 10, 5, 31 - ; CHECK: renamable $r3 = RLWINM killed renamable $r3, 10, 30, 5, implicit-def $x3 - ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit killed $x3 - $r3 = RLWINM killed $r3, 10, 5, 31 - dead renamable $r3 = RLWINM killed renamable $r3, 10, 30, 5, implicit-def $x3 - BLR8 implicit $lr8, implicit $rm, implicit killed $x3 -... ---- -name: testFoldRLWINMResultWrapped -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $r3 - ; CHECK-LABEL: name: testFoldRLWINMResultWrapped - ; CHECK: liveins: $r3 - ; CHECK: $r3 = RLWINM killed $r3, 10, 20, 10 - ; CHECK: renamable $r3 = RLWINM killed renamable $r3, 10, 0, 31, implicit-def $x3 - ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit killed $x3 - $r3 = RLWINM killed $r3, 10, 20, 10 - dead renamable $r3 = RLWINM killed renamable $r3, 10, 0, 31, implicit-def $x3 - BLR8 implicit $lr8, implicit $rm, implicit killed $x3 -... ---- -name: testFoldRLWINMToZero -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $r3 - ; CHECK-LABEL: name: testFoldRLWINMToZero - ; CHECK: liveins: $r3 - ; CHECK: renamable $r3 = LI 0, implicit-def $x3 - ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit killed $x3 - $r3 = RLWINM killed $r3, 27, 5, 10 - dead renamable $r3 = RLWINM killed renamable $r3, 8, 5, 10, implicit-def $x3 - BLR8 implicit $lr8, implicit $rm, implicit killed $x3 -... ---- -name: testFoldRLWINM_recToZero -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $r3 - ; CHECK-LABEL: name: testFoldRLWINM_recToZero - ; CHECK: liveins: $r3 - ; CHECK: dead renamable $r3 = ANDI_rec killed renamable $r3, 0, implicit-def $cr0 - ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit killed $cr0 - $r3 = RLWINM killed $r3, 27, 5, 10 - dead renamable $r3 = RLWINM_rec killed renamable $r3, 8, 5, 10, implicit-def $cr0 - BLR8 implicit $lr8, implicit $rm, implicit killed $cr0 -... ---- -name: testFoldRLWINMInvalidMask -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $r3 - ; CHECK-LABEL: name: testFoldRLWINMInvalidMask - ; CHECK: liveins: $r3 - ; CHECK: $r3 = RLWINM killed $r3, 20, 5, 31 - ; CHECK: renamable $r3 = RLWINM killed renamable $r3, 19, 10, 20, implicit-def $x3 - ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit killed $x3 - $r3 = RLWINM killed $r3, 20, 5, 31 - dead renamable $r3 = RLWINM killed renamable $r3, 19, 10, 20, implicit-def $x3 - BLR8 implicit $lr8, implicit $rm, implicit killed $x3 -... ---- -name: testFoldRLWINCanNotBeDeleted -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $r2, $r3 - ; CHECK-LABEL: name: testFoldRLWINCanNotBeDeleted - ; CHECK: liveins: $r2, $r3 - ; CHECK: $r3 = RLWINM_rec $r2, 27, 5, 10, implicit-def dead $cr0 - ; CHECK: dead renamable $r3 = ANDI_rec $r2, 0, implicit-def $cr0 - ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit killed $cr0 - $r3 = RLWINM_rec $r2, 27, 5, 10, implicit-def $cr0 - dead renamable $r3 = RLWINM_rec killed renamable $r3, 8, 5, 10, implicit-def $cr0 - BLR8 implicit $lr8, implicit $rm, implicit killed $cr0 -... ---- -name: testCanNotFoldRLWINM -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $r3 - ; CHECK-LABEL: name: testCanNotFoldRLWINM - ; CHECK: liveins: $r3 - ; CHECK: $r3 = RLWINM_rec killed $r3, 27, 5, 10, implicit-def dead $cr0 - ; CHECK: dead renamable $r3 = RLWINM_rec killed renamable $r3, 8, 5, 10, implicit-def $cr0 - ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit killed $cr0 - $r3 = RLWINM_rec $r3, 27, 5, 10, implicit-def $cr0 - dead renamable $r3 = RLWINM_rec killed renamable $r3, 8, 5, 10, implicit-def $cr0 - BLR8 implicit $lr8, implicit $rm, implicit killed $cr0 -... diff --git a/llvm/test/CodeGen/PowerPC/vsx_builtins.ll b/llvm/test/CodeGen/PowerPC/vsx_builtins.ll index b40a84a7e95c59..0aae50af26490c 100644 --- a/llvm/test/CodeGen/PowerPC/vsx_builtins.ll +++ b/llvm/test/CodeGen/PowerPC/vsx_builtins.ll @@ -131,7 +131,8 @@ define i32 @xvtdivdp_shift(<2 x double> %a, <2 x double> %b) { ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: xvtdivdp cr0, v2, v3 ; CHECK-NEXT: mfocrf r3, 128 -; CHECK-NEXT: li r3, 0 +; CHECK-NEXT: srwi r3, r3, 28 +; CHECK-NEXT: rlwinm r3, r3, 28, 31, 31 ; CHECK-NEXT: blr entry: %0 = tail call i32 @llvm.ppc.vsx.xvtdivdp(<2 x double> %a, <2 x double> %b)