diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h index 2bbe430dc68d..a113100f04e6 100644 --- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h +++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h @@ -1025,6 +1025,11 @@ class TargetInstrInfo : public MCInstrInfo { return std::nullopt; } + virtual std::optional + isCopyLikeInstrImpl(const MachineInstr &MI) const { + return std::nullopt; + } + /// Return true if the given terminator MI is not expected to spill. This /// sets the live interval as not spillable and adjusts phi node lowering to /// not introduce copies after the terminator. Use with care, these are @@ -1050,6 +1055,14 @@ class TargetInstrInfo : public MCInstrInfo { return isCopyInstrImpl(MI); } + // Similar to `isCopyInstr`, but adds non-copy semantics on MIR, but + // ultimately generates a copy instruction. + std::optional isCopyLikeInstr(const MachineInstr &MI) const { + if (auto IsCopyInstr = isCopyInstr(MI)) + return IsCopyInstr; + return isCopyLikeInstrImpl(MI); + } + bool isFullCopyInstr(const MachineInstr &MI) const { auto DestSrc = isCopyInstr(MI); if (!DestSrc) diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp index b2c2b40139ed..8a78a51f72eb 100644 --- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp @@ -2116,7 +2116,7 @@ bool InstrRefBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI) { } bool InstrRefBasedLDV::transferRegisterCopy(MachineInstr &MI) { - auto DestSrc = TII->isCopyInstr(MI); + auto DestSrc = TII->isCopyLikeInstr(MI); if (!DestSrc) return false; diff --git a/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp index 116c6b7e2d19..bf730be00a9a 100644 --- a/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp @@ -1364,7 +1364,7 @@ void VarLocBasedLDV::removeEntryValue(const MachineInstr &MI, // TODO: Try to keep tracking of an entry value if we encounter a propagated // DBG_VALUE describing the copy of the entry value. (Propagated entry value // does not indicate the parameter modification.) - auto DestSrc = TII->isCopyInstr(*TransferInst); + auto DestSrc = TII->isCopyLikeInstr(*TransferInst); if (DestSrc) { const MachineOperand *SrcRegOp, *DestRegOp; SrcRegOp = DestSrc->Source; @@ -1840,7 +1840,7 @@ void VarLocBasedLDV::transferRegisterCopy(MachineInstr &MI, OpenRangesSet &OpenRanges, VarLocMap &VarLocIDs, TransferMap &Transfers) { - auto DestSrc = TII->isCopyInstr(MI); + auto DestSrc = TII->isCopyLikeInstr(MI); if (!DestSrc) return; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 50cbd3672fbd..7d71c316bcb0 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -9185,19 +9185,32 @@ AArch64InstrInfo::isCopyInstrImpl(const MachineInstr &MI) const { // and zero immediate operands used as an alias for mov instruction. if (MI.getOpcode() == AArch64::ORRWrs && MI.getOperand(1).getReg() == AArch64::WZR && - MI.getOperand(3).getImm() == 0x0) { + MI.getOperand(3).getImm() == 0x0 && + // Check that the w->w move is not a zero-extending w->x mov. + (!MI.getOperand(0).getReg().isVirtual() || + MI.getOperand(0).getSubReg() == 0) && + (!MI.getOperand(0).getReg().isPhysical() || + MI.findRegisterDefOperandIdx(MI.getOperand(0).getReg() - AArch64::W0 + + AArch64::X0) == -1)) return DestSourcePair{MI.getOperand(0), MI.getOperand(2)}; - } if (MI.getOpcode() == AArch64::ORRXrs && MI.getOperand(1).getReg() == AArch64::XZR && - MI.getOperand(3).getImm() == 0x0) { + MI.getOperand(3).getImm() == 0x0) return DestSourcePair{MI.getOperand(0), MI.getOperand(2)}; - } return std::nullopt; } +std::optional +AArch64InstrInfo::isCopyLikeInstrImpl(const MachineInstr &MI) const { + if (MI.getOpcode() == AArch64::ORRWrs && + MI.getOperand(1).getReg() == AArch64::WZR && + MI.getOperand(3).getImm() == 0x0) + return DestSourcePair{MI.getOperand(0), MI.getOperand(2)}; + return std::nullopt; +} + std::optional AArch64InstrInfo::isAddImmediate(const MachineInstr &MI, Register Reg) const { int Sign = 1; @@ -9241,7 +9254,7 @@ static std::optional describeORRLoadedValue(const MachineInstr &MI, Register DescribedReg, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) { - auto DestSrc = TII->isCopyInstr(MI); + auto DestSrc = TII->isCopyLikeInstr(MI); if (!DestSrc) return std::nullopt; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h index e97ff0a9758d..6526f6740747 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h @@ -401,6 +401,8 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo { /// registers as machine operands. std::optional isCopyInstrImpl(const MachineInstr &MI) const override; + std::optional + isCopyLikeInstrImpl(const MachineInstr &MI) const override; private: unsigned getInstBundleLength(const MachineInstr &MI) const; diff --git a/llvm/test/CodeGen/AArch64/machine-cp-sub-reg.mir b/llvm/test/CodeGen/AArch64/machine-cp-sub-reg.mir new file mode 100644 index 000000000000..23cf1dcda839 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/machine-cp-sub-reg.mir @@ -0,0 +1,33 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4 +# RUN: llc -o - %s --run-pass=machine-cp -mcp-use-is-copy-instr -mtriple=arm64-apple-macos --verify-machineinstrs | FileCheck %s + +--- +name: test +tracksRegLiveness: true +body: | + ; CHECK-LABEL: name: test + ; CHECK: bb.0: + ; CHECK-NEXT: successors: %bb.1(0x80000000) + ; CHECK-NEXT: liveins: $w0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: $x8 = ORRXrs $xzr, $x0, 0, implicit $w0 + ; CHECK-NEXT: $w8 = ORRWrs $wzr, $w0, 0, implicit-def $x8 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.1: + ; CHECK-NEXT: liveins: $x8 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: $x0 = ADDXri $x8, 1, 0 + ; CHECK-NEXT: RET undef $lr, implicit $x0 + bb.0: + successors: %bb.1(0x80000000) + liveins: $w0 + + $x8 = ORRXrs $xzr, $x0, 0, implicit $w0 + $w8 = ORRWrs $wzr, $w0, 0, implicit-def $x8 + + bb.1: + liveins: $x8 + $x0 = ADDXri $x8, 1, 0 + + RET undef $lr, implicit $x0 +...