Skip to content

Commit

Permalink
llvm: add arm64 optimisation patch
Browse files Browse the repository at this point in the history
  • Loading branch information
Bo98 committed Jan 6, 2024
1 parent d1f5fea commit 2370440
Showing 1 changed file with 187 additions and 0 deletions.
187 changes: 187 additions & 0 deletions llvm/17.x-arm64-opt.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
From c3866492879d67314325fbb42b0cdbc9cd882424 Mon Sep 17 00:00:00 2001
From: DianQK <[email protected]>
Date: Thu, 14 Dec 2023 19:19:55 +0800
Subject: [PATCH] [AArch64] ORRWrs is copy instruction when there's no implicit
def of the X register (#75184)

Follows
https://github.com/llvm/llvm-project/pull/74682#issuecomment-1850268782.
Fixes #74680.
---
llvm/include/llvm/CodeGen/TargetInstrInfo.h | 13 ++++++++
.../LiveDebugValues/InstrRefBasedImpl.cpp | 2 +-
.../LiveDebugValues/VarLocBasedImpl.cpp | 4 +--
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 23 ++++++++++---
llvm/lib/Target/AArch64/AArch64InstrInfo.h | 2 ++
.../CodeGen/AArch64/machine-cp-sub-reg.mir | 33 +++++++++++++++++++
6 files changed, 69 insertions(+), 8 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/machine-cp-sub-reg.mir

diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
index 93dfcfc399247e4cb681a329c9791cd6aed08e2c..6ded5f99f0df396001ad1520829a9bee90a0e585 100644
--- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
@@ -1019,6 +1019,11 @@ protected:
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
@@ -1044,6 +1049,14 @@ public:
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);
+ }
+
/// If the specific machine instruction is an instruction that adds an
/// immediate value and a physical register, and stores the result in
/// the given physical register \c Reg, return a pair of the source
diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
index 57df9b67fd0263466484ee136e6db9c3c33d9061..7a77141256a36957c8bf34c8b4abbbd9dbd63e1b 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 116c6b7e2d19efad22b780f7cda3e3c816b27938..bf730be00a9a92c93e1b4e749e1085f7529a6694 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 0691e07a639beee77f8096e2cdb1f70e259a0e03..5fbb5947788c640aa6cb203efe6f90df64c5fe74 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -8269,19 +8269,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;
@@ -8325,7 +8338,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;

diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
index 20210a96d67ad28def588797a694c958c5aaaa79..ba16b6dba857bf8f0d5b6cdf912c5256255e7ae9 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
@@ -349,6 +349,8 @@ protected:
/// 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;
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 0000000000000000000000000000000000000000..23cf1dcda839e3072af578a617e5823cb3fbff2d
--- /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
+...

0 comments on commit 2370440

Please sign in to comment.