Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AArch64] ORRWrs is copy instruction when there's no implicit def of the X register #75184

Merged
merged 7 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions llvm/include/llvm/CodeGen/TargetInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,11 @@ class TargetInstrInfo : public MCInstrInfo {
return std::nullopt;
}

virtual std::optional<DestSourcePair>
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
Expand All @@ -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<DestSourcePair> 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)
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down
23 changes: 18 additions & 5 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<DestSourcePair>
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<RegImmPair>
AArch64InstrInfo::isAddImmediate(const MachineInstr &MI, Register Reg) const {
int Sign = 1;
Expand Down Expand Up @@ -9241,7 +9254,7 @@ static std::optional<ParamLoadedValue>
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;

Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,8 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo {
/// registers as machine operands.
std::optional<DestSourcePair>
isCopyInstrImpl(const MachineInstr &MI) const override;
std::optional<DestSourcePair>
isCopyLikeInstrImpl(const MachineInstr &MI) const override;

private:
unsigned getInstBundleLength(const MachineInstr &MI) const;
Expand Down
33 changes: 33 additions & 0 deletions llvm/test/CodeGen/AArch64/machine-cp-sub-reg.mir
Original file line number Diff line number Diff line change
@@ -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
...