From 23704400c86976aaa4f421f56928484a270ac79c Mon Sep 17 00:00:00 2001 From: Bo Anderson Date: Sat, 6 Jan 2024 21:50:37 +0000 Subject: [PATCH] llvm: add arm64 optimisation patch --- llvm/17.x-arm64-opt.patch | 187 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 llvm/17.x-arm64-opt.patch diff --git a/llvm/17.x-arm64-opt.patch b/llvm/17.x-arm64-opt.patch new file mode 100644 index 00000000..f5c12495 --- /dev/null +++ b/llvm/17.x-arm64-opt.patch @@ -0,0 +1,187 @@ +From c3866492879d67314325fbb42b0cdbc9cd882424 Mon Sep 17 00:00:00 2001 +From: DianQK +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 ++ 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 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 ++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; +@@ -8325,7 +8338,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 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 + 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 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 ++...