From: QingShan Zhang Date: Fri, 28 Dec 2018 03:38:09 +0000 (+0000) Subject: [PowerPC] Remove the implicit use of the register if it is replaced by Imm X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d966eee3287e04df622aa871ec6b45a96c3eee23;p=llvm [PowerPC] Remove the implicit use of the register if it is replaced by Imm If we are changing the MI operand from Reg to Imm, we need also handle its implicit use if have. Differential Revision: https://reviews.llvm.org/D56078 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350115 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index 1b9d5d2d8e0..d754ce2990d 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -2248,6 +2248,35 @@ static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc, return PPC::NoRegister; } +void PPCInstrInfo::replaceInstrOperandWithImm(MachineInstr &MI, + unsigned OpNo, + int64_t Imm) const { + assert(MI.getOperand(OpNo).isReg() && "Operand must be a REG"); + // Replace the REG with the Immediate. + unsigned InUseReg = MI.getOperand(OpNo).getReg(); + MI.getOperand(OpNo).ChangeToImmediate(Imm); + + if (empty(MI.implicit_operands())) + return; + + // We need to make sure that the MI didn't have any implicit use + // of this REG any more. + const TargetRegisterInfo *TRI = &getRegisterInfo(); + int UseOpIdx = MI.findRegisterUseOperandIdx(InUseReg, false, TRI); + if (UseOpIdx >= 0) { + MachineOperand &MO = MI.getOperand(UseOpIdx); + if (MO.isImplicit()) + // The operands must always be in the following order: + // - explicit reg defs, + // - other explicit operands (reg uses, immediates, etc.), + // - implicit reg defs + // - implicit reg uses + // Therefore, removing the implicit operand won't change the explicit + // operands layout. + MI.RemoveOperand(UseOpIdx); + } +} + // Replace an instruction with one that materializes a constant (and sets // CR0 if the original instruction was a record-form instruction). void PPCInstrInfo::replaceInstrWithLI(MachineInstr &MI, @@ -2481,7 +2510,7 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI, // Can't use PPC::COPY to copy PPC::ZERO[8]. Convert it to LI[8] 0. if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) { CompareUseMI.setDesc(get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI)); - CompareUseMI.getOperand(1).ChangeToImmediate(0); + replaceInstrOperandWithImm(CompareUseMI, 1, 0); CompareUseMI.RemoveOperand(3); CompareUseMI.RemoveOperand(2); continue; @@ -3292,7 +3321,7 @@ bool PPCInstrInfo::transformToImmFormFedByAdd(MachineInstr &MI, if (ImmMO->isImm()) { // If the ImmMO is Imm, change the operand that has ZERO to that Imm // directly. - MI.getOperand(III.ZeroIsSpecialOrig).ChangeToImmediate(Imm); + replaceInstrOperandWithImm(MI, III.ZeroIsSpecialOrig, Imm); } else { // Otherwise, it is Constant Pool Index(CPI) or Global, @@ -3411,24 +3440,24 @@ bool PPCInstrInfo::transformToImmFormFedByLI(MachineInstr &MI, uint64_t SH = RightShift ? 32 - ShAmt : ShAmt; uint64_t MB = RightShift ? ShAmt : 0; uint64_t ME = RightShift ? 31 : 31 - ShAmt; - MI.getOperand(III.OpNoForForwarding).ChangeToImmediate(SH); + replaceInstrOperandWithImm(MI, III.OpNoForForwarding, SH); MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(MB) .addImm(ME); } else { // Left shifts use (N, 63-N), right shifts use (64-N, N). uint64_t SH = RightShift ? 64 - ShAmt : ShAmt; uint64_t ME = RightShift ? ShAmt : 63 - ShAmt; - MI.getOperand(III.OpNoForForwarding).ChangeToImmediate(SH); + replaceInstrOperandWithImm(MI, III.OpNoForForwarding, SH); MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(ME); } } } else - MI.getOperand(ConstantOpNo).ChangeToImmediate(Imm); + replaceInstrOperandWithImm(MI, ConstantOpNo, Imm); } // Convert commutative instructions (switch the operands and convert the // desired one to an immediate. else if (III.IsCommutative) { - MI.getOperand(ConstantOpNo).ChangeToImmediate(Imm); + replaceInstrOperandWithImm(MI, ConstantOpNo, Imm); swapMIOperands(MI, ConstantOpNo, III.OpNoForForwarding); } else llvm_unreachable("Should have exited early!"); diff --git a/lib/Target/PowerPC/PPCInstrInfo.h b/lib/Target/PowerPC/PPCInstrInfo.h index 9c556e32496..7ed558b835a 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.h +++ b/lib/Target/PowerPC/PPCInstrInfo.h @@ -413,6 +413,8 @@ public: bool convertToImmediateForm(MachineInstr &MI, MachineInstr **KilledDef = nullptr) const; void replaceInstrWithLI(MachineInstr &MI, const LoadImmediateInfo &LII) const; + void replaceInstrOperandWithImm(MachineInstr &MI, unsigned OpNo, + int64_t Imm) const; bool instrHasImmForm(const MachineInstr &MI, ImmInstrInfo &III, bool PostRA) const; diff --git a/test/CodeGen/PowerPC/remove-implicit-use.mir b/test/CodeGen/PowerPC/remove-implicit-use.mir new file mode 100644 index 00000000000..9a70ce31785 --- /dev/null +++ b/test/CodeGen/PowerPC/remove-implicit-use.mir @@ -0,0 +1,78 @@ +# RUN: llc -mtriple=powerpc64le-unknown-unknown -start-after=ppc-mi-peepholes \ +# RUN: -stop-before=ppc-expand-isel -verify-machineinstrs %s -o - | FileCheck %s +--- | + ; ModuleID = 'a.ll' + source_filename = "a.c" + target datalayout = "e-m:e-i64:64-n32:64" + target triple = "powerpc64le-unknown-linux-gnu" + + ; Function Attrs: norecurse nounwind readnone + define signext i32 @test(i32 signext %a, i32 signext %b, i32 signext %c) local_unnamed_addr #0 { + entry: + %cmp = icmp sgt i32 %a, %b + %add = add nsw i32 %c, %b + %cond = select i1 %cmp, i32 %a, i32 %add + ret i32 %cond + } + + + !llvm.module.flags = !{!0, !1} + !llvm.ident = !{!2} + + !0 = !{i32 1, !"wchar_size", i32 4} + !1 = !{i32 7, !"PIC Level", i32 2} + !2 = !{!"clang version 8.0.0 (trunk 347251)"} + +... +--- +name: test +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false +tracksRegLiveness: true +hasWinCFI: false +registers: [] +liveins: + - { reg: '$x3', virtual-reg: '' } + - { reg: '$x4', virtual-reg: '' } + - { reg: '$x5', virtual-reg: '' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 0 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: [] +stack: [] +constants: [] +body: | + bb.0.entry: + liveins: $x3, $x5 + + renamable $r4 = LI 0 + renamable $r5 = nsw ADD4 killed renamable $r5, renamable $r5, implicit $x5 + renamable $cr0 = CMPW renamable $r3, killed renamable $r4, implicit $x4 + ; CHECK: ADD4 + ; CHECK-NOT: implicit $x4 + renamable $r3 = ISEL killed renamable $r3, killed renamable $r5, killed renamable $cr0gt, implicit $cr0, implicit $x3 + renamable $x3 = EXTSW_32_64 killed renamable $r3 + BLR8 implicit $lr8, implicit $rm, implicit killed $x3 + +... +